From c069ec1b26014b55bc961846feaf7f7554fc2bb2 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Fri, 24 Oct 2014 11:06:40 +0300 Subject: [PATCH 001/333] Textures support for ObjectLoader. #4967 --- src/loaders/ObjectLoader.js | 123 ++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 7 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 741dd72575baca..5f087a89461aea 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -6,6 +6,8 @@ THREE.ObjectLoader = function ( manager ) { this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + this.texturePath = ''; + }; THREE.ObjectLoader.prototype = { @@ -20,25 +22,45 @@ THREE.ObjectLoader.prototype = { loader.setCrossOrigin( this.crossOrigin ); loader.load( url, function ( text ) { - onLoad( scope.parse( JSON.parse( text ) ) ); + scope.parse( JSON.parse( text ), onLoad ); }, onProgress, onError ); }, + setTexturePath: function ( texturePath ) { + + if ( typeof texturePath === 'string' ) { + this.texturePath = texturePath; + } + else { + console.warn( 'THREE.ObjectLoader: texturePath should be a string', texturePath ); + } + + }, + setCrossOrigin: function ( value ) { this.crossOrigin = value; }, - parse: function ( json ) { + parse: function ( json, onLoad ) { + + var geometries, materials, images, textures; + var self = this; - var geometries = this.parseGeometries( json.geometries ); - var materials = this.parseMaterials( json.materials ); - var object = this.parseObject( json.object, geometries, materials ); + var manager = new THREE.LoadingManager( function() { - return object; + textures = self.parseTextures( json.textures, images ); + materials = self.parseMaterials( json.materials, textures ); + + onLoad( self.parseObject( json.object, geometries, materials ) ); + + } ); + + geometries = this.parseGeometries( json.geometries ); + images = this.parseImages( json.images, manager ); }, @@ -182,7 +204,7 @@ THREE.ObjectLoader.prototype = { }, - parseMaterials: function ( json ) { + parseMaterials: function ( json, textures ) { var materials = {}; @@ -199,6 +221,16 @@ THREE.ObjectLoader.prototype = { if ( data.name !== undefined ) material.name = data.name; + if ( data.map ) { + + if ( !textures[data.map] ) { + console.warn( 'THREE.ObjectLoader: Undefined texture', data.map ); + } + + material.map = textures[data.map]; + + } + materials[ data.uuid ] = material; } @@ -209,6 +241,83 @@ THREE.ObjectLoader.prototype = { }, + parseImages: function ( json, manager ) { + + var images = {}; + var self = this; + + if ( json !== undefined ) { + + var loader = new THREE.ImageLoader( manager ); + loader.setCrossOrigin( this.crossOrigin ); + + for ( var i = 0, l = json.length; i < l; i ++ ) { + + var data = json[ i ], + url = self.texturePath + data.url; + + self.manager.itemStart( url ); + loader.load( url, function ( image ) { + + self.manager.itemEnd( url ); + + images[ data.uuid ] = image; + + } ); + + } + + } + + return images; + + }, + + parseTextures: function ( json, images ) { + + var textures = {}; + + if ( json !== undefined ) { + + for ( var i = 0, l = json.length; i < l; i ++ ) { + + var data = json[ i ]; + + if ( !data.image ) { + console.warn( 'THREE.ObjectLoader: No "image" speficied for', data.uuid ); + } + + if ( !images[data.image] ) { + console.warn( 'THREE.ObjectLoader: Undefined image', data.image ); + } + + var texture = new THREE.Texture( images[data.image] ); + texture.needsUpdate = true; + + texture.uuid = data.uuid; + + if ( data.name !== undefined ) texture.name = data.name; + if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2(data.repeat[0], data.repeat[1]); + if ( data.minFilter !== undefined ) texture.minFilter = THREE[data.minFilter]; + if ( data.magFilter !== undefined ) texture.magFilter = THREE[data.magFilter]; + if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; + if ( data.wrap instanceof Array ) { + + texture.wrapS = THREE[data.wrap[0]]; + texture.wrapT = THREE[data.wrap[1]]; + + } + + textures[ data.uuid ] = texture; + + } + + } + + return textures; + + }, + parseObject: function () { var matrix = new THREE.Matrix4(); From e4d3e69ad65213d48bbe191e833ca1c0ef029229 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Mon, 27 Oct 2014 23:06:59 +0200 Subject: [PATCH 002/333] ObjectLoader: fix for materials without textures --- src/loaders/ObjectLoader.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 5f087a89461aea..78e6f53b053a3c 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -251,10 +251,16 @@ THREE.ObjectLoader.prototype = { var loader = new THREE.ImageLoader( manager ); loader.setCrossOrigin( this.crossOrigin ); + if ( json.length === 0 ) { + + manager.onLoad(); + + } + for ( var i = 0, l = json.length; i < l; i ++ ) { - var data = json[ i ], - url = self.texturePath + data.url; + var data = json[ i ]; + var url = self.texturePath + data.url; self.manager.itemStart( url ); loader.load( url, function ( image ) { @@ -267,6 +273,11 @@ THREE.ObjectLoader.prototype = { } + } + else { + + manager.onLoad(); + } return images; From 3909dc68c87e01968b0286cc12e791930c71f2ee Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 19 Dec 2014 11:46:39 -0500 Subject: [PATCH 003/333] add decay exponent to Point and Spot lights and applicable shaders. --- src/lights/PointLight.js | 6 ++++-- src/lights/SpotLight.js | 6 ++++-- src/renderers/WebGLRenderer.js | 12 ++++++++++-- src/renderers/shaders/ShaderChunk/common.glsl | 8 ++++++++ .../ShaderChunk/lights_lambert_pars_vertex.glsl | 2 ++ .../shaders/ShaderChunk/lights_lambert_vertex.glsl | 8 ++------ .../shaders/ShaderChunk/lights_phong_fragment.glsl | 8 ++------ .../ShaderChunk/lights_phong_pars_fragment.glsl | 3 ++- src/renderers/shaders/ShaderLib.js | 10 ++++------ src/renderers/shaders/UniformsLib.js | 4 +++- 10 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/lights/PointLight.js b/src/lights/PointLight.js index c81d689c0c9a55..5cdce0cd896dbc 100644 --- a/src/lights/PointLight.js +++ b/src/lights/PointLight.js @@ -2,7 +2,7 @@ * @author mrdoob / http://mrdoob.com/ */ -THREE.PointLight = function ( color, intensity, distance ) { +THREE.PointLight = function ( color, intensity, distance, decayExponent ) { THREE.Light.call( this, color ); @@ -10,6 +10,7 @@ THREE.PointLight = function ( color, intensity, distance ) { this.intensity = ( intensity !== undefined ) ? intensity : 1; this.distance = ( distance !== undefined ) ? distance : 0; + this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 0;; // for physically correct lights, should be 2. }; @@ -24,7 +25,8 @@ THREE.PointLight.prototype.clone = function () { light.intensity = this.intensity; light.distance = this.distance; - + light.decayExponent = this.decayExponent; + return light; }; diff --git a/src/lights/SpotLight.js b/src/lights/SpotLight.js index cbc82bde5988ec..f2281ee741fcb8 100644 --- a/src/lights/SpotLight.js +++ b/src/lights/SpotLight.js @@ -2,7 +2,7 @@ * @author alteredq / http://alteredqualia.com/ */ -THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) { +THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decayExponent ) { THREE.Light.call( this, color ); @@ -15,6 +15,7 @@ THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) { this.distance = ( distance !== undefined ) ? distance : 0; this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; this.exponent = ( exponent !== undefined ) ? exponent : 10; + this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 0;; // for physically correct lights, should be 2. this.castShadow = false; this.onlyShadow = false; @@ -57,7 +58,8 @@ THREE.SpotLight.prototype.clone = function () { light.distance = this.distance; light.angle = this.angle; light.exponent = this.exponent; - + light.decayExponent = this.decayExponent; + light.castShadow = this.castShadow; light.onlyShadow = this.onlyShadow; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d10a7811df59d7..4f9d48e87b81e3 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -168,8 +168,8 @@ THREE.WebGLRenderer = function ( parameters ) { ambient: [ 0, 0, 0 ], directional: { length: 0, colors:[], positions: [] }, - point: { length: 0, colors: [], positions: [], distances: [] }, - spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [] }, + point: { length: 0, colors: [], positions: [], distances: [], decayExponents: [] }, + spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [], decayExponents: [] }, hemi: { length: 0, skyColors: [], groundColors: [], positions: [] } }; @@ -4710,6 +4710,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.pointLightColor.value = lights.point.colors; uniforms.pointLightPosition.value = lights.point.positions; uniforms.pointLightDistance.value = lights.point.distances; + uniforms.pointLightDecayExponent.value = lights.point.decayExponents; uniforms.spotLightColor.value = lights.spot.colors; uniforms.spotLightPosition.value = lights.spot.positions; @@ -4717,6 +4718,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.spotLightDirection.value = lights.spot.directions; uniforms.spotLightAngleCos.value = lights.spot.anglesCos; uniforms.spotLightExponent.value = lights.spot.exponents; + uniforms.spotLightDecayExponent.value = lights.spot.decayExponents; uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors; uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors; @@ -4736,6 +4738,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.pointLightColor.needsUpdate = boolean; uniforms.pointLightPosition.needsUpdate = boolean; uniforms.pointLightDistance.needsUpdate = boolean; + uniforms.pointLightDecayExponent.needsUpdate = boolean; uniforms.spotLightColor.needsUpdate = boolean; uniforms.spotLightPosition.needsUpdate = boolean; @@ -4743,6 +4746,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.spotLightDirection.needsUpdate = boolean; uniforms.spotLightAngleCos.needsUpdate = boolean; uniforms.spotLightExponent.needsUpdate = boolean; + uniforms.spotLightDecayExponent.needsUpdate = boolean; uniforms.hemisphereLightSkyColor.needsUpdate = boolean; uniforms.hemisphereLightGroundColor.needsUpdate = boolean; @@ -5190,6 +5194,7 @@ THREE.WebGLRenderer = function ( parameters ) { pointColors = zlights.point.colors, pointPositions = zlights.point.positions, pointDistances = zlights.point.distances, + pointDecayExponents = zlights.point.decayExponents, spotColors = zlights.spot.colors, spotPositions = zlights.spot.positions, @@ -5197,6 +5202,7 @@ THREE.WebGLRenderer = function ( parameters ) { spotDirections = zlights.spot.directions, spotAnglesCos = zlights.spot.anglesCos, spotExponents = zlights.spot.exponents, + spotDecayExponents = zlights.spot.decayExponents, hemiSkyColors = zlights.hemi.skyColors, hemiGroundColors = zlights.hemi.groundColors, @@ -5299,6 +5305,7 @@ THREE.WebGLRenderer = function ( parameters ) { pointPositions[ pointOffset + 2 ] = _vector3.z; pointDistances[ pointLength ] = distance; + pointDecayExponents[ pointLength ] = light.decayExponent; pointLength += 1; @@ -5338,6 +5345,7 @@ THREE.WebGLRenderer = function ( parameters ) { spotAnglesCos[ spotLength ] = Math.cos( light.angle ); spotExponents[ spotLength ] = light.exponent; + spotDecayExponents[ pointLength ] = light.decayExponent; spotLength += 1; diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index d796b9e3aeeef2..1cdca80269a613 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -32,4 +32,12 @@ float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { } vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ); +} +// standard exponential distance attenuation multiplied by a linear distance cutoff, if cutoffDistance > 0. +float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) { + float distanceAttenuation = 1.0 / pow( lightDistance, decayExponent ); + if ( cutoffDistance > 0.0 ) { + distanceAttenuation *= 1.0 - min( lightDistance / cutoffDistance, 1.0 ); + } + return distanceAttenuation; } \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl index 511c1a83ec33eb..7e54e59611a0cb 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl @@ -24,6 +24,7 @@ uniform vec3 ambientLightColor; uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; + uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; #endif @@ -35,6 +36,7 @@ uniform vec3 ambientLightColor; uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; + uniform float spotLightDecayExponent[ MAX_SPOT_LIGHTS ]; #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 2d680f3bfa9f17..1ba492e0d28746 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -61,9 +61,7 @@ for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 ); vec3 lVector = lPosition.xyz - mvPosition.xyz; - float lDistance = 1.0; - if ( pointLightDistance[ i ] > 0.0 ) - lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 ); + float lDistance = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] ); lVector = normalize( lVector ); float dotProduct = dot( transformedNormal, lVector ); @@ -120,9 +118,7 @@ for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 ); - float lDistance = 1.0; - if ( spotLightDistance[ i ] > 0.0 ) - lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 ); + float lDistance = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecayExponent[i] ); lVector = normalize( lVector ); diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 2a88aec393b60c..08ee3569b76ce8 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -27,9 +27,7 @@ vec3 viewPosition = normalize( vViewPosition ); vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 ); vec3 lVector = lPosition.xyz + vViewPosition.xyz; - float lDistance = 1.0; - if ( pointLightDistance[ i ] > 0.0 ) - lDistance = saturate( 1.0 - ( length( lVector ) / pointLightDistance[ i ] ) ); + float lDistance = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] ); lVector = normalize( lVector ); @@ -77,9 +75,7 @@ vec3 viewPosition = normalize( vViewPosition ); vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 ); vec3 lVector = lPosition.xyz + vViewPosition.xyz; - float lDistance = 1.0; - if ( spotLightDistance[ i ] > 0.0 ) - lDistance = saturate( 1.0 - ( length( lVector ) / spotLightDistance[ i ] ); + float lDistance = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecayExponent[i] ); lVector = normalize( lVector ); diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 54228c49bd5b8d..11e00995c7d225 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -21,6 +21,7 @@ uniform vec3 ambientLightColor; uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; + uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ]; #endif @@ -31,8 +32,8 @@ uniform vec3 ambientLightColor; uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; - uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; + uniform float spotLightDecayExponent[ MAX_SPOT_LIGHTS ]; #endif diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index f92e0094603eb3..40985d2c02016f 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -709,6 +709,7 @@ THREE.ShaderLib = { " uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", " uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", " uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", + " uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ];", "#endif", @@ -720,6 +721,7 @@ THREE.ShaderLib = { " uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];", " uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];", " uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];", + " uniform float spotLightDecayExponent[ MAX_SPOT_LIGHTS ];", "#endif", @@ -810,9 +812,7 @@ THREE.ShaderLib = { " vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", " vec3 pointVector = lPosition.xyz + vViewPosition.xyz;", - " float pointDistance = 1.0;", - " if ( pointLightDistance[ i ] > 0.0 )", - " pointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );", + " float pointDistance = calcLightAttenuation( length( pointVector ), pointLightDistance[ i ], pointLightDecayExponent[i] );", " pointVector = normalize( pointVector );", @@ -860,9 +860,7 @@ THREE.ShaderLib = { " vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );", " vec3 spotVector = lPosition.xyz + vViewPosition.xyz;", - " float spotDistance = 1.0;", - " if ( spotLightDistance[ i ] > 0.0 )", - " spotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );", + " float spotDistance = calcLightAttenuation( length( spotVector ), spotLightDistance[ i ], spotLightDecayExponent[i] );", " spotVector = normalize( spotVector );", diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index 135925fa1f3bf1..2302425dfb2f07 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -61,13 +61,15 @@ THREE.UniformsLib = { "pointLightColor" : { type: "fv", value: [] }, "pointLightPosition" : { type: "fv", value: [] }, "pointLightDistance" : { type: "fv1", value: [] }, + "pointLightDecayExponent" : { type: "fv1", value: [] }, "spotLightColor" : { type: "fv", value: [] }, "spotLightPosition" : { type: "fv", value: [] }, "spotLightDirection" : { type: "fv", value: [] }, "spotLightDistance" : { type: "fv1", value: [] }, "spotLightAngleCos" : { type: "fv1", value: [] }, - "spotLightExponent" : { type: "fv1", value: [] } + "spotLightExponent" : { type: "fv1", value: [] }, + "spotLightDecayExponent" : { type: "fv1", value: [] } }, From 612c83aeca1124cfbf5b609aa9e1fa8046dbd39f Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 19 Dec 2014 12:55:46 -0500 Subject: [PATCH 004/333] add import/export support to Spot/Point decayExponent. --- examples/js/exporters/SceneExporter.js | 28 ++++++++++++++------------ src/core/Object3D.js | 2 ++ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/examples/js/exporters/SceneExporter.js b/examples/js/exporters/SceneExporter.js index 296aaa618c2827..7d0504c4769467 100644 --- a/examples/js/exporters/SceneExporter.js +++ b/examples/js/exporters/SceneExporter.js @@ -238,11 +238,12 @@ THREE.SceneExporter.prototype = { var output = [ '\t\t' + LabelString( getObjectName( o ) ) + ' : {', - ' "type" : "PointLight",', - ' "color" : ' + o.color.getHex() + ',', - ' "intensity" : ' + o.intensity + ',', - ' "position" : ' + Vector3String( o.position ) + ',', - ' "distance" : ' + o.distance + ( o.children.length ? ',' : '' ) + ' "type" : "PointLight",', + ' "color" : ' + o.color.getHex() + ',', + ' "intensity" : ' + o.intensity + ',', + ' "position" : ' + Vector3String( o.position ) + ',', + ' "decayExponent" : ' + o.decayExponent + ',', + ' "distance" : ' + o.distance + ( o.children.length ? ',' : '' ) ]; @@ -251,14 +252,15 @@ THREE.SceneExporter.prototype = { var output = [ '\t\t' + LabelString( getObjectName( o ) ) + ' : {', - ' "type" : "SpotLight",', - ' "color" : ' + o.color.getHex() + ',', - ' "intensity" : ' + o.intensity + ',', - ' "position" : ' + Vector3String( o.position ) + ',', - ' "distance" : ' + o.distance + ',', - ' "angle" : ' + o.angle + ',', - ' "exponent" : ' + o.exponent + ',', - ' "target" : ' + LabelString( getObjectName( o.target ) ) + ( o.children.length ? ',' : '' ) + ' "type" : "SpotLight",', + ' "color" : ' + o.color.getHex() + ',', + ' "intensity" : ' + o.intensity + ',', + ' "position" : ' + Vector3String( o.position ) + ',', + ' "distance" : ' + o.distance + ',', + ' "angle" : ' + o.angle + ',', + ' "exponent" : ' + o.exponent + ',', + ' "decayExponent" : ' + o.decayExponent + ',', + ' "target" : ' + LabelString( getObjectName( o.target ) ) + ( o.children.length ? ',' : '' ) ]; diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 7ec4aee6f65475..f3da2ea66655e3 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -677,6 +677,7 @@ THREE.Object3D.prototype = { data.color = object.color.getHex(); data.intensity = object.intensity; data.distance = object.distance; + data.decayExponent = object.decayExponent || 0; } else if ( object instanceof THREE.SpotLight ) { @@ -685,6 +686,7 @@ THREE.Object3D.prototype = { data.distance = object.distance; data.angle = object.angle; data.exponent = object.exponent; + data.decayExponent = object.decayExponent || 0; } else if ( object instanceof THREE.HemisphereLight ) { From 1e97815e773234f47e45e74170689cccaf544327 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 19 Dec 2014 14:38:43 -0500 Subject: [PATCH 005/333] add THREE.error/THREE.warning to allow for easy redirection of THREE.js specific errors and warnings. --- src/Three.js | 37 ++++++++++++++++--- src/core/BufferAttribute.js | 18 ++++----- src/core/BufferGeometry.js | 10 ++--- src/core/Face4.js | 2 +- src/core/Geometry.js | 4 +- src/core/Object3D.js | 16 ++++---- src/core/Raycaster.js | 4 +- src/extras/GeometryUtils.js | 4 +- src/extras/ImageUtils.js | 4 +- src/extras/animation/AnimationHandler.js | 6 +-- src/extras/core/Curve.js | 2 +- src/extras/geometries/CubeGeometry.js | 2 +- src/extras/geometries/ExtrudeGeometry.js | 2 +- src/extras/objects/MorphBlendMesh.js | 4 +- src/loaders/JSONLoader.js | 10 ++--- src/loaders/ObjectLoader.js | 10 ++--- src/materials/Material.js | 2 +- src/materials/PointCloudMaterial.js | 4 +- src/math/Euler.js | 2 +- src/math/Matrix3.js | 8 ++-- src/math/Matrix4.js | 34 ++++++++--------- src/math/Quaternion.js | 4 +- src/math/Vector2.js | 4 +- src/math/Vector3.js | 22 +++++------ src/math/Vector4.js | 4 +- src/objects/Mesh.js | 2 +- src/objects/MorphAnimMesh.js | 2 +- src/objects/PointCloud.js | 2 +- src/objects/Skeleton.js | 2 +- src/objects/SkinnedMesh.js | 2 +- src/renderers/WebGLRenderer.js | 36 +++++++++--------- src/renderers/webgl/WebGLExtensions.js | 2 +- src/renderers/webgl/WebGLProgram.js | 12 +++--- src/renderers/webgl/WebGLShader.js | 6 +-- .../webgl/plugins/ShadowMapPlugin.js | 4 +- 35 files changed, 158 insertions(+), 131 deletions(-) diff --git a/src/Three.js b/src/Three.js index f9689195dcd8e0..497ebda8d272fe 100644 --- a/src/Three.js +++ b/src/Three.js @@ -24,6 +24,33 @@ if ( Math.sign === undefined ) { } + +THREE.ExceptionErrorHandler = function( message, optionalData ) { + console.error( message ); + console.error( optionalData ); + var error = new Error( message ); + error.optionalData = optionalData; + throw error; +}; + +THREE.ConsoleErrorHandler = function( message, optionalData ) { + console.error( message ); + console.error( optionalData ); +}; + +THREE.ConsoleWarningHandler = function( message, optionalData ) { + console.warn( message ); + console.warn( optionalData ); +}; + +THREE.NullHandler = function( message, optionalData ) { +}; + +// set the default error handlers +THREE.error = THREE.ConsoleErrorHandler; +THREE.warning = THREE.ConsoleWarningHandler; + + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button THREE.MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; @@ -187,25 +214,25 @@ THREE.RGBA_PVRTC_2BPPV1_Format = 2103; THREE.Projector = function () { - console.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' ); + THREE.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' ); this.projectVector = function ( vector, camera ) { - console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); + THREE.warning( 'THREE.Projector: .projectVector() is now vector.project().' ); vector.project( camera ); }; this.unprojectVector = function ( vector, camera ) { - console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); + THREE.warning( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); vector.unproject( camera ); }; this.pickingRay = function ( vector, camera ) { - console.error( 'THREE.Projector: .pickingRay() has been removed.' ); + THREE.error( 'THREE.Projector: .pickingRay() has been removed.' ); }; @@ -213,7 +240,7 @@ THREE.Projector = function () { THREE.CanvasRenderer = function () { - console.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' ); + THREE.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' ); this.domElement = document.createElement( 'canvas' ); this.clear = function () {}; diff --git a/src/core/BufferAttribute.js b/src/core/BufferAttribute.js index d19a4aeed2d8a4..8d891bce2acfa7 100644 --- a/src/core/BufferAttribute.js +++ b/src/core/BufferAttribute.js @@ -114,21 +114,21 @@ THREE.BufferAttribute.prototype = { THREE.Int8Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint8Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint8ClampedAttribute = function ( data, itemSize ) { - console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); @@ -136,42 +136,42 @@ THREE.Uint8ClampedAttribute = function ( data, itemSize ) { THREE.Int16Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint16Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Int32Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint32Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Float32Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Float64Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warning( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index 173d6206a48bf6..99c0d864e474f9 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -31,7 +31,7 @@ THREE.BufferGeometry.prototype = { if ( attribute instanceof THREE.BufferAttribute === false ) { - console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); + THREE.warning( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); this.attributes[ name ] = { array: arguments[ 1 ], itemSize: arguments[ 2 ] }; @@ -277,7 +277,7 @@ THREE.BufferGeometry.prototype = { if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.' ); + THREE.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.' ); } @@ -331,7 +331,7 @@ THREE.BufferGeometry.prototype = { if ( isNaN( this.boundingSphere.radius ) ) { - console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.' ); + THREE.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.' ); } @@ -476,7 +476,7 @@ THREE.BufferGeometry.prototype = { this.attributes.normal === undefined || this.attributes.uv === undefined ) { - console.warn( 'Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); + THREE.warning( 'Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); return; } @@ -764,7 +764,7 @@ THREE.BufferGeometry.prototype = { if ( geometry instanceof THREE.BufferGeometry === false ) { - console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); + THREE.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); return; } diff --git a/src/core/Face4.js b/src/core/Face4.js index ee2b05556d48ee..89545ffafabbed 100644 --- a/src/core/Face4.js +++ b/src/core/Face4.js @@ -4,7 +4,7 @@ THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) { - console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ) + THREE.warning( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ) return new THREE.Face3( a, b, c, normal, color, materialIndex ); }; diff --git a/src/core/Geometry.js b/src/core/Geometry.js index 69307159117a82..76b52321f1acc3 100644 --- a/src/core/Geometry.js +++ b/src/core/Geometry.js @@ -565,7 +565,7 @@ THREE.Geometry.prototype = { if ( geometry instanceof THREE.Geometry === false ) { - console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); + THREE.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); return; } @@ -675,7 +675,7 @@ THREE.Geometry.prototype = { if ( mesh instanceof THREE.Mesh === false ) { - console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); + THREE.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); return; } diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 7ec4aee6f65475..adedff10f692ee 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -83,7 +83,7 @@ THREE.Object3D.prototype = { get eulerOrder () { - console.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); + THREE.warning( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); return this.rotation.order; @@ -91,7 +91,7 @@ THREE.Object3D.prototype = { set eulerOrder ( value ) { - console.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); + THREE.warning( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); this.rotation.order = value; @@ -99,13 +99,13 @@ THREE.Object3D.prototype = { get useQuaternion () { - console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); + THREE.warning( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); }, set useQuaternion ( value ) { - console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); + THREE.warning( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); }, @@ -223,7 +223,7 @@ THREE.Object3D.prototype = { translate: function ( distance, axis ) { - console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); + THREE.warning( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); return this.translateOnAxis( axis, distance ); }, @@ -314,7 +314,7 @@ THREE.Object3D.prototype = { if ( object === this ) { - console.error( "THREE.Object3D.add:", object, "can't be added as a child of itself." ); + THREE.error( "THREE.Object3D.add:", object, "can't be added as a child of itself." ); return this; } @@ -334,7 +334,7 @@ THREE.Object3D.prototype = { } else { - console.error( "THREE.Object3D.add:", object, "is not an instance of THREE.Object3D." ); + THREE.error( "THREE.Object3D.add:", object, "is not an instance of THREE.Object3D." ); } @@ -370,7 +370,7 @@ THREE.Object3D.prototype = { getChildByName: function ( name, recursive ) { - console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); + THREE.warning( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); return this.getObjectByName( name, recursive ); }, diff --git a/src/core/Raycaster.js b/src/core/Raycaster.js index 5f06777084f4f2..0008a69bbe7bb7 100644 --- a/src/core/Raycaster.js +++ b/src/core/Raycaster.js @@ -81,7 +81,7 @@ } else { - console.error( 'THREE.Raycaster: Unsupported camera type.' ); + THREE.error( 'THREE.Raycaster: Unsupported camera type.' ); } @@ -105,7 +105,7 @@ if ( objects instanceof Array === false ) { - console.log( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); + THREE.warning( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); return intersects; } diff --git a/src/extras/GeometryUtils.js b/src/extras/GeometryUtils.js index ca413e216563e2..419d38cc7f96a6 100644 --- a/src/extras/GeometryUtils.js +++ b/src/extras/GeometryUtils.js @@ -6,7 +6,7 @@ THREE.GeometryUtils = { merge: function ( geometry1, geometry2, materialIndexOffset ) { - console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); + THREE.warning( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); var matrix; @@ -25,7 +25,7 @@ THREE.GeometryUtils = { center: function ( geometry ) { - console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); + THREE.warning( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); return geometry.center(); } diff --git a/src/extras/ImageUtils.js b/src/extras/ImageUtils.js index 4b0b1e8ee4858d..4ef48a748d1fb3 100644 --- a/src/extras/ImageUtils.js +++ b/src/extras/ImageUtils.js @@ -81,13 +81,13 @@ THREE.ImageUtils = { loadCompressedTexture: function () { - console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' ) + THREE.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' ) }, loadCompressedTextureCube: function () { - console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' ) + THREE.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' ) }, diff --git a/src/extras/animation/AnimationHandler.js b/src/extras/animation/AnimationHandler.js index 4780ad53b2415a..a7606b86ca7d16 100644 --- a/src/extras/animation/AnimationHandler.js +++ b/src/extras/animation/AnimationHandler.js @@ -10,9 +10,9 @@ THREE.AnimationHandler = { // - add: function () { console.warn( 'THREE.AnimationHandler.add() has been deprecated.' ); }, - get: function () { console.warn( 'THREE.AnimationHandler.get() has been deprecated.' ); }, - remove: function () { console.warn( 'THREE.AnimationHandler.remove() has been deprecated.' ); }, + add: function () { THREE.warning( 'THREE.AnimationHandler.add() has been deprecated.' ); }, + get: function () { THREE.warning( 'THREE.AnimationHandler.get() has been deprecated.' ); }, + remove: function () { THREE.warning( 'THREE.AnimationHandler.remove() has been deprecated.' ); }, // diff --git a/src/extras/core/Curve.js b/src/extras/core/Curve.js index 04decdccd13363..5e83a8751d7643 100644 --- a/src/extras/core/Curve.js +++ b/src/extras/core/Curve.js @@ -43,7 +43,7 @@ THREE.Curve = function () { THREE.Curve.prototype.getPoint = function ( t ) { - console.log( "Warning, getPoint() not implemented!" ); + THREE.warning( "Warning, THREE.Curve.getPoint() not implemented!" ); return null; }; diff --git a/src/extras/geometries/CubeGeometry.js b/src/extras/geometries/CubeGeometry.js index d2dff8ccf0126b..a52ff40b30d534 100644 --- a/src/extras/geometries/CubeGeometry.js +++ b/src/extras/geometries/CubeGeometry.js @@ -5,7 +5,7 @@ THREE.CubeGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) { - console.warn( 'THREE.CubeGeometry has been renamed to THREE.BoxGeometry.' ); + THREE.warning( 'THREE.CubeGeometry has been renamed to THREE.BoxGeometry.' ); return new THREE.BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ); }; diff --git a/src/extras/geometries/ExtrudeGeometry.js b/src/extras/geometries/ExtrudeGeometry.js index a5a5a9c9625cf3..f42835d41567f3 100644 --- a/src/extras/geometries/ExtrudeGeometry.js +++ b/src/extras/geometries/ExtrudeGeometry.js @@ -174,7 +174,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { function scalePt2 ( pt, vec, size ) { - if ( ! vec ) console.log( "die" ); + if ( ! vec ) THREE.error( "vec does not exist" ); return vec.clone().multiplyScalar( size ).add( pt ); diff --git a/src/extras/objects/MorphBlendMesh.js b/src/extras/objects/MorphBlendMesh.js index 3c04a7aa64bd75..6414406e3f009f 100644 --- a/src/extras/objects/MorphBlendMesh.js +++ b/src/extras/objects/MorphBlendMesh.js @@ -27,7 +27,7 @@ THREE.MorphBlendMesh = function( geometry, material ) { }; THREE.MorphBlendMesh.prototype = Object.create( THREE.Mesh.prototype ); -THREE.MorphBlendMesh.prototype.constructor = THREE.MorphBlendMesh; +THREE.MorphBlendMesh.prototype.constructor = THREE.MorphBlendMesh; THREE.MorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) { @@ -221,7 +221,7 @@ THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) { } else { - console.warn( "animation[" + name + "] undefined" ); + THREE.warning( "animation[" + name + "] undefined" ); } diff --git a/src/loaders/JSONLoader.js b/src/loaders/JSONLoader.js index 602697d2507f73..e1f003227dc4f2 100644 --- a/src/loaders/JSONLoader.js +++ b/src/loaders/JSONLoader.js @@ -12,7 +12,7 @@ THREE.JSONLoader = function ( showStatus ) { }; THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype ); -THREE.JSONLoader.prototype.constructor = THREE.JSONLoader; +THREE.JSONLoader.prototype.constructor = THREE.JSONLoader; THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) { @@ -45,7 +45,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex if ( json.metadata !== undefined && json.metadata.type === 'scene' ) { - console.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' ); + THREE.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' ); return; } @@ -55,7 +55,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex } else { - console.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' ); + THREE.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' ); } @@ -67,7 +67,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex } else { - console.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' ); + THREE.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' ); } @@ -454,7 +454,7 @@ THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + + THREE.warning( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); } diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 741dd72575baca..264ceb8f5599c7 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -274,13 +274,13 @@ THREE.ObjectLoader.prototype = { if ( geometry === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); + THREE.warning( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); } if ( material === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined material', data.material ); + THREE.warning( 'THREE.ObjectLoader: Undefined material', data.material ); } @@ -295,13 +295,13 @@ THREE.ObjectLoader.prototype = { if ( geometry === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); + THREE.warning( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); } if ( material === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined material', data.material ); + THREE.warning( 'THREE.ObjectLoader: Undefined material', data.material ); } @@ -315,7 +315,7 @@ THREE.ObjectLoader.prototype = { if ( material === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined material', data.material ); + THREE.warning( 'THREE.ObjectLoader: Undefined material', data.material ); } diff --git a/src/materials/Material.js b/src/materials/Material.js index 75d066f1665918..2b686a3c3f3896 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -54,7 +54,7 @@ THREE.Material.prototype = { if ( newValue === undefined ) { - console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); + THREE.warning( "THREE.Material: '" + key + "' parameter is undefined." ); continue; } diff --git a/src/materials/PointCloudMaterial.js b/src/materials/PointCloudMaterial.js index 0a3891092b9d84..71cd07f87c4732 100644 --- a/src/materials/PointCloudMaterial.js +++ b/src/materials/PointCloudMaterial.js @@ -69,14 +69,14 @@ THREE.PointCloudMaterial.prototype.clone = function () { THREE.ParticleBasicMaterial = function ( parameters ) { - console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointCloudMaterial.' ); + THREE.warning( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointCloudMaterial.' ); return new THREE.PointCloudMaterial( parameters ); }; THREE.ParticleSystemMaterial = function ( parameters ) { - console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' ); + THREE.warning( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' ); return new THREE.PointCloudMaterial( parameters ); }; diff --git a/src/math/Euler.js b/src/math/Euler.js index ea0b48615cfe3b..11e717b70d894b 100644 --- a/src/math/Euler.js +++ b/src/math/Euler.js @@ -212,7 +212,7 @@ THREE.Euler.prototype = { } else { - console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ) + THREE.warning( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ) } diff --git a/src/math/Matrix3.js b/src/math/Matrix3.js index 6dc582649f1379..ebc400251b5482 100644 --- a/src/math/Matrix3.js +++ b/src/math/Matrix3.js @@ -16,7 +16,7 @@ THREE.Matrix3 = function () { if ( arguments.length > 0 ) { - console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); + THREE.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); } @@ -70,14 +70,14 @@ THREE.Matrix3.prototype = { multiplyVector3: function ( vector ) { - console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); + THREE.warning( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); return vector.applyMatrix3( this ); }, multiplyVector3Array: function ( a ) { - console.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); + THREE.warning( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); return this.applyToVector3Array( a ); }, @@ -167,7 +167,7 @@ THREE.Matrix3.prototype = { } else { - console.warn( msg ); + THREE.warning( msg ); } diff --git a/src/math/Matrix4.js b/src/math/Matrix4.js index b210a554f83cbd..c41c4a3c94a36b 100644 --- a/src/math/Matrix4.js +++ b/src/math/Matrix4.js @@ -24,7 +24,7 @@ THREE.Matrix4 = function () { if ( arguments.length > 0 ) { - console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); + THREE.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); } @@ -72,7 +72,7 @@ THREE.Matrix4.prototype = { extractPosition: function ( m ) { - console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); + THREE.warning( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); return this.copyPosition( m ); }, @@ -125,7 +125,7 @@ THREE.Matrix4.prototype = { if ( euler instanceof THREE.Euler === false ) { - console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); + THREE.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); } @@ -251,7 +251,7 @@ THREE.Matrix4.prototype = { setRotationFromQuaternion: function ( q ) { - console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); + THREE.warning( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); return this.makeRotationFromQuaternion( q ); @@ -338,7 +338,7 @@ THREE.Matrix4.prototype = { if ( n !== undefined ) { - console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); + THREE.warning( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); return this.multiplyMatrices( m, n ); } @@ -417,21 +417,21 @@ THREE.Matrix4.prototype = { multiplyVector3: function ( vector ) { - console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); + THREE.warning( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); return vector.applyProjection( this ); }, multiplyVector4: function ( vector ) { - console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + THREE.warning( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); return vector.applyMatrix4( this ); }, multiplyVector3Array: function ( a ) { - console.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); + THREE.warning( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); return this.applyToVector3Array( a ); }, @@ -467,7 +467,7 @@ THREE.Matrix4.prototype = { rotateAxis: function ( v ) { - console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); + THREE.warning( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); v.transformDirection( this ); @@ -475,7 +475,7 @@ THREE.Matrix4.prototype = { crossVector: function ( vector ) { - console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + THREE.warning( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); return vector.applyMatrix4( this ); }, @@ -581,7 +581,7 @@ THREE.Matrix4.prototype = { return function () { - console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); + THREE.warning( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); var te = this.elements; return v1.set( te[ 12 ], te[ 13 ], te[ 14 ] ); @@ -642,7 +642,7 @@ THREE.Matrix4.prototype = { } else { - console.warn( msg ); + THREE.warning( msg ); } @@ -659,31 +659,31 @@ THREE.Matrix4.prototype = { translate: function ( v ) { - console.warn( 'THREE.Matrix4: .translate() has been removed.' ); + THREE.error( 'THREE.Matrix4: .translate() has been removed.' ); }, rotateX: function ( angle ) { - console.warn( 'THREE.Matrix4: .rotateX() has been removed.' ); + THREE.error( 'THREE.Matrix4: .rotateX() has been removed.' ); }, rotateY: function ( angle ) { - console.warn( 'THREE.Matrix4: .rotateY() has been removed.' ); + THREE.error( 'THREE.Matrix4: .rotateY() has been removed.' ); }, rotateZ: function ( angle ) { - console.warn( 'THREE.Matrix4: .rotateZ() has been removed.' ); + THREE.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); }, rotateByAxis: function ( axis, angle ) { - console.warn( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); + THREE.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); }, diff --git a/src/math/Quaternion.js b/src/math/Quaternion.js index 2ac5218aa9bb2b..8b6d486aa04ff2 100644 --- a/src/math/Quaternion.js +++ b/src/math/Quaternion.js @@ -363,7 +363,7 @@ THREE.Quaternion.prototype = { if ( p !== undefined ) { - console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); + THREE.warning( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); return this.multiplyQuaternions( q, p ); } @@ -392,7 +392,7 @@ THREE.Quaternion.prototype = { multiplyVector3: function ( vector ) { - console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); + THREE.warning( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); return vector.applyQuaternion( this ); }, diff --git a/src/math/Vector2.js b/src/math/Vector2.js index 97d6899b36e8be..4a1e91dea7b3c7 100644 --- a/src/math/Vector2.js +++ b/src/math/Vector2.js @@ -78,7 +78,7 @@ THREE.Vector2.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warning( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -112,7 +112,7 @@ THREE.Vector2.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warning( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } diff --git a/src/math/Vector3.js b/src/math/Vector3.js index efdc533543d320..5bb40a73dbf657 100644 --- a/src/math/Vector3.js +++ b/src/math/Vector3.js @@ -93,7 +93,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warning( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -130,7 +130,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warning( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } @@ -157,7 +157,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); + THREE.warning( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); return this.multiplyVectors( v, w ); } @@ -198,7 +198,7 @@ THREE.Vector3.prototype = { if ( euler instanceof THREE.Euler === false ) { - console.error( 'THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.' ); + THREE.error( 'THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.' ); } @@ -601,7 +601,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); + THREE.warning( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); return this.crossVectors( v, w ); } @@ -708,19 +708,19 @@ THREE.Vector3.prototype = { setEulerFromRotationMatrix: function ( m, order ) { - console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); + THREE.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); }, setEulerFromQuaternion: function ( q, order ) { - console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); + THREE.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); }, getPositionFromMatrix: function ( m ) { - console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); + THREE.warning( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); return this.setFromMatrixPosition( m ); @@ -728,14 +728,14 @@ THREE.Vector3.prototype = { getScaleFromMatrix: function ( m ) { - console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); + THREE.warning( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); return this.setFromMatrixScale( m ); }, getColumnFromMatrix: function ( index, matrix ) { - console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); + THREE.warning( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); return this.setFromMatrixColumn( index, matrix ); @@ -765,7 +765,7 @@ THREE.Vector3.prototype = { }, setFromMatrixColumn: function ( index, matrix ) { - + var offset = index * 4; var me = matrix.elements; diff --git a/src/math/Vector4.js b/src/math/Vector4.js index b0fbd7d4579a01..6fce492b746a09 100644 --- a/src/math/Vector4.js +++ b/src/math/Vector4.js @@ -105,7 +105,7 @@ THREE.Vector4.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warning( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -145,7 +145,7 @@ THREE.Vector4.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warning( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } diff --git a/src/objects/Mesh.js b/src/objects/Mesh.js index 3fe68e3c9e2a92..775a0352826ca5 100644 --- a/src/objects/Mesh.js +++ b/src/objects/Mesh.js @@ -49,7 +49,7 @@ THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) { } - console.log( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); + THREE.warning( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); return 0; diff --git a/src/objects/MorphAnimMesh.js b/src/objects/MorphAnimMesh.js index 35eb210203c421..a305e46bfc9919 100644 --- a/src/objects/MorphAnimMesh.js +++ b/src/objects/MorphAnimMesh.js @@ -109,7 +109,7 @@ THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) { } else { - console.warn( 'animation[' + label + '] undefined' ); + THREE.warning( 'animation[' + label + '] undefined' ); } diff --git a/src/objects/PointCloud.js b/src/objects/PointCloud.js index 9a14a6b010f3a3..2ba51f4abd210f 100644 --- a/src/objects/PointCloud.js +++ b/src/objects/PointCloud.js @@ -157,7 +157,7 @@ THREE.PointCloud.prototype.clone = function ( object ) { THREE.ParticleSystem = function ( geometry, material ) { - console.warn( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' ); + THREE.warning( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' ); return new THREE.PointCloud( geometry, material ); }; diff --git a/src/objects/Skeleton.js b/src/objects/Skeleton.js index 8fbb9983990fa4..41b6f0cdb4ad84 100644 --- a/src/objects/Skeleton.js +++ b/src/objects/Skeleton.js @@ -69,7 +69,7 @@ THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) { } else { - console.warn( 'THREE.Skeleton bonInverses is the wrong length.' ); + THREE.warning( 'THREE.Skeleton bonInverses is the wrong length.' ); this.boneInverses = []; diff --git a/src/objects/SkinnedMesh.js b/src/objects/SkinnedMesh.js index 7be365aca83f54..c122109477ad6a 100644 --- a/src/objects/SkinnedMesh.js +++ b/src/objects/SkinnedMesh.js @@ -148,7 +148,7 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) { } else { - console.warn( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode ); + THREE.warning( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode ); } diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d10a7811df59d7..b66e21a26e2f1f 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -218,7 +218,7 @@ THREE.WebGLRenderer = function ( parameters ) { } catch ( error ) { - console.error( error ); + THREE.error( error ); } @@ -362,12 +362,12 @@ THREE.WebGLRenderer = function ( parameters ) { if ( mediumpAvailable ) { _precision = 'mediump'; - console.warn( 'THREE.WebGLRenderer: highp not supported, using mediump.' ); + THREE.warning( 'THREE.WebGLRenderer: highp not supported, using mediump.' ); } else { _precision = 'lowp'; - console.warn( 'THREE.WebGLRenderer: highp and mediump not supported, using lowp.' ); + THREE.warning( 'THREE.WebGLRenderer: highp and mediump not supported, using lowp.' ); } @@ -376,7 +376,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _precision === 'mediump' && ! mediumpAvailable ) { _precision = 'lowp'; - console.warn( 'THREE.WebGLRenderer: mediump not supported, using lowp.' ); + THREE.warning( 'THREE.WebGLRenderer: mediump not supported, using lowp.' ); } @@ -535,7 +535,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.setClearColorHex = function ( hex, alpha ) { - console.warn( 'THREE.WebGLRenderer: .setClearColorHex() is being removed. Use .setClearColor() instead.' ); + THREE.warning( 'THREE.WebGLRenderer: .setClearColorHex() is being removed. Use .setClearColor() instead.' ); this.setClearColor( hex, alpha ); }; @@ -3231,7 +3231,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( camera instanceof THREE.Camera === false ) { - console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); + THREE.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); return; } @@ -4802,7 +4802,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( textureUnit >= _maxTextures ) { - console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures ); + THREE.warning( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures ); } @@ -5140,7 +5140,7 @@ THREE.WebGLRenderer = function ( parameters ) { default: - console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type ); + THREE.warning( 'THREE.WebGLRenderer: Unknown uniform type: ' + type ); } @@ -5646,7 +5646,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) { - console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' ); + THREE.warning( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' ); } @@ -5655,7 +5655,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) { - console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( ' + texture.sourceFile + ' )' ); + THREE.warning( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( ' + texture.sourceFile + ' )' ); } @@ -5744,7 +5744,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - console.warn( "Attempt to load unsupported compressed texture format" ); + THREE.warning( "Attempt to load unsupported compressed texture format" ); } @@ -5821,7 +5821,7 @@ THREE.WebGLRenderer = function ( parameters ) { var context = canvas.getContext( '2d' ); context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); - console.log( 'THREE.WebGLRenderer:', image, 'is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height + '.' ); + THREE.warning( 'THREE.WebGLRenderer:', image, 'is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height + '.' ); return canvas; @@ -5908,7 +5908,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - console.warn( "Attempt to load unsupported compressed texture format" ); + THREE.warning( "Attempt to load unsupported compressed texture format" ); } @@ -6287,7 +6287,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( maxBones < object.skeleton.bones.length ) { - console.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' ); + THREE.warning( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' ); } @@ -6346,25 +6346,25 @@ THREE.WebGLRenderer = function ( parameters ) { this.initMaterial = function () { - console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); + THREE.warning( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); }; this.addPrePlugin = function () { - console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); + THREE.warning( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); }; this.addPostPlugin = function () { - console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); + THREE.warning( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); }; this.updateShadowMap = function () { - console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); + THREE.warning( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); }; diff --git a/src/renderers/webgl/WebGLExtensions.js b/src/renderers/webgl/WebGLExtensions.js index f9c154c18cbcd9..9306d45e22dcb1 100644 --- a/src/renderers/webgl/WebGLExtensions.js +++ b/src/renderers/webgl/WebGLExtensions.js @@ -37,7 +37,7 @@ THREE.WebGLExtensions = function ( gl ) { if ( extension === null ) { - console.log( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); + THREE.warning( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); } diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 31bb5e22c96e6f..1570e0805259f4 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -336,17 +336,17 @@ THREE.WebGLProgram = ( function () { if ( _gl.getProgramParameter( program, _gl.LINK_STATUS ) === false ) { - console.error( 'THREE.WebGLProgram: Could not initialise shader.' ); - console.error( 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) ); - console.error( 'gl.getError()', _gl.getError() ); + THREE.error( 'THREE.WebGLProgram: Could not initialise shader.' ); + THREE.error( 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) ); + THREE.error( 'gl.getError()', _gl.getError() ); } if ( _gl.getProgramInfoLog( program ) !== '' ) { - console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', _gl.getProgramInfoLog( program ) ); - // console.warn( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); - // console.warn( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); + THREE.warning( 'THREE.WebGLProgram: gl.getProgramInfoLog()', _gl.getProgramInfoLog( program ) ); + // THREE.warning( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); + // THREE.warning( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); } diff --git a/src/renderers/webgl/WebGLShader.js b/src/renderers/webgl/WebGLShader.js index 0948a6997b4850..e20f7fec795cf5 100644 --- a/src/renderers/webgl/WebGLShader.js +++ b/src/renderers/webgl/WebGLShader.js @@ -23,14 +23,14 @@ THREE.WebGLShader = ( function () { if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) { - console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); + THREE.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); } if ( gl.getShaderInfoLog( shader ) !== '' ) { - console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ) ); - console.warn( addLineNumbers( string ) ); + THREE.warning( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ) ); + THREE.warning( addLineNumbers( string ) ); } diff --git a/src/renderers/webgl/plugins/ShadowMapPlugin.js b/src/renderers/webgl/plugins/ShadowMapPlugin.js index 82eac2d8d1fac2..65d64c4600c899 100644 --- a/src/renderers/webgl/plugins/ShadowMapPlugin.js +++ b/src/renderers/webgl/plugins/ShadowMapPlugin.js @@ -122,7 +122,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje light.shadowCascadeArray[ n ] = virtualLight; - console.log( "Created virtualLight", virtualLight ); + //console.log( "Created virtualLight", virtualLight ); } else { @@ -183,7 +183,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje } else { - console.error( "Unsupported light type for shadow" ); + THREE.error( "Unsupported light type for shadow" ); continue; } From 0e80b447e168a2863cd9a84f6ce1be1abe8e0529 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 19 Dec 2014 14:43:59 -0500 Subject: [PATCH 006/333] avoid outputting undefined unnecessarily. --- src/Three.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Three.js b/src/Three.js index 497ebda8d272fe..a03e2aac11b044 100644 --- a/src/Three.js +++ b/src/Three.js @@ -27,7 +27,7 @@ if ( Math.sign === undefined ) { THREE.ExceptionErrorHandler = function( message, optionalData ) { console.error( message ); - console.error( optionalData ); + if( optionalData ) console.error( optionalData ); var error = new Error( message ); error.optionalData = optionalData; throw error; @@ -35,12 +35,12 @@ THREE.ExceptionErrorHandler = function( message, optionalData ) { THREE.ConsoleErrorHandler = function( message, optionalData ) { console.error( message ); - console.error( optionalData ); + if( optionalData ) console.error( optionalData ); }; THREE.ConsoleWarningHandler = function( message, optionalData ) { console.warn( message ); - console.warn( optionalData ); + if( optionalData ) console.warn( optionalData ); }; THREE.NullHandler = function( message, optionalData ) { From c6c3e32e8b4d08d87274d3245b7cafd92e3c6acc Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 19 Dec 2014 15:39:07 -0500 Subject: [PATCH 007/333] fix error message formatting, needs to be one line with THREE.warning. --- src/renderers/WebGLRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index b66e21a26e2f1f..4f6bfac8639538 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -5821,7 +5821,7 @@ THREE.WebGLRenderer = function ( parameters ) { var context = canvas.getContext( '2d' ); context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); - THREE.warning( 'THREE.WebGLRenderer:', image, 'is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height + '.' ); + THREE.warning( 'THREE.WebGLRenderer:' + image + 'is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height + '.' ); return canvas; From 7f656a89ac59b78543cc754cb9a1104e8b8a6426 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 19 Dec 2014 15:43:20 -0500 Subject: [PATCH 008/333] make use of optionalData on THREE.error. --- src/renderers/webgl/WebGLProgram.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 1570e0805259f4..e7387b6495bc38 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -334,17 +334,20 @@ THREE.WebGLProgram = ( function () { _gl.linkProgram( program ); + var programLogInfo = _gl.getProgramInfoLog( program ); + if ( _gl.getProgramParameter( program, _gl.LINK_STATUS ) === false ) { - THREE.error( 'THREE.WebGLProgram: Could not initialise shader.' ); - THREE.error( 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) ); - THREE.error( 'gl.getError()', _gl.getError() ); + THREE.error( 'THREE.WebGLProgram: shader error: ' + _gl.getError(), { + 'gl.VALIDATE_STATUS': _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ), + 'gl.getPRogramInfoLog': programLogInfo + }); } + + if ( programLogInfo !== '' ) { - if ( _gl.getProgramInfoLog( program ) !== '' ) { - - THREE.warning( 'THREE.WebGLProgram: gl.getProgramInfoLog()', _gl.getProgramInfoLog( program ) ); + THREE.warning( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLogInfo ); // THREE.warning( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); // THREE.warning( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); From 71944ab20f57e260e238dd2f570e28d745821af7 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 22 Dec 2014 09:15:04 -0500 Subject: [PATCH 009/333] use arguments variable to simplify ThreeJS error/warning handlers per @mrdoob's comments here: https://github.com/mrdoob/three.js/pull/5791#issuecomment-67733222 --- src/Three.js | 19 ++++++++----------- src/core/Object3D.js | 4 ++-- src/renderers/WebGLRenderer.js | 2 +- src/renderers/webgl/WebGLProgram.js | 7 ++----- src/renderers/webgl/WebGLShader.js | 3 +-- 5 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/Three.js b/src/Three.js index a03e2aac11b044..fc762345254b5e 100644 --- a/src/Three.js +++ b/src/Three.js @@ -25,25 +25,22 @@ if ( Math.sign === undefined ) { } -THREE.ExceptionErrorHandler = function( message, optionalData ) { - console.error( message ); - if( optionalData ) console.error( optionalData ); +THREE.ExceptionErrorHandler = function( message ) { + console.error( arguments ); var error = new Error( message ); - error.optionalData = optionalData; + error.optionalData = arguments; throw error; }; -THREE.ConsoleErrorHandler = function( message, optionalData ) { - console.error( message ); - if( optionalData ) console.error( optionalData ); +THREE.ConsoleErrorHandler = function() { + console.error( arguments ); }; -THREE.ConsoleWarningHandler = function( message, optionalData ) { - console.warn( message ); - if( optionalData ) console.warn( optionalData ); +THREE.ConsoleWarningHandler = function() { + console.warn( arguments ); }; -THREE.NullHandler = function( message, optionalData ) { +THREE.NullHandler = function() { }; // set the default error handlers diff --git a/src/core/Object3D.js b/src/core/Object3D.js index adedff10f692ee..f2e24718abd475 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -314,7 +314,7 @@ THREE.Object3D.prototype = { if ( object === this ) { - THREE.error( "THREE.Object3D.add:", object, "can't be added as a child of itself." ); + THREE.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); return this; } @@ -334,7 +334,7 @@ THREE.Object3D.prototype = { } else { - THREE.error( "THREE.Object3D.add:", object, "is not an instance of THREE.Object3D." ); + THREE.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); } diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 4f6bfac8639538..b86d1bb7a6a554 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -5821,7 +5821,7 @@ THREE.WebGLRenderer = function ( parameters ) { var context = canvas.getContext( '2d' ); context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); - THREE.warning( 'THREE.WebGLRenderer:' + image + 'is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height + '.' ); + THREE.warning( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image ); return canvas; diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index e7387b6495bc38..238616e169ebcb 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -338,16 +338,13 @@ THREE.WebGLProgram = ( function () { if ( _gl.getProgramParameter( program, _gl.LINK_STATUS ) === false ) { - THREE.error( 'THREE.WebGLProgram: shader error: ' + _gl.getError(), { - 'gl.VALIDATE_STATUS': _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ), - 'gl.getPRogramInfoLog': programLogInfo - }); + THREE.error( 'THREE.WebGLProgram: shader error: ' + _gl.getError(), 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ), 'gl.getPRogramInfoLog', programLogInfo ); } if ( programLogInfo !== '' ) { - THREE.warning( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLogInfo ); + THREE.warning( 'THREE.WebGLProgram: gl.getProgramInfoLog()' + programLogInfo ); // THREE.warning( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); // THREE.warning( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); diff --git a/src/renderers/webgl/WebGLShader.js b/src/renderers/webgl/WebGLShader.js index e20f7fec795cf5..ee1bebd0a56179 100644 --- a/src/renderers/webgl/WebGLShader.js +++ b/src/renderers/webgl/WebGLShader.js @@ -29,8 +29,7 @@ THREE.WebGLShader = ( function () { if ( gl.getShaderInfoLog( shader ) !== '' ) { - THREE.warning( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ) ); - THREE.warning( addLineNumbers( string ) ); + THREE.warning( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ), addLineNumbers( string ) ); } From fd500a63e99e0474ce11f70f4bd67fba2f059320 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 22 Dec 2014 14:21:45 -0500 Subject: [PATCH 010/333] ensure that lightMap is modulated by surface color and then added to resulting fragColor. --- .../ShaderChunk/lightmap_fragment.glsl | 10 +++++++++- .../ShaderChunk/lights_phong_fragment.glsl | 20 +++++++++---------- .../shaders/ShaderChunk/map_fragment.glsl | 6 ++++++ src/renderers/shaders/ShaderLib.js | 3 ++- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl index 5f4afaa00e6046..4b94ee35ac1e8f 100644 --- a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl @@ -1,5 +1,13 @@ #ifdef USE_LIGHTMAP - gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 ); + #if defined( PHONG ) + + gl_FragColor += diffuseColor * texture2D( lightMap, vUv2 ); + + #else + + gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 ); + + #endif #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 49d949d1820468..0202290e4fb61b 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -33,7 +33,7 @@ vec3 viewPosition = normalize( vViewPosition ); lVector = normalize( lVector ); - // diffuse + // diffuse float dotProduct = dot( normal, lVector ); @@ -50,7 +50,7 @@ vec3 viewPosition = normalize( vViewPosition ); #endif - pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance; + pointDiffuse += pointLightColor[ i ] * pointDiffuseWeight * lDistance; // specular @@ -89,7 +89,7 @@ vec3 viewPosition = normalize( vViewPosition ); spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 ); - // diffuse + // diffuse float dotProduct = dot( normal, lVector ); @@ -106,9 +106,9 @@ vec3 viewPosition = normalize( vViewPosition ); #endif - spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect; + spotDiffuse += spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect; - // specular + // specular vec3 spotHalfVector = normalize( lVector + viewPosition ); float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 ); @@ -135,7 +135,7 @@ vec3 viewPosition = normalize( vViewPosition ); vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 ); vec3 dirVector = normalize( lDirection.xyz ); - // diffuse + // diffuse float dotProduct = dot( normal, dirVector ); @@ -152,7 +152,7 @@ vec3 viewPosition = normalize( vViewPosition ); #endif - dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight; + dirDiffuse += directionalLightColor[ i ] * dirDiffuseWeight; // specular @@ -208,7 +208,7 @@ vec3 viewPosition = normalize( vViewPosition ); vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ); - hemiDiffuse += diffuse * hemiColor; + hemiDiffuse += hemiColor; // specular (sky light) @@ -269,10 +269,10 @@ vec3 totalSpecular = vec3( 0.0 ); #ifdef METAL - gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular ); + gl_FragColor.xyz = diffuseColor * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular ); #else - gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular; + gl_FragColor.xyz = diffuseColor * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular; #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/map_fragment.glsl b/src/renderers/shaders/ShaderChunk/map_fragment.glsl index 7773eebbc37a8f..560cd9962665a9 100644 --- a/src/renderers/shaders/ShaderChunk/map_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/map_fragment.glsl @@ -9,5 +9,11 @@ #endif gl_FragColor = gl_FragColor * texelColor; + + #if defined( PHONG ) + + diffuseColor *= texelColor.xyz; + + #endif #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 5c88cfb1825e79..725c52647e71db 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -186,7 +186,7 @@ THREE.ShaderLib = { "void main() {", " gl_FragColor = vec4( vec3( 1.0 ), opacity );", - + THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], THREE.ShaderChunk[ "alphamap_fragment" ], @@ -319,6 +319,7 @@ THREE.ShaderLib = { "void main() {", " gl_FragColor = vec4( vec3( 1.0 ), opacity );", + " vec3 diffuseColor = diffuse;", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], From cc7634efa2ac6783ee58a5aa5893bd9ba71814bc Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 23 Dec 2014 11:39:40 -0500 Subject: [PATCH 011/333] refactor shaders to use diffuseColor and outgoingLight instead of gl_FragColor. --- examples/js/ShaderSkin.js | 47 ++++------- examples/js/ShaderTerrain.js | 58 ++++--------- .../js/shaders/NormalDisplacementShader.js | 84 +++++-------------- examples/webgl_materials2.html | 8 +- .../ShaderChunk/alphamap_fragment.glsl | 2 +- .../ShaderChunk/alphatest_fragment.glsl | 2 +- .../shaders/ShaderChunk/color_fragment.glsl | 2 +- .../shaders/ShaderChunk/envmap_fragment.glsl | 6 +- .../shaders/ShaderChunk/fog_fragment.glsl | 2 +- .../ShaderChunk/lightmap_fragment.glsl | 10 +-- .../ShaderChunk/lights_phong_fragment.glsl | 66 +++------------ .../ShaderChunk/linear_to_gamma_fragment.glsl | 2 +- .../shaders/ShaderChunk/map_fragment.glsl | 10 +-- .../ShaderChunk/map_particle_fragment.glsl | 2 +- .../ShaderChunk/shadowmap_fragment.glsl | 6 +- src/renderers/shaders/ShaderLib.js | 49 +++++++---- 16 files changed, 121 insertions(+), 235 deletions(-) diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 3b155e7775114b..b63378e4c13578 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -159,12 +159,13 @@ THREE.ShaderSkin = { "void main() {", - "gl_FragColor = vec4( vec3( 1.0 ), opacity );", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", "vec4 colDiffuse = texture2D( tDiffuse, vUv );", "colDiffuse.rgb *= colDiffuse.rgb;", - "gl_FragColor = gl_FragColor * colDiffuse;", + "diffuseColor = diffuseColor * colDiffuse;", "vec3 normal = normalize( vNormal );", "vec3 viewPosition = normalize( vViewPosition );", @@ -190,12 +191,11 @@ THREE.ShaderSkin = { // point lights - "vec3 specularTotal = vec3( 0.0 );", + "vec3 totalSpecularLight = vec3( 0.0 );", + "vec3 totalDiffuseLight = vec3( 0.0 );", "#if MAX_POINT_LIGHTS > 0", - "vec3 pointTotal = vec3( 0.0 );", - "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", @@ -215,8 +215,8 @@ THREE.ShaderSkin = { "float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );", - "pointTotal += lDistance * diffuse * pointLightColor[ i ] * pointDiffuseWeight;", - "specularTotal += lDistance * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;", + "totalDiffuseLight += lDistance * pointLightColor[ i ] * pointDiffuseWeight;", + "totalSpecularLight += lDistance * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;", "}", @@ -226,8 +226,6 @@ THREE.ShaderSkin = { "#if MAX_DIR_LIGHTS > 0", - "vec3 dirTotal = vec3( 0.0 );", - "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", @@ -240,8 +238,8 @@ THREE.ShaderSkin = { "float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );", - "dirTotal += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;", - "specularTotal += specular * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;", + "totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;", + "totalSpecularLight += specular * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;", "}", @@ -251,8 +249,6 @@ THREE.ShaderSkin = { "#if MAX_HEMI_LIGHTS > 0", - "vec3 hemiTotal = vec3( 0.0 );", - "for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {", "vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );", @@ -261,7 +257,7 @@ THREE.ShaderSkin = { "float dotProduct = dot( normal, lVector );", "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - "hemiTotal += diffuse * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", + "totalDiffuseLight += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", // specular (sky light) @@ -273,34 +269,21 @@ THREE.ShaderSkin = { "vec3 lVectorGround = -lVector;", "hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewPosition, uRoughness, uSpecularBrightness );", - "specularTotal += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;", + "totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;", "}", "#endif", - // all lights contribution summation - - "vec3 totalLight = vec3( 0.0 );", - - "#if MAX_DIR_LIGHTS > 0", - "totalLight += dirTotal;", - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - "totalLight += pointTotal;", - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - "totalLight += hemiTotal;", - "#endif", - - "gl_FragColor.xyz = gl_FragColor.xyz * ( totalLight + ambientLightColor * ambient ) + specularTotal;", + "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight;", THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + + "}" ].join("\n"), diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index 391e03c30ce869..4fc546a606fc4c 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -118,7 +118,8 @@ THREE.ShaderTerrain = { "void main() {", - "gl_FragColor = vec4( vec3( 1.0 ), opacity );", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", "vec3 specularTex = vec3( 1.0 );", @@ -141,15 +142,15 @@ THREE.ShaderTerrain = { "#endif", - "gl_FragColor = gl_FragColor * mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );", + "diffuseColor *= mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );", " } else if( enableDiffuse1 ) {", - "gl_FragColor = gl_FragColor * texture2D( tDiffuse1, uvOverlay );", + "diffuseColor *= texture2D( tDiffuse1, uvOverlay );", "} else if( enableDiffuse2 ) {", - "gl_FragColor = gl_FragColor * texture2D( tDiffuse2, uvOverlay );", + "diffuseColor *= texture2D( tDiffuse2, uvOverlay );", "}", @@ -162,13 +163,13 @@ THREE.ShaderTerrain = { "vec3 normal = normalize( finalNormal );", "vec3 viewPosition = normalize( vViewPosition );", + "vec3 totalDiffuseLight = vec3( 0.0 );", + "vec3 totalSpecularLight = vec3( 0.0 );", + // point lights "#if MAX_POINT_LIGHTS > 0", - "vec3 pointDiffuse = vec3( 0.0 );", - "vec3 pointSpecular = vec3( 0.0 );", - "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", @@ -188,8 +189,8 @@ THREE.ShaderTerrain = { "float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );", - "pointDiffuse += pointDistance * pointLightColor[ i ] * diffuse * pointDiffuseWeight;", - "pointSpecular += pointDistance * pointLightColor[ i ] * specular * pointSpecularWeight * pointDiffuseWeight;", + "totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;", + "totalSpecularLight += pointDistance * pointLightColor[ i ] * specular * pointSpecularWeight * pointDiffuseWeight;", "}", @@ -214,8 +215,8 @@ THREE.ShaderTerrain = { "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );", - "dirDiffuse += directionalLightColor[ i ] * diffuse * dirDiffuseWeight;", - "dirSpecular += directionalLightColor[ i ] * specular * dirSpecularWeight * dirDiffuseWeight;", + "totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;", + "totalSpecularLight += directionalLightColor[ i ] * specular * dirSpecularWeight * dirDiffuseWeight;", "}", @@ -238,7 +239,7 @@ THREE.ShaderTerrain = { "float dotProduct = dot( normal, lVector );", "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - "hemiDiffuse += diffuse * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", + "totalDiffuseLight += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", // specular (sky light) @@ -256,45 +257,22 @@ THREE.ShaderTerrain = { "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;", "hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );", - "hemiSpecular += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;", + "totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;", "}", "#endif", - // all lights contribution summation - - "vec3 totalDiffuse = vec3( 0.0 );", - "vec3 totalSpecular = vec3( 0.0 );", - - "#if MAX_DIR_LIGHTS > 0", - - "totalDiffuse += dirDiffuse;", - "totalSpecular += dirSpecular;", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - "totalDiffuse += hemiDiffuse;", - "totalSpecular += hemiSpecular;", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - "totalDiffuse += pointDiffuse;", - "totalSpecular += pointSpecular;", - - "#endif", - //"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient) + totalSpecular;", - "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient + totalSpecular );", + "outgoingLight.rgb += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight );", THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + + "}" ].join("\n"), diff --git a/examples/js/shaders/NormalDisplacementShader.js b/examples/js/shaders/NormalDisplacementShader.js index 9273c073ad873a..cea0de2b924458 100644 --- a/examples/js/shaders/NormalDisplacementShader.js +++ b/examples/js/shaders/NormalDisplacementShader.js @@ -135,7 +135,8 @@ THREE.NormalDisplacementShader = { "void main() {", THREE.ShaderChunk[ "logdepthbuf_fragment" ], - " gl_FragColor = vec4( vec3( 1.0 ), opacity );", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", " vec3 specularTex = vec3( 1.0 );", @@ -150,11 +151,11 @@ THREE.NormalDisplacementShader = { " vec4 texelColor = texture2D( tDiffuse, vUv );", " texelColor.xyz *= texelColor.xyz;", - " gl_FragColor = gl_FragColor * texelColor;", + " diffuseColor *= texelColor;", " #else", - " gl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );", + " diffuseColor *= texture2D( tDiffuse, vUv );", " #endif", @@ -167,11 +168,11 @@ THREE.NormalDisplacementShader = { " vec4 aoColor = texture2D( tAO, vUv );", " aoColor.xyz *= aoColor.xyz;", - " gl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;", + " diffuseColor.rgb *= aoColor.xyz;", " #else", - " gl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;", + " diffuseColor.rgb *= texture2D( tAO, vUv ).xyz;", " #endif", @@ -194,13 +195,13 @@ THREE.NormalDisplacementShader = { " vec3 normal = normalize( finalNormal );", " vec3 viewPosition = normalize( vViewPosition );", + " vec3 totalDiffuseLight = vec3( 0.0 );", + " vec3 totalSpecularLight = vec3( 0.0 );", + // point lights " #if MAX_POINT_LIGHTS > 0", - " vec3 pointDiffuse = vec3( 0.0 );", - " vec3 pointSpecular = vec3( 0.0 );", - " for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", " vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", @@ -227,7 +228,7 @@ THREE.NormalDisplacementShader = { " #endif", - " pointDiffuse += pointDistance * pointLightColor[ i ] * diffuse * pointDiffuseWeight;", + " totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;", // specular @@ -238,7 +239,7 @@ THREE.NormalDisplacementShader = { " float specularNormalization = ( shininess + 2.0 ) / 8.0;", " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( pointVector, pointHalfVector ), 0.0 ), 5.0 );", - " pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;", + " totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;", " }", @@ -248,9 +249,6 @@ THREE.NormalDisplacementShader = { " #if MAX_SPOT_LIGHTS > 0", - " vec3 spotDiffuse = vec3( 0.0 );", - " vec3 spotSpecular = vec3( 0.0 );", - " for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {", " vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );", @@ -283,7 +281,7 @@ THREE.NormalDisplacementShader = { " #endif", - " spotDiffuse += spotDistance * spotLightColor[ i ] * diffuse * spotDiffuseWeight * spotEffect;", + " totalDiffuseLight += spotDistance * spotLightColor[ i ] * spotDiffuseWeight * spotEffect;", // specular @@ -294,7 +292,7 @@ THREE.NormalDisplacementShader = { " float specularNormalization = ( shininess + 2.0 ) / 8.0;", " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( spotVector, spotHalfVector ), 0.0 ), 5.0 );", - " spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;", + " totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;", " }", @@ -306,9 +304,6 @@ THREE.NormalDisplacementShader = { " #if MAX_DIR_LIGHTS > 0", - " vec3 dirDiffuse = vec3( 0.0 );", - " vec3 dirSpecular = vec3( 0.0 );", - " for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", " vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", @@ -329,7 +324,7 @@ THREE.NormalDisplacementShader = { " #endif", - " dirDiffuse += directionalLightColor[ i ] * diffuse * dirDiffuseWeight;", + " totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;", // specular @@ -340,7 +335,7 @@ THREE.NormalDisplacementShader = { " float specularNormalization = ( shininess + 2.0 ) / 8.0;", " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );", - " dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;", + " totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;", " }", @@ -350,9 +345,6 @@ THREE.NormalDisplacementShader = { " #if MAX_HEMI_LIGHTS > 0", - " vec3 hemiDiffuse = vec3( 0.0 );", - " vec3 hemiSpecular = vec3( 0.0 );" , - " for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {", " vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );", @@ -365,7 +357,7 @@ THREE.NormalDisplacementShader = { " vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", - " hemiDiffuse += diffuse * hemiColor;", + " totalDiffuseLight += hemiColor;", // specular (sky light) @@ -388,52 +380,19 @@ THREE.NormalDisplacementShader = { " vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );", " vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );", - " hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );", + " totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );", " }", - " #endif", - - // all lights contribution summation - - " vec3 totalDiffuse = vec3( 0.0 );", - " vec3 totalSpecular = vec3( 0.0 );", - - " #if MAX_DIR_LIGHTS > 0", - - " totalDiffuse += dirDiffuse;", - " totalSpecular += dirSpecular;", - - " #endif", - - " #if MAX_HEMI_LIGHTS > 0", - - " totalDiffuse += hemiDiffuse;", - " totalSpecular += hemiSpecular;", - - " #endif", - - " #if MAX_POINT_LIGHTS > 0", - - " totalDiffuse += pointDiffuse;", - " totalSpecular += pointSpecular;", - - " #endif", - - " #if MAX_SPOT_LIGHTS > 0", - - " totalDiffuse += spotDiffuse;", - " totalSpecular += spotSpecular;", - " #endif", " #ifdef METAL", - " gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient + totalSpecular );", + " outgoingLight.xyz += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight );", " #else", - " gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient ) + totalSpecular;", + " outgoingLight.xyz += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight;", " #endif", @@ -459,7 +418,7 @@ THREE.NormalDisplacementShader = { " #endif", - " gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * reflectivity );", + " outgoingLight.xyz = mix( outgoingLight.xyz, cubeColor.xyz, specularTex.r * reflectivity );", " }", @@ -467,6 +426,9 @@ THREE.NormalDisplacementShader = { THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + + "}" ].join("\n"), diff --git a/examples/webgl_materials2.html b/examples/webgl_materials2.html index 85297a87266a20..f5e0250ee2bd56 100644 --- a/examples/webgl_materials2.html +++ b/examples/webgl_materials2.html @@ -69,10 +69,10 @@ shininess = 15; - materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0xffaa00, shininess: shininess, metal: true, shading: shading } ) ); - materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0xaaff00, shininess: shininess, metal: true, shading: shading } ) ); - materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0x00ffaa, shininess: shininess, metal: true, shading: shading } ) ); - materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0x00aaff, shininess: shininess, metal: true, shading: shading } ) ); + materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0xffaa00, shininess: shininess, metal: true, shading: shading } ) ); + materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0xaaff00, shininess: shininess, metal: true, shading: shading } ) ); + materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0x00ffaa, shininess: shininess, metal: true, shading: shading } ) ); + materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0x00aaff, shininess: shininess, metal: true, shading: shading } ) ); // Spheres geometry diff --git a/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl b/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl index 976c607cad4960..1aa712eb3aaa9c 100644 --- a/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl @@ -1,5 +1,5 @@ #ifdef USE_ALPHAMAP - gl_FragColor.a *= texture2D( alphaMap, vUv ).g; + diffuseColor.a *= texture2D( alphaMap, vUv ).g; #endif diff --git a/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl b/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl index e7d97a3b71bd57..448b2bf55661f7 100644 --- a/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl @@ -1,5 +1,5 @@ #ifdef ALPHATEST - if ( gl_FragColor.a < ALPHATEST ) discard; + if ( diffuseColor.a < ALPHATEST ) discard; #endif diff --git a/src/renderers/shaders/ShaderChunk/color_fragment.glsl b/src/renderers/shaders/ShaderChunk/color_fragment.glsl index 7a657096e95629..693fdf061c226f 100644 --- a/src/renderers/shaders/ShaderChunk/color_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/color_fragment.glsl @@ -1,5 +1,5 @@ #ifdef USE_COLOR - gl_FragColor = gl_FragColor * vec4( vColor, 1.0 ); + diffuseColor.rgb *= vColor; #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl index a44c2be9e7edfd..dcc7d32c815756 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl @@ -53,15 +53,15 @@ #ifdef ENVMAP_BLENDING_MULTIPLY - gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity ); + outgoingLight.xyz = mix( outgoingLight.xyz, outgoingLight.xyz * envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_MIX ) - gl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity ); + outgoingLight.xyz = mix( outgoingLight.xyz, envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_ADD ) - gl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity; + outgoingLight.xyz += envColor.xyz * specularStrength * reflectivity; #endif diff --git a/src/renderers/shaders/ShaderChunk/fog_fragment.glsl b/src/renderers/shaders/ShaderChunk/fog_fragment.glsl index 0ba51f224ccdaf..f851bb865fdb54 100644 --- a/src/renderers/shaders/ShaderChunk/fog_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/fog_fragment.glsl @@ -22,6 +22,6 @@ #endif - gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor ); + outgoingLight = mix( outgoingLight, fogColor, fogFactor ); #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl index 4b94ee35ac1e8f..6e373629889276 100644 --- a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl @@ -1,13 +1,5 @@ #ifdef USE_LIGHTMAP - #if defined( PHONG ) - - gl_FragColor += diffuseColor * texture2D( lightMap, vUv2 ); - - #else - - gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 ); - - #endif + outgoingLight += diffuseColor.xyz * texture2D( lightMap, vUv2 ).xyz; #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 0202290e4fb61b..da1cddaf1af720 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -17,10 +17,10 @@ vec3 viewPosition = normalize( vViewPosition ); #endif -#if MAX_POINT_LIGHTS > 0 +vec3 totalDiffuseLight = vec3( 0.0 ); +vec3 totalSpecularLight = vec3( 0.0 ); - vec3 pointDiffuse = vec3( 0.0 ); - vec3 pointSpecular = vec3( 0.0 ); +#if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { @@ -50,7 +50,7 @@ vec3 viewPosition = normalize( vViewPosition ); #endif - pointDiffuse += pointLightColor[ i ] * pointDiffuseWeight * lDistance; + totalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * lDistance; // specular @@ -61,7 +61,7 @@ vec3 viewPosition = normalize( vViewPosition ); float specularNormalization = ( shininess + 2.0 ) / 8.0; vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 ); - pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization; + totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization; } @@ -69,9 +69,6 @@ vec3 viewPosition = normalize( vViewPosition ); #if MAX_SPOT_LIGHTS > 0 - vec3 spotDiffuse = vec3( 0.0 ); - vec3 spotSpecular = vec3( 0.0 ); - for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 ); @@ -106,7 +103,7 @@ vec3 viewPosition = normalize( vViewPosition ); #endif - spotDiffuse += spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect; + totalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect; // specular @@ -117,7 +114,7 @@ vec3 viewPosition = normalize( vViewPosition ); float specularNormalization = ( shininess + 2.0 ) / 8.0; vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 ); - spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect; + totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect; } @@ -127,9 +124,6 @@ vec3 viewPosition = normalize( vViewPosition ); #if MAX_DIR_LIGHTS > 0 - vec3 dirDiffuse = vec3( 0.0 ); - vec3 dirSpecular = vec3( 0.0 ); - for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 ); @@ -152,7 +146,7 @@ vec3 viewPosition = normalize( vViewPosition ); #endif - dirDiffuse += directionalLightColor[ i ] * dirDiffuseWeight; + totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight; // specular @@ -184,7 +178,7 @@ vec3 viewPosition = normalize( vViewPosition ); // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel; vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 ); - dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization; + totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization; } @@ -193,9 +187,6 @@ vec3 viewPosition = normalize( vViewPosition ); #if MAX_HEMI_LIGHTS > 0 - vec3 hemiDiffuse = vec3( 0.0 ); - vec3 hemiSpecular = vec3( 0.0 ); - for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 ); @@ -208,7 +199,7 @@ vec3 viewPosition = normalize( vViewPosition ); vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ); - hemiDiffuse += hemiColor; + totalDiffuseLight += hemiColor; // specular (sky light) @@ -230,49 +221,18 @@ vec3 viewPosition = normalize( vViewPosition ); vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 ); vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 ); - hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) ); + totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) ); } #endif -vec3 totalDiffuse = vec3( 0.0 ); -vec3 totalSpecular = vec3( 0.0 ); - -#if MAX_DIR_LIGHTS > 0 - - totalDiffuse += dirDiffuse; - totalSpecular += dirSpecular; - -#endif - -#if MAX_HEMI_LIGHTS > 0 - - totalDiffuse += hemiDiffuse; - totalSpecular += hemiSpecular; - -#endif - -#if MAX_POINT_LIGHTS > 0 - - totalDiffuse += pointDiffuse; - totalSpecular += pointSpecular; - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - totalDiffuse += spotDiffuse; - totalSpecular += spotSpecular; - -#endif - #ifdef METAL - gl_FragColor.xyz = diffuseColor * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular ); + outgoingLight += diffuseColor.rgb * ( emissive + totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight ); #else - gl_FragColor.xyz = diffuseColor * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular; + outgoingLight += diffuseColor.rgb * ( emissive + totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight; #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl b/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl index 1af6c29d2f00bb..2f69ef0bb6bdbc 100644 --- a/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl @@ -1,5 +1,5 @@ #ifdef GAMMA_OUTPUT - gl_FragColor.xyz = sqrt( gl_FragColor.xyz ); + outgoingLight.xyz = sqrt( outgoingLight.xyz ); #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/map_fragment.glsl b/src/renderers/shaders/ShaderChunk/map_fragment.glsl index 560cd9962665a9..770ff5ec41f869 100644 --- a/src/renderers/shaders/ShaderChunk/map_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/map_fragment.glsl @@ -4,16 +4,10 @@ #ifdef GAMMA_INPUT - texelColor.xyz *= texelColor.xyz; + texelColor.rgb *= texelColor.rgb; #endif - gl_FragColor = gl_FragColor * texelColor; - - #if defined( PHONG ) - - diffuseColor *= texelColor.xyz; - - #endif + diffuseColor.rgb *= texelColor.rgb; #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl b/src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl index 3faf7b91fd6c75..1c2c4361e7d67f 100644 --- a/src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl @@ -1,5 +1,5 @@ #ifdef USE_MAP - gl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) ); + diffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) ); #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl index 87e592d37f13d4..09a9152fb0987c 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl @@ -197,11 +197,11 @@ #ifdef SHADOWMAP_CASCADE - if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ]; + if ( inFrustum && inFrustumCount == 1 ) outgoingLight *= frustumColors[ i ]; #else - if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ]; + if ( inFrustum ) outgoingLight *= frustumColors[ i ]; #endif @@ -215,6 +215,6 @@ #endif - gl_FragColor.xyz = gl_FragColor.xyz * shadowColor; + outgoingLight = outgoingLight * shadowColor; #endif diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 725c52647e71db..8e3757b8ab4897 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -1,4 +1,4 @@ -/** + /** * Webgl Shader Library for three.js * * @author alteredq / http://alteredqualia.com/ @@ -75,22 +75,28 @@ THREE.ShaderLib = { "void main() {", - " gl_FragColor = vec4( diffuse, opacity );", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], + THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "alphamap_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], - THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], + + " outgoingLight.rgb = diffuseColor.rgb;", // simple shader + + THREE.ShaderChunk[ "lightmap_fragment" ], // TODO: Light map on an otherwise unlit surface doesn't make sense. THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], + THREE.ShaderChunk[ "shadowmap_fragment" ], // TODO: Shadows on an otherwise unlit surface doesn't make sense. THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -185,10 +191,12 @@ THREE.ShaderLib = { "void main() {", - " gl_FragColor = vec4( vec3( 1.0 ), opacity );", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( 1.0, 1.0, 1.0, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], + THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "alphamap_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], @@ -199,18 +207,17 @@ THREE.ShaderLib = { //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;", " if ( gl_FrontFacing )", - " gl_FragColor.xyz *= vLightFront;", + " outgoingLight += diffuseColor.rgb * vLightFront;", " else", - " gl_FragColor.xyz *= vLightBack;", + " outgoingLight += diffuseColor.rgb * vLightBack;", " #else", - " gl_FragColor.xyz *= vLightFront;", + " outgoingLight += diffuseColor.rgb * vLightFront;", " #endif", THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "envmap_fragment" ], THREE.ShaderChunk[ "shadowmap_fragment" ], @@ -218,6 +225,8 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -318,11 +327,12 @@ THREE.ShaderLib = { "void main() {", - " gl_FragColor = vec4( vec3( 1.0 ), opacity );", - " vec3 diffuseColor = diffuse;", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], + THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "alphamap_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], @@ -330,7 +340,6 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "lights_phong_fragment" ], THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "envmap_fragment" ], THREE.ShaderChunk[ "shadowmap_fragment" ], @@ -338,6 +347,8 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -397,7 +408,8 @@ THREE.ShaderLib = { "void main() {", - " gl_FragColor = vec4( psColor, opacity );", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( psColor, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_particle_fragment" ], @@ -406,6 +418,8 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -474,12 +488,15 @@ THREE.ShaderLib = { " }", - " gl_FragColor = vec4( diffuse, opacity );", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -534,7 +551,7 @@ THREE.ShaderLib = { " #endif", " float color = 1.0 - smoothstep( mNear, mFar, depth );", - " gl_FragColor = vec4( vec3( color ), opacity );", + " gl_FragColor = vec4( vec3( color ), opacity );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects "}" From 80ff7d2adea7698fbbde26629a5bb6a39eef2816 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 23 Dec 2014 11:48:24 -0500 Subject: [PATCH 012/333] complete application of outgoingLight and diffuseColor to ShaderSkin.js --- examples/js/ShaderSkin.js | 52 ++++++++++++++------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index b63378e4c13578..d8e9cd8f7f8708 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -275,7 +275,7 @@ THREE.ShaderSkin = { "#endif", - "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight;", + "outgoingLight.xyz += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight;", THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "linear_to_gamma_fragment" ], @@ -457,9 +457,9 @@ THREE.ShaderSkin = { "void main() {", - "gl_FragColor = vec4( 1.0 );", + " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", - "vec4 mColor = vec4( diffuse, opacity );", "vec4 mSpecular = vec4( specular, opacity );", "vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;", @@ -469,7 +469,7 @@ THREE.ShaderSkin = { "vec4 colDiffuse = texture2D( tDiffuse, vUv );", "colDiffuse *= colDiffuse;", - "gl_FragColor = gl_FragColor * colDiffuse;", + "diffuseColor *= colDiffuse;", "mat3 tsb = mat3( vTangent, vBinormal, vNormal );", "vec3 finalNormal = tsb * normalTex;", @@ -479,12 +479,11 @@ THREE.ShaderSkin = { // point lights - "vec3 specularTotal = vec3( 0.0 );", + "vec3 totalDiffuseLight = vec3( 0.0 );", + "vec3 totalSpecularLight = vec3( 0.0 );", "#if MAX_POINT_LIGHTS > 0", - "vec4 pointTotal = vec4( vec3( 0.0 ), 1.0 );", - "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", "vec3 pointVector = normalize( vPointLight[ i ].xyz );", @@ -492,10 +491,10 @@ THREE.ShaderSkin = { "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );", - "pointTotal += pointDistance * vec4( pointLightColor[ i ], 1.0 ) * ( mColor * pointDiffuseWeight );", + "totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;", "if ( passID == 1 )", - "specularTotal += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );", + "totalSpecularLight += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );", "}", @@ -504,9 +503,7 @@ THREE.ShaderSkin = { // directional lights "#if MAX_DIR_LIGHTS > 0", - - "vec4 dirTotal = vec4( vec3( 0.0 ), 1.0 );", - + "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", @@ -515,32 +512,21 @@ THREE.ShaderSkin = { "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", - "dirTotal += vec4( directionalLightColor[ i ], 1.0 ) * ( mColor * dirDiffuseWeight );", + "totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;", "if ( passID == 1 )", - "specularTotal += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );", + "totalSpecularLight += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );", "}", "#endif", - // all lights contribution summation - - "vec4 totalLight = vec4( vec3( 0.0 ), opacity );", - - "#if MAX_DIR_LIGHTS > 0", - "totalLight += dirTotal;", - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - "totalLight += pointTotal;", - "#endif", - "gl_FragColor = gl_FragColor * totalLight;", + "outgoingLight += diffuseColor.rgb * totalDiffuseLight;", "if ( passID == 0 ) {", - "gl_FragColor = vec4( sqrt( gl_FragColor.xyz ), gl_FragColor.w );", + "gl_FragColor = vec4( sqrt( outgoingLight ), diffuseColor.w );", "} else if ( passID == 1 ) {", @@ -569,20 +555,18 @@ THREE.ShaderSkin = { //"gl_FragColor = vec4( vec3( 0.25, 0.6, 0.8 ) * nonblurColor + vec3( 0.15, 0.25, 0.2 ) * blur1Color + vec3( 0.15, 0.15, 0.0 ) * blur2Color + vec3( 0.45, 0.0, 0.0 ) * blur3Color, gl_FragColor.w );", - "gl_FragColor = vec4( vec3( 0.22, 0.437, 0.635 ) * nonblurColor + ", + "vec3 blurColor = vec3( vec3( 0.22, 0.437, 0.635 ) * nonblurColor + ", "vec3( 0.101, 0.355, 0.365 ) * blur1Color + ", "vec3( 0.119, 0.208, 0.0 ) * blur2Color + ", "vec3( 0.114, 0.0, 0.0 ) * blur3Color + ", - "vec3( 0.444, 0.0, 0.0 ) * blur4Color", - ", gl_FragColor.w );", + "vec3( 0.444, 0.0, 0.0 ) * blur4Color );", - "gl_FragColor.xyz *= pow( colDiffuse.xyz, vec3( 0.5 ) );", - "gl_FragColor.xyz += ambientLightColor * ambient * colDiffuse.xyz + specularTotal;", + "outgoingLight += ambientLightColor * sqrt( diffuseColor.rgb ) * blurColor + totalSpecularLight;", "#ifndef VERSION1", - "gl_FragColor.xyz = sqrt( gl_FragColor.xyz );", + "outgoingLight = sqrt( outgoingLight );", "#endif", @@ -590,6 +574,8 @@ THREE.ShaderSkin = { THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n"), From 93517e66c7aef4efdce05d5cd2d222831eb33bff Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 23 Dec 2014 11:57:57 -0500 Subject: [PATCH 013/333] fix bug related to semi-transparent maps. --- src/renderers/shaders/ShaderChunk/map_fragment.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderChunk/map_fragment.glsl b/src/renderers/shaders/ShaderChunk/map_fragment.glsl index 770ff5ec41f869..a0305c668d2123 100644 --- a/src/renderers/shaders/ShaderChunk/map_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/map_fragment.glsl @@ -8,6 +8,6 @@ #endif - diffuseColor.rgb *= texelColor.rgb; + diffuseColor *= texelColor; #endif \ No newline at end of file From 728f409415916e7b65aae0da8a7b73ea247fbbdb Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 23 Dec 2014 11:58:22 -0500 Subject: [PATCH 014/333] do not modulate emissive by diffuseColor. --- src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index da1cddaf1af720..e3268c5e064346 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -229,10 +229,10 @@ vec3 totalSpecularLight = vec3( 0.0 ); #ifdef METAL - outgoingLight += diffuseColor.rgb * ( emissive + totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight ); + outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight ) + emissive; #else - outgoingLight += diffuseColor.rgb * ( emissive + totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight; + outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight + emissive; #endif \ No newline at end of file From f15ae3a87b22398861633c1df5988e30b52c0df7 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 23 Dec 2014 12:04:06 -0500 Subject: [PATCH 015/333] replicate previous phong metal look -- it still isn't correct but at least it roughly matches previous look. --- examples/webgl_materials2.html | 8 ++++---- .../shaders/ShaderChunk/lights_phong_fragment.glsl | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/webgl_materials2.html b/examples/webgl_materials2.html index f5e0250ee2bd56..85297a87266a20 100644 --- a/examples/webgl_materials2.html +++ b/examples/webgl_materials2.html @@ -69,10 +69,10 @@ shininess = 15; - materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0xffaa00, shininess: shininess, metal: true, shading: shading } ) ); - materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0xaaff00, shininess: shininess, metal: true, shading: shading } ) ); - materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0x00ffaa, shininess: shininess, metal: true, shading: shading } ) ); - materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0x00aaff, shininess: shininess, metal: true, shading: shading } ) ); + materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0xffaa00, shininess: shininess, metal: true, shading: shading } ) ); + materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0xaaff00, shininess: shininess, metal: true, shading: shading } ) ); + materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0x00ffaa, shininess: shininess, metal: true, shading: shading } ) ); + materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0x00aaff, shininess: shininess, metal: true, shading: shading } ) ); // Spheres geometry diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index e3268c5e064346..0a043681a40adf 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -229,7 +229,7 @@ vec3 totalSpecularLight = vec3( 0.0 ); #ifdef METAL - outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight ) + emissive; + outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * ambient ) * specular + totalSpecularLight + emissive; #else From 91b34be36d44e0dd677603845ffef3ab5b44887a Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 23 Dec 2014 12:22:17 -0500 Subject: [PATCH 016/333] fix particle_basic to new outgoingLight/diffuseColor model. --- src/renderers/shaders/ShaderLib.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 8e3757b8ab4897..26ca1758f22818 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -413,8 +413,11 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_particle_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "color_fragment" ], + THREE.ShaderChunk[ "alphatest_fragment" ], + + " outgoingLight.rgb = diffuseColor.rgb;", // simple shader + THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], From 487e008ed5e7f98849b51b31590926f0cf4dbf52 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 23 Dec 2014 12:32:03 -0500 Subject: [PATCH 017/333] improve settings for light map example now that lightMap is properly modulated and additive. --- examples/webgl_materials_lightmap.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/webgl_materials_lightmap.html b/examples/webgl_materials_lightmap.html index dbbf8a2fb3296a..cb2caabacfbb26 100644 --- a/examples/webgl_materials_lightmap.html +++ b/examples/webgl_materials_lightmap.html @@ -100,14 +100,15 @@ // LIGHTS - var directionalLight = new THREE.DirectionalLight( 0xffffff, 1.475 ); + var directionalLight = new THREE.DirectionalLight( 0x333333, 1.475 ); directionalLight.position.set( 100, 100, -100 ); scene.add( directionalLight ); - var hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 1.25 ); - hemiLight.color.setHSL( 0.6, 1, 0.75 ); - hemiLight.groundColor.setHSL( 0.1, 0.8, 0.7 ); + var hemiLight = new THREE.HemisphereLight( 0x333333, 0x333333, 1.25 ); + hemiLight.color.setHSL( 0.6, 1, 0.375 ); + hemiLight.groundColor.setHSL( 0.1, 0.8, 0.35 ); + hemiLight.position.y = 500; scene.add( hemiLight ); From 1c24e4d1ad59c9a32de47beeded64b3dfd64e46a Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 29 Dec 2014 21:01:09 -0500 Subject: [PATCH 018/333] allowing for adjustable gamma factor in WebGLRenderer. --- src/math/Color.js | 21 ++++++++++------ src/renderers/WebGLRenderer.js | 39 ++++++++++++++--------------- src/renderers/webgl/WebGLProgram.js | 2 ++ 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/math/Color.js b/src/math/Color.js index d00573d1908cf2..4b31ac7af97402 100644 --- a/src/math/Color.js +++ b/src/math/Color.js @@ -173,21 +173,26 @@ THREE.Color.prototype = { }, - copyGammaToLinear: function ( color ) { + copyGammaToLinear: function ( color, gammaFactor ) { - this.r = color.r * color.r; - this.g = color.g * color.g; - this.b = color.b * color.b; + gammaFactor = gammaFactor || 2.0; + + this.r = Math.pow( color.r, gammaFactor ); + this.g = Math.pow( color.g, gammaFactor ); + this.b = Math.pow( color.b, gammaFactor ); return this; }, - copyLinearToGamma: function ( color ) { + copyLinearToGamma: function ( color, gammaFactor ) { + + gammaFactor = gammaFactor || 2.0; - this.r = Math.sqrt( color.r ); - this.g = Math.sqrt( color.g ); - this.b = Math.sqrt( color.b ); + var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; + this.r = Math.pow( color.r, safeInverse ); + this.g = Math.pow( color.g, safeInverse ); + this.b = Math.pow( color.b, safeInverse ); return this; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d10a7811df59d7..eff37bba81c166 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -58,6 +58,7 @@ THREE.WebGLRenderer = function ( parameters ) { // physically based shading + this.gammaFactor = 2.0; // for backwards compatibility this.gammaInput = false; this.gammaOutput = false; @@ -4524,7 +4525,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - uniforms.diffuse.value.copyGammaToLinear( material.color ); + uniforms.diffuse.value.copyGammaToLinear( material.color, this.gammaFactor ); } else { @@ -4658,9 +4659,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - uniforms.ambient.value.copyGammaToLinear( material.ambient ); - uniforms.emissive.value.copyGammaToLinear( material.emissive ); - uniforms.specular.value.copyGammaToLinear( material.specular ); + uniforms.ambient.value.copyGammaToLinear( material.ambient, this.gammaFactor ); + uniforms.emissive.value.copyGammaToLinear( material.emissive, this.gammaFactor ); + uniforms.specular.value.copyGammaToLinear( material.specular, this.gammaFactor ); } else { @@ -4682,8 +4683,8 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - uniforms.ambient.value.copyGammaToLinear( material.ambient ); - uniforms.emissive.value.copyGammaToLinear( material.emissive ); + uniforms.ambient.value.copyGammaToLinear( material.ambient, this.gammaFactor ); + uniforms.emissive.value.copyGammaToLinear( material.emissive, this.gammaFactor ); } else { @@ -5157,11 +5158,11 @@ THREE.WebGLRenderer = function ( parameters ) { // - function setColorGamma( array, offset, color, intensitySq ) { + function setColorGamma( array, offset, color, intensity ) { - array[ offset ] = color.r * color.r * intensitySq; - array[ offset + 1 ] = color.g * color.g * intensitySq; - array[ offset + 2 ] = color.b * color.b * intensitySq; + array[ offset ] = Math.pow( color.r * intensity, this.gammaFactor ); + array[ offset + 1 ] = Math.pow( color.g * intensity, this.gammaFactor ); + array[ offset + 2 ] = Math.pow( color.b * intensity, this.gammaFactor ); } @@ -5233,9 +5234,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - r += color.r * color.r; - g += color.g * color.g; - b += color.b * color.b; + r += Math.pow( color.r, this.gammaFactor ); + g += Math.pow( color.g, this.gammaFactor ); + b += Math.pow( color.b, this.gammaFactor ); } else { @@ -5264,7 +5265,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - setColorGamma( dirColors, dirOffset, color, intensity * intensity ); + setColorGamma( dirColors, dirOffset, color, intensity ); } else { @@ -5284,7 +5285,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - setColorGamma( pointColors, pointOffset, color, intensity * intensity ); + setColorGamma( pointColors, pointOffset, color, intensity ); } else { @@ -5312,7 +5313,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - setColorGamma( spotColors, spotOffset, color, intensity * intensity ); + setColorGamma( spotColors, spotOffset, color, intensity ); } else { @@ -5361,10 +5362,8 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - intensitySq = intensity * intensity; - - setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq ); - setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq ); + setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensity ); + setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensity ); } else { diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 31bb5e22c96e6f..f4eb84bc8d49cd 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -165,6 +165,7 @@ THREE.WebGLProgram = ( function () { _this.gammaInput ? "#define GAMMA_INPUT" : "", _this.gammaOutput ? "#define GAMMA_OUTPUT" : "", + "#define GAMMA_FACTOR " + this.renderer.gammaFactor, "#define MAX_DIR_LIGHTS " + parameters.maxDirLights, "#define MAX_POINT_LIGHTS " + parameters.maxPointLights, @@ -279,6 +280,7 @@ THREE.WebGLProgram = ( function () { _this.gammaInput ? "#define GAMMA_INPUT" : "", _this.gammaOutput ? "#define GAMMA_OUTPUT" : "", + "#define GAMMA_FACTOR " + this.renderer.gammaFactor, ( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "", ( parameters.useFog && parameters.fogExp ) ? "#define FOG_EXP2" : "", From af236a42f2e42fd27fd4630353375d515917e9ab Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 29 Dec 2014 22:05:53 -0500 Subject: [PATCH 019/333] completing adjustable gamma - still one bug left. --- examples/js/ShaderDeferred.js | 6 +--- examples/js/ShaderTerrain.js | 8 ++--- .../shaders/ShaderChunk/color_vertex.glsl | 10 +----- src/renderers/shaders/ShaderChunk/common.glsl | 16 +++++++++ .../shaders/ShaderChunk/envmap_fragment.glsl | 6 +--- .../ShaderChunk/linear_to_gamma_fragment.glsl | 5 +-- .../shaders/ShaderChunk/map_fragment.glsl | 6 +--- .../ShaderChunk/shadowmap_fragment.glsl | 7 ++-- src/renderers/shaders/ShaderLib.js | 35 +++---------------- src/renderers/webgl/WebGLProgram.js | 6 ++-- 10 files changed, 34 insertions(+), 71 deletions(-) diff --git a/examples/js/ShaderDeferred.js b/examples/js/ShaderDeferred.js index 3e6c52bf3ec2ee..b6d2bb75a5243b 100644 --- a/examples/js/ShaderDeferred.js +++ b/examples/js/ShaderDeferred.js @@ -225,11 +225,7 @@ THREE.ShaderDeferred = { "#endif", - "#ifdef GAMMA_INPUT", - - "cubeColor.xyz *= cubeColor.xyz;", - - "#endif", + "cubeColor.xyz = inputToLinear( cubeColor.xyz );", "if ( combine == 1 ) {", diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index 391e03c30ce869..81542bc58bd96c 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -134,12 +134,8 @@ THREE.ShaderTerrain = { "vec4 colDiffuse1 = texture2D( tDiffuse1, uvOverlay );", "vec4 colDiffuse2 = texture2D( tDiffuse2, uvOverlay );", - "#ifdef GAMMA_INPUT", - - "colDiffuse1.xyz *= colDiffuse1.xyz;", - "colDiffuse2.xyz *= colDiffuse2.xyz;", - - "#endif", + "colDiffuse1.xyz = inputToLinear( colDiffuse1.xyz );", + "colDiffuse2.xyz = inputToLinear( colDiffuse2.xyz );", "gl_FragColor = gl_FragColor * mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );", diff --git a/src/renderers/shaders/ShaderChunk/color_vertex.glsl b/src/renderers/shaders/ShaderChunk/color_vertex.glsl index 34439eed4e290f..70260dfcfa0dd1 100644 --- a/src/renderers/shaders/ShaderChunk/color_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/color_vertex.glsl @@ -1,13 +1,5 @@ #ifdef USE_COLOR - #ifdef GAMMA_INPUT - - vColor = square( color ); - - #else - - vColor = color; - - #endif + vColor.xyz = inputToLinear( color.xyz ); #endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index b14850181ee351..5766828f72b8ae 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -36,4 +36,20 @@ float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { } vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ); +} + +vec3 inputToLinear( in vec3 a ) { +#ifdef GAMMA_INPUT + return pow( a.rgb, vec3( float( GAMMA_FACTOR ) ) ); +#else + return a; +#endif +} + +vec3 linearToOutput( in vec3 a ) { +#ifdef GAMMA_OUTPUT + return pow( a.rgb, vec3( 1.0 / float( GAMMA_FACTOR ) ) ); +#else + return a; +#endif } \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl index 127a2458dabfb8..604c3484d0d2ff 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl @@ -43,11 +43,7 @@ vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 ); #endif - #ifdef GAMMA_INPUT - - envColor.xyz *= envColor.xyz; - - #endif + envColor.xyz = inputToLinear( envColor.xyz ); #ifdef ENVMAP_BLENDING_MULTIPLY diff --git a/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl b/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl index 1af6c29d2f00bb..6ab6b2e8b35397 100644 --- a/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl @@ -1,5 +1,2 @@ -#ifdef GAMMA_OUTPUT - gl_FragColor.xyz = sqrt( gl_FragColor.xyz ); - -#endif \ No newline at end of file + gl_FragColor.xyz = linearToOutput( gl_FragColor.xyz ); diff --git a/src/renderers/shaders/ShaderChunk/map_fragment.glsl b/src/renderers/shaders/ShaderChunk/map_fragment.glsl index 7773eebbc37a8f..15e91ca4b17536 100644 --- a/src/renderers/shaders/ShaderChunk/map_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/map_fragment.glsl @@ -2,11 +2,7 @@ vec4 texelColor = texture2D( map, vUv ); - #ifdef GAMMA_INPUT - - texelColor.xyz *= texelColor.xyz; - - #endif + texelColor.xyz = inputToLinear( texelColor.xyz ); gl_FragColor = gl_FragColor * texelColor; diff --git a/src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl index 87e592d37f13d4..d91bc51dd3340e 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl @@ -209,11 +209,8 @@ } - #ifdef GAMMA_OUTPUT - - shadowColor *= shadowColor; - - #endif + // NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014 + shadowColor = inputToLinear( shadowColor ); gl_FragColor.xyz = gl_FragColor.xyz * shadowColor; diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 4a2318e825dd61..795d9caf01c444 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -749,35 +749,15 @@ THREE.ShaderLib = { " if( enableDiffuse ) {", - " #ifdef GAMMA_INPUT", - - " vec4 texelColor = texture2D( tDiffuse, vUv );", - " texelColor.xyz *= texelColor.xyz;", - - " gl_FragColor = gl_FragColor * texelColor;", - - " #else", - - " gl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );", - - " #endif", + " vec4 texelColor = texture2D( tDiffuse, vUv );", + " texelColor.xyz = inputToLinear( texelColor.xyz );", + " gl_FragColor = gl_FragColor * texelColor;", " }", " if( enableAO ) {", - " #ifdef GAMMA_INPUT", - - " vec4 aoColor = texture2D( tAO, vUv );", - " aoColor.xyz *= aoColor.xyz;", - - " gl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;", - - " #else", - - " gl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;", - - " #endif", + " gl_FragColor.xyz = gl_FragColor.xyz * inputToLinear( texture2D( tAO, vUv ).xyz );", " }", @@ -1054,12 +1034,7 @@ THREE.ShaderLib = { " #endif", " vec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );", - - " #ifdef GAMMA_INPUT", - - " cubeColor.xyz *= cubeColor.xyz;", - - " #endif", + " cubeColor.xyz = inputToLinear( cubeColor.xyz );", " gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * reflectivity );", diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index f4eb84bc8d49cd..f6433a69162f4d 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -135,6 +135,8 @@ THREE.WebGLProgram = ( function () { } + var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; + // console.log( "building new program " ); // @@ -165,7 +167,7 @@ THREE.WebGLProgram = ( function () { _this.gammaInput ? "#define GAMMA_INPUT" : "", _this.gammaOutput ? "#define GAMMA_OUTPUT" : "", - "#define GAMMA_FACTOR " + this.renderer.gammaFactor, + "#define GAMMA_FACTOR " + gammaFactorDefine, "#define MAX_DIR_LIGHTS " + parameters.maxDirLights, "#define MAX_POINT_LIGHTS " + parameters.maxPointLights, @@ -280,7 +282,7 @@ THREE.WebGLProgram = ( function () { _this.gammaInput ? "#define GAMMA_INPUT" : "", _this.gammaOutput ? "#define GAMMA_OUTPUT" : "", - "#define GAMMA_FACTOR " + this.renderer.gammaFactor, + "#define GAMMA_FACTOR " + gammaFactorDefine, ( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "", ( parameters.useFog && parameters.fogExp ) ? "#define FOG_EXP2" : "", From 368b55f2cc57ace60b4cfebdd05f8c2ece676864 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 30 Dec 2014 10:38:20 -0500 Subject: [PATCH 020/333] clean up this versus _this in WebGLRenderer regards to gammaFactor. --- src/renderers/WebGLRenderer.js | 37 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index eff37bba81c166..541c1111ebcffd 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -4525,7 +4525,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - uniforms.diffuse.value.copyGammaToLinear( material.color, this.gammaFactor ); + uniforms.diffuse.value.copyGammaToLinear( material.color, _this.gammaFactor ); } else { @@ -4659,9 +4659,10 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - uniforms.ambient.value.copyGammaToLinear( material.ambient, this.gammaFactor ); - uniforms.emissive.value.copyGammaToLinear( material.emissive, this.gammaFactor ); - uniforms.specular.value.copyGammaToLinear( material.specular, this.gammaFactor ); + uniforms.ambient.value.copyGammaToLinear( material.ambient, _this.gammaFactor ); + uniforms.emissive.value.copyGammaToLinear( material.emissive, _this.gammaFactor ); + uniforms.specular.value.copyGammaToLinear( material.specular, _this.gammaFactor ); + } else { @@ -4683,8 +4684,8 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - uniforms.ambient.value.copyGammaToLinear( material.ambient, this.gammaFactor ); - uniforms.emissive.value.copyGammaToLinear( material.emissive, this.gammaFactor ); + uniforms.ambient.value.copyGammaToLinear( material.ambient, _this.gammaFactor ); + uniforms.emissive.value.copyGammaToLinear( material.emissive, _this.gammaFactor ); } else { @@ -5158,11 +5159,11 @@ THREE.WebGLRenderer = function ( parameters ) { // - function setColorGamma( array, offset, color, intensity ) { + function setColorGamma( array, offset, color, intensity, gammaFactor ) { - array[ offset ] = Math.pow( color.r * intensity, this.gammaFactor ); - array[ offset + 1 ] = Math.pow( color.g * intensity, this.gammaFactor ); - array[ offset + 2 ] = Math.pow( color.b * intensity, this.gammaFactor ); + array[ offset ] = Math.pow( color.r * intensity, gammaFactor ); + array[ offset + 1 ] = Math.pow( color.g * intensity, gammaFactor ); + array[ offset + 2 ] = Math.pow( color.b * intensity, gammaFactor ); } @@ -5234,9 +5235,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - r += Math.pow( color.r, this.gammaFactor ); - g += Math.pow( color.g, this.gammaFactor ); - b += Math.pow( color.b, this.gammaFactor ); + r += Math.pow( color.r, _this.gammaFactor ); + g += Math.pow( color.g, _this.gammaFactor ); + b += Math.pow( color.b, _this.gammaFactor ); } else { @@ -5265,7 +5266,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - setColorGamma( dirColors, dirOffset, color, intensity ); + setColorGamma( dirColors, dirOffset, color, intensity, _this.gammaFactor ); } else { @@ -5285,7 +5286,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - setColorGamma( pointColors, pointOffset, color, intensity ); + setColorGamma( pointColors, pointOffset, color, intensity, _this.gammaFactor ); } else { @@ -5313,7 +5314,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - setColorGamma( spotColors, spotOffset, color, intensity ); + setColorGamma( spotColors, spotOffset, color, intensity, _this.gammaFactor ); } else { @@ -5362,8 +5363,8 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.gammaInput ) { - setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensity ); - setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensity ); + setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensity, _this.gammaFactor ); + setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensity, _this.gammaFactor ); } else { From 1b940ff79fe2c9d93dfbd92ce16e54f069d29d76 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 30 Dec 2014 10:56:55 -0500 Subject: [PATCH 021/333] add gamma GUI to webgl_shading_physical.html. But it is slightly incorrect because the shaders are not properly recompiled upon gamma change. --- examples/webgl_shading_physical.html | 44 ++++++++++++++++--- src/renderers/shaders/ShaderChunk/common.glsl | 4 +- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/examples/webgl_shading_physical.html b/examples/webgl_shading_physical.html index baa287bc13f480..61d914e939cb4d 100644 --- a/examples/webgl_shading_physical.html +++ b/examples/webgl_shading_physical.html @@ -88,6 +88,10 @@ shadowBias: -0.0002, shadowDarkness: 0.3 + }, gamma = { + gammaFactor: 2.0, + gammaInput: true, + gammaOutput: true }; init(); @@ -385,44 +389,70 @@ gui = new dat.GUI(); - gui.add( shadowConfig, 'shadowCameraVisible' ).onChange( function() { + shadowGUI = gui.addFolder( "Shadow" ); + + shadowGUI.add( shadowConfig, 'shadowCameraVisible' ).onChange( function() { sunLight.shadowCameraVisible = shadowConfig.shadowCameraVisible; }); - gui.add( shadowConfig, 'shadowCameraNear', 1, 1500 ).onChange( function() { + shadowGUI.add( shadowConfig, 'shadowCameraNear', 1, 1500 ).onChange( function() { sunLight.shadowCamera.near = shadowConfig.shadowCameraNear; sunLight.shadowCamera.updateProjectionMatrix(); }); - gui.add( shadowConfig, 'shadowCameraFar', 1501, 5000 ).onChange( function() { + shadowGUI.add( shadowConfig, 'shadowCameraFar', 1501, 5000 ).onChange( function() { sunLight.shadowCamera.far = shadowConfig.shadowCameraFar; sunLight.shadowCamera.updateProjectionMatrix(); }); - gui.add( shadowConfig, 'shadowCameraFov', 1, 120 ).onChange( function() { + shadowGUI.add( shadowConfig, 'shadowCameraFov', 1, 120 ).onChange( function() { sunLight.shadowCamera.fov = shadowConfig.shadowCameraFov; sunLight.shadowCamera.updateProjectionMatrix(); }); - gui.add( shadowConfig, 'shadowBias', -0.01, 0.01 ).onChange( function() { + shadowGUI.add( shadowConfig, 'shadowBias', -0.01, 0.01 ).onChange( function() { sunLight.shadowBias = shadowConfig.shadowBias; }); - gui.add( shadowConfig, 'shadowDarkness', 0, 1 ).onChange( function() { + shadowGUI.add( shadowConfig, 'shadowDarkness', 0, 1 ).onChange( function() { }); + shadowGUI.open(); - gui.close(); + gammaGUI = gui.addFolder( "Gamma" ); + + gammaGUI.add( gamma, 'gammaFactor', 0.1, 4.0 ).onChange( function() { + + renderer.gammaFactor = gamma.gammaFactor; + + }); + gammaGUI.open(); + + /* + + Not exposed because they are not easily dynamically updated - as all shaders need to be recompiled. -bhouston + + gammaGUI.add( gamma, 'gammaInput', true ).onChange( function() { + + renderer.gammaInput = gamma.gammaInput; + + }); + + gammaGUI.add( gamma, 'gammaOutput', true ).onChange( function() { + + renderer.gammaOutput = gamma.gammaOutput; + + });*/ } diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 5766828f72b8ae..d022f7aaa77e3f 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -40,7 +40,7 @@ vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 poi vec3 inputToLinear( in vec3 a ) { #ifdef GAMMA_INPUT - return pow( a.rgb, vec3( float( GAMMA_FACTOR ) ) ); + return pow( a, vec3( float( GAMMA_FACTOR ) ) ); #else return a; #endif @@ -48,7 +48,7 @@ vec3 inputToLinear( in vec3 a ) { vec3 linearToOutput( in vec3 a ) { #ifdef GAMMA_OUTPUT - return pow( a.rgb, vec3( 1.0 / float( GAMMA_FACTOR ) ) ); + return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) ); #else return a; #endif From da09e160c7dcf2d374503993ac906d76fd78ced0 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 30 Dec 2014 13:37:17 -0500 Subject: [PATCH 022/333] remove exception error handler for now, not a necessary example. --- src/Three.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Three.js b/src/Three.js index fc762345254b5e..fd1e26498457bc 100644 --- a/src/Three.js +++ b/src/Three.js @@ -25,13 +25,6 @@ if ( Math.sign === undefined ) { } -THREE.ExceptionErrorHandler = function( message ) { - console.error( arguments ); - var error = new Error( message ); - error.optionalData = arguments; - throw error; -}; - THREE.ConsoleErrorHandler = function() { console.error( arguments ); }; From ad068a8757e917f2152ff123d30ecad3838d33f5 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 30 Dec 2014 13:38:31 -0500 Subject: [PATCH 023/333] ensure that "THREE.CLASSNAME:" prefixes all warnings and errors. Redirect two console.log warnings to THREE.warning for improved robustness. --- src/core/BufferGeometry.js | 2 +- src/extras/FontUtils.js | 2 +- src/extras/core/Curve.js | 2 +- src/extras/core/Shape.js | 2 +- src/extras/geometries/ExtrudeGeometry.js | 2 +- src/extras/objects/MorphBlendMesh.js | 2 +- src/loaders/JSONLoader.js | 2 +- src/math/Matrix4.js | 2 +- src/objects/MorphAnimMesh.js | 2 +- src/renderers/WebGLRenderer.js | 6 +++--- src/renderers/webgl/plugins/ShadowMapPlugin.js | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index 99c0d864e474f9..61648f6f4e2a6e 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -476,7 +476,7 @@ THREE.BufferGeometry.prototype = { this.attributes.normal === undefined || this.attributes.uv === undefined ) { - THREE.warning( 'Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); + THREE.warning( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); return; } diff --git a/src/extras/FontUtils.js b/src/extras/FontUtils.js index 49a9f38ec93a4e..2d4d54c9fb34dc 100644 --- a/src/extras/FontUtils.js +++ b/src/extras/FontUtils.js @@ -333,7 +333,7 @@ THREE.FontUtils.generateShapes = function ( text, parameters ) { //throw ( "Warning, unable to triangulate polygon!" ); //return null; // Sometimes warning is fine, especially polygons are triangulated in reverse. - console.log( 'Warning, unable to triangulate polygon!' ); + THREE.warning( 'THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()' ); if ( indices ) return vertIndices; return result; diff --git a/src/extras/core/Curve.js b/src/extras/core/Curve.js index 5e83a8751d7643..0289776eec906a 100644 --- a/src/extras/core/Curve.js +++ b/src/extras/core/Curve.js @@ -43,7 +43,7 @@ THREE.Curve = function () { THREE.Curve.prototype.getPoint = function ( t ) { - THREE.warning( "Warning, THREE.Curve.getPoint() not implemented!" ); + THREE.warning( "THREE.Curve: Warning, getPoint() not implemented!" ); return null; }; diff --git a/src/extras/core/Shape.js b/src/extras/core/Shape.js index e97891637a2c12..c28f4d61e28777 100644 --- a/src/extras/core/Shape.js +++ b/src/extras/core/Shape.js @@ -462,7 +462,7 @@ THREE.Shape.Utils = { if ( allPointsMap[ key ] !== undefined ) { - console.log( "Duplicate point", key ); + THREE.warning( "THREE.Shape: Duplicate point", key ); } diff --git a/src/extras/geometries/ExtrudeGeometry.js b/src/extras/geometries/ExtrudeGeometry.js index f42835d41567f3..b511496a964192 100644 --- a/src/extras/geometries/ExtrudeGeometry.js +++ b/src/extras/geometries/ExtrudeGeometry.js @@ -174,7 +174,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { function scalePt2 ( pt, vec, size ) { - if ( ! vec ) THREE.error( "vec does not exist" ); + if ( ! vec ) THREE.error( "THREE.ExtrudeGeometry: vec does not exist" ); return vec.clone().multiplyScalar( size ).add( pt ); diff --git a/src/extras/objects/MorphBlendMesh.js b/src/extras/objects/MorphBlendMesh.js index 6414406e3f009f..a42d390d949b3d 100644 --- a/src/extras/objects/MorphBlendMesh.js +++ b/src/extras/objects/MorphBlendMesh.js @@ -221,7 +221,7 @@ THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) { } else { - THREE.warning( "animation[" + name + "] undefined" ); + THREE.warning( "THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()" ); } diff --git a/src/loaders/JSONLoader.js b/src/loaders/JSONLoader.js index e1f003227dc4f2..2908a21e6f8628 100644 --- a/src/loaders/JSONLoader.js +++ b/src/loaders/JSONLoader.js @@ -454,7 +454,7 @@ THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - THREE.warning( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + + THREE.warning( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); } diff --git a/src/math/Matrix4.js b/src/math/Matrix4.js index c41c4a3c94a36b..06cb746f428174 100644 --- a/src/math/Matrix4.js +++ b/src/math/Matrix4.js @@ -634,7 +634,7 @@ THREE.Matrix4.prototype = { if ( det == 0 ) { - var msg = "Matrix4.getInverse(): can't invert matrix, determinant is 0"; + var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0"; if ( throwOnInvertible || false ) { diff --git a/src/objects/MorphAnimMesh.js b/src/objects/MorphAnimMesh.js index a305e46bfc9919..851ae51a905be8 100644 --- a/src/objects/MorphAnimMesh.js +++ b/src/objects/MorphAnimMesh.js @@ -109,7 +109,7 @@ THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) { } else { - THREE.warning( 'animation[' + label + '] undefined' ); + THREE.warning( 'THREE.MorphAnimMesh: animation[' + label + '] undefined in .playAnimation()' ); } diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index b86d1bb7a6a554..d75afbe1c0721d 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -218,7 +218,7 @@ THREE.WebGLRenderer = function ( parameters ) { } catch ( error ) { - THREE.error( error ); + THREE.error( 'THREE.WebGLRenderer: ' + error ); } @@ -5744,7 +5744,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - THREE.warning( "Attempt to load unsupported compressed texture format" ); + THREE.warning( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" ); } @@ -5908,7 +5908,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - THREE.warning( "Attempt to load unsupported compressed texture format" ); + THREE.warning( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()" ); } diff --git a/src/renderers/webgl/plugins/ShadowMapPlugin.js b/src/renderers/webgl/plugins/ShadowMapPlugin.js index 65d64c4600c899..3755aebdc1fd82 100644 --- a/src/renderers/webgl/plugins/ShadowMapPlugin.js +++ b/src/renderers/webgl/plugins/ShadowMapPlugin.js @@ -183,7 +183,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje } else { - THREE.error( "Unsupported light type for shadow" ); + THREE.error( "THREE.ShadowMapPlugin: Unsupported light type for shadow", light ); continue; } From c622b5be56709c54ff4aa0b4d2f35025dc01e01f Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 30 Dec 2014 22:30:45 -0500 Subject: [PATCH 024/333] make default decayExponent backwards compatible, so existing scenes are unchanged. --- src/lights/PointLight.js | 2 +- src/lights/SpotLight.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lights/PointLight.js b/src/lights/PointLight.js index 5cdce0cd896dbc..fb21de59a09ff4 100644 --- a/src/lights/PointLight.js +++ b/src/lights/PointLight.js @@ -10,7 +10,7 @@ THREE.PointLight = function ( color, intensity, distance, decayExponent ) { this.intensity = ( intensity !== undefined ) ? intensity : 1; this.distance = ( distance !== undefined ) ? distance : 0; - this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 0;; // for physically correct lights, should be 2. + this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 1; // for physically correct lights, should be 2. }; diff --git a/src/lights/SpotLight.js b/src/lights/SpotLight.js index f2281ee741fcb8..f409bbccc76879 100644 --- a/src/lights/SpotLight.js +++ b/src/lights/SpotLight.js @@ -15,7 +15,7 @@ THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decayE this.distance = ( distance !== undefined ) ? distance : 0; this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; this.exponent = ( exponent !== undefined ) ? exponent : 10; - this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 0;; // for physically correct lights, should be 2. + this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 1; // for physically correct lights, should be 2. this.castShadow = false; this.onlyShadow = false; From 632002cb4053768ac40477a7c6557012ba237d33 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 30 Dec 2014 22:43:40 -0500 Subject: [PATCH 025/333] add THREE.log per https://github.com/mrdoob/three.js/pull/5835#issuecomment-68418304 --- examples/js/renderers/CSS2DRenderer.js | 2 +- examples/js/renderers/CSS3DRenderer.js | 2 +- examples/js/renderers/CSS3DStereoRenderer.js | 2 +- examples/js/renderers/CanvasRenderer.js | 2 +- examples/js/renderers/RaytracingRenderer.js | 2 +- examples/js/renderers/SVGRenderer.js | 2 +- examples/js/renderers/SoftwareRenderer.js | 2 +- src/Three.js | 4 +++- src/renderers/WebGLRenderer.js | 2 +- 9 files changed, 11 insertions(+), 9 deletions(-) diff --git a/examples/js/renderers/CSS2DRenderer.js b/examples/js/renderers/CSS2DRenderer.js index 0797fbc2dec062..43757314f469f6 100644 --- a/examples/js/renderers/CSS2DRenderer.js +++ b/examples/js/renderers/CSS2DRenderer.js @@ -28,7 +28,7 @@ THREE.CSS2DObject.prototype.constructor = THREE.CSS2DObject; THREE.CSS2DRenderer = function () { - console.log( 'THREE.CSS2DRenderer', THREE.REVISION ); + THREE.log( 'THREE.CSS2DRenderer', THREE.REVISION ); var _width, _height; var _widthHalf, _heightHalf; diff --git a/examples/js/renderers/CSS3DRenderer.js b/examples/js/renderers/CSS3DRenderer.js index f198d6b5cec65e..c925dddbd09e5c 100644 --- a/examples/js/renderers/CSS3DRenderer.js +++ b/examples/js/renderers/CSS3DRenderer.js @@ -38,7 +38,7 @@ THREE.CSS3DSprite.prototype.constructor = THREE.CSS3DSprite; THREE.CSS3DRenderer = function () { - console.log( 'THREE.CSS3DRenderer', THREE.REVISION ); + THREE.log( 'THREE.CSS3DRenderer', THREE.REVISION ); var _width, _height; var _widthHalf, _heightHalf; diff --git a/examples/js/renderers/CSS3DStereoRenderer.js b/examples/js/renderers/CSS3DStereoRenderer.js index 944303893ed573..722c84829137ce 100644 --- a/examples/js/renderers/CSS3DStereoRenderer.js +++ b/examples/js/renderers/CSS3DStereoRenderer.js @@ -46,7 +46,7 @@ THREE.CSS3DSprite.prototype.constructor = THREE.CSS3DSprite; THREE.CSS3DStereoRenderer = function () { - console.log( 'THREE.CSS3DRenderer', THREE.REVISION ); + THREE.log( 'THREE.CSS3DRenderer', THREE.REVISION ); var _width, _height; var _widthHalf, _heightHalf; diff --git a/examples/js/renderers/CanvasRenderer.js b/examples/js/renderers/CanvasRenderer.js index d8a72857082566..9f63e6a4f8cec0 100644 --- a/examples/js/renderers/CanvasRenderer.js +++ b/examples/js/renderers/CanvasRenderer.js @@ -35,7 +35,7 @@ THREE.SpriteCanvasMaterial.prototype.clone = function () { THREE.CanvasRenderer = function ( parameters ) { - console.log( 'THREE.CanvasRenderer', THREE.REVISION ); + THREE.log( 'THREE.CanvasRenderer', THREE.REVISION ); var smoothstep = THREE.Math.smoothstep; diff --git a/examples/js/renderers/RaytracingRenderer.js b/examples/js/renderers/RaytracingRenderer.js index ca612a633d473f..ff566dc2b98f04 100644 --- a/examples/js/renderers/RaytracingRenderer.js +++ b/examples/js/renderers/RaytracingRenderer.js @@ -5,7 +5,7 @@ THREE.RaytracingRenderer = function ( parameters ) { - console.log( 'THREE.RaytracingRenderer', THREE.REVISION ); + THREE.log( 'THREE.RaytracingRenderer', THREE.REVISION ); parameters = parameters || {}; diff --git a/examples/js/renderers/SVGRenderer.js b/examples/js/renderers/SVGRenderer.js index f4a7989dd89b99..16489a685fefe6 100644 --- a/examples/js/renderers/SVGRenderer.js +++ b/examples/js/renderers/SVGRenderer.js @@ -15,7 +15,7 @@ THREE.SVGObject.prototype.constructor = THREE.SVGObject; THREE.SVGRenderer = function () { - console.log( 'THREE.SVGRenderer', THREE.REVISION ); + THREE.log( 'THREE.SVGRenderer', THREE.REVISION ); var _this = this, _renderData, _elements, _lights, diff --git a/examples/js/renderers/SoftwareRenderer.js b/examples/js/renderers/SoftwareRenderer.js index 782741fb0a1d67..cd1426d63085de 100644 --- a/examples/js/renderers/SoftwareRenderer.js +++ b/examples/js/renderers/SoftwareRenderer.js @@ -7,7 +7,7 @@ THREE.SoftwareRenderer = function ( parameters ) { - console.log( 'THREE.SoftwareRenderer', THREE.REVISION ); + THREE.log( 'THREE.SoftwareRenderer', THREE.REVISION ); parameters = parameters || {}; diff --git a/src/Three.js b/src/Three.js index fd1e26498457bc..cafe15705fc774 100644 --- a/src/Three.js +++ b/src/Three.js @@ -33,12 +33,14 @@ THREE.ConsoleWarningHandler = function() { console.warn( arguments ); }; -THREE.NullHandler = function() { +THREE.ConsoleLogHandler = function() { + console.log( arguments ); }; // set the default error handlers THREE.error = THREE.ConsoleErrorHandler; THREE.warning = THREE.ConsoleWarningHandler; +THREE.log = THREE.ConsoleLogHandler; // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d75afbe1c0721d..c1bb4d6dee2d5c 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -7,7 +7,7 @@ THREE.WebGLRenderer = function ( parameters ) { - console.log( 'THREE.WebGLRenderer', THREE.REVISION ); + THREE.log( 'THREE.WebGLRenderer', THREE.REVISION ); parameters = parameters || {}; From c4f0046f9b20001faa156034b74a8cba21ff292d Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 30 Dec 2014 22:58:06 -0500 Subject: [PATCH 026/333] simplify THREE.error/warning/log redirects to console.* --- src/Three.js | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/Three.js b/src/Three.js index cafe15705fc774..026b341651a258 100644 --- a/src/Three.js +++ b/src/Three.js @@ -25,22 +25,10 @@ if ( Math.sign === undefined ) { } -THREE.ConsoleErrorHandler = function() { - console.error( arguments ); -}; - -THREE.ConsoleWarningHandler = function() { - console.warn( arguments ); -}; - -THREE.ConsoleLogHandler = function() { - console.log( arguments ); -}; - -// set the default error handlers -THREE.error = THREE.ConsoleErrorHandler; -THREE.warning = THREE.ConsoleWarningHandler; -THREE.log = THREE.ConsoleLogHandler; +// set the default log handlers +THREE.error = function() { console.error.apply( console, arguments ); } +THREE.warning = function() { console.warn.apply( console, arguments ); } +THREE.log = function() { console.log.apply( console, arguments ); } // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button From fab13aa2fbb976f7695402f150c9749bef4f0f5a Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 31 Dec 2014 11:11:19 -0500 Subject: [PATCH 027/333] Revert "add THREE.log per https://github.com/mrdoob/three.js/pull/5835#issuecomment-68418304" This reverts commit 632002cb4053768ac40477a7c6557012ba237d33. Conflicts: src/Three.js --- examples/js/renderers/CSS2DRenderer.js | 2 +- examples/js/renderers/CSS3DRenderer.js | 2 +- examples/js/renderers/CSS3DStereoRenderer.js | 2 +- examples/js/renderers/CanvasRenderer.js | 2 +- examples/js/renderers/RaytracingRenderer.js | 2 +- examples/js/renderers/SVGRenderer.js | 2 +- examples/js/renderers/SoftwareRenderer.js | 2 +- src/renderers/WebGLRenderer.js | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/js/renderers/CSS2DRenderer.js b/examples/js/renderers/CSS2DRenderer.js index 43757314f469f6..0797fbc2dec062 100644 --- a/examples/js/renderers/CSS2DRenderer.js +++ b/examples/js/renderers/CSS2DRenderer.js @@ -28,7 +28,7 @@ THREE.CSS2DObject.prototype.constructor = THREE.CSS2DObject; THREE.CSS2DRenderer = function () { - THREE.log( 'THREE.CSS2DRenderer', THREE.REVISION ); + console.log( 'THREE.CSS2DRenderer', THREE.REVISION ); var _width, _height; var _widthHalf, _heightHalf; diff --git a/examples/js/renderers/CSS3DRenderer.js b/examples/js/renderers/CSS3DRenderer.js index c925dddbd09e5c..f198d6b5cec65e 100644 --- a/examples/js/renderers/CSS3DRenderer.js +++ b/examples/js/renderers/CSS3DRenderer.js @@ -38,7 +38,7 @@ THREE.CSS3DSprite.prototype.constructor = THREE.CSS3DSprite; THREE.CSS3DRenderer = function () { - THREE.log( 'THREE.CSS3DRenderer', THREE.REVISION ); + console.log( 'THREE.CSS3DRenderer', THREE.REVISION ); var _width, _height; var _widthHalf, _heightHalf; diff --git a/examples/js/renderers/CSS3DStereoRenderer.js b/examples/js/renderers/CSS3DStereoRenderer.js index 722c84829137ce..944303893ed573 100644 --- a/examples/js/renderers/CSS3DStereoRenderer.js +++ b/examples/js/renderers/CSS3DStereoRenderer.js @@ -46,7 +46,7 @@ THREE.CSS3DSprite.prototype.constructor = THREE.CSS3DSprite; THREE.CSS3DStereoRenderer = function () { - THREE.log( 'THREE.CSS3DRenderer', THREE.REVISION ); + console.log( 'THREE.CSS3DRenderer', THREE.REVISION ); var _width, _height; var _widthHalf, _heightHalf; diff --git a/examples/js/renderers/CanvasRenderer.js b/examples/js/renderers/CanvasRenderer.js index 9f63e6a4f8cec0..d8a72857082566 100644 --- a/examples/js/renderers/CanvasRenderer.js +++ b/examples/js/renderers/CanvasRenderer.js @@ -35,7 +35,7 @@ THREE.SpriteCanvasMaterial.prototype.clone = function () { THREE.CanvasRenderer = function ( parameters ) { - THREE.log( 'THREE.CanvasRenderer', THREE.REVISION ); + console.log( 'THREE.CanvasRenderer', THREE.REVISION ); var smoothstep = THREE.Math.smoothstep; diff --git a/examples/js/renderers/RaytracingRenderer.js b/examples/js/renderers/RaytracingRenderer.js index ff566dc2b98f04..ca612a633d473f 100644 --- a/examples/js/renderers/RaytracingRenderer.js +++ b/examples/js/renderers/RaytracingRenderer.js @@ -5,7 +5,7 @@ THREE.RaytracingRenderer = function ( parameters ) { - THREE.log( 'THREE.RaytracingRenderer', THREE.REVISION ); + console.log( 'THREE.RaytracingRenderer', THREE.REVISION ); parameters = parameters || {}; diff --git a/examples/js/renderers/SVGRenderer.js b/examples/js/renderers/SVGRenderer.js index 16489a685fefe6..f4a7989dd89b99 100644 --- a/examples/js/renderers/SVGRenderer.js +++ b/examples/js/renderers/SVGRenderer.js @@ -15,7 +15,7 @@ THREE.SVGObject.prototype.constructor = THREE.SVGObject; THREE.SVGRenderer = function () { - THREE.log( 'THREE.SVGRenderer', THREE.REVISION ); + console.log( 'THREE.SVGRenderer', THREE.REVISION ); var _this = this, _renderData, _elements, _lights, diff --git a/examples/js/renderers/SoftwareRenderer.js b/examples/js/renderers/SoftwareRenderer.js index cd1426d63085de..782741fb0a1d67 100644 --- a/examples/js/renderers/SoftwareRenderer.js +++ b/examples/js/renderers/SoftwareRenderer.js @@ -7,7 +7,7 @@ THREE.SoftwareRenderer = function ( parameters ) { - THREE.log( 'THREE.SoftwareRenderer', THREE.REVISION ); + console.log( 'THREE.SoftwareRenderer', THREE.REVISION ); parameters = parameters || {}; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index c1bb4d6dee2d5c..d75afbe1c0721d 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -7,7 +7,7 @@ THREE.WebGLRenderer = function ( parameters ) { - THREE.log( 'THREE.WebGLRenderer', THREE.REVISION ); + console.log( 'THREE.WebGLRenderer', THREE.REVISION ); parameters = parameters || {}; From c9f111c3109b98b2449cf8849787096594e3282e Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 31 Dec 2014 11:37:57 -0500 Subject: [PATCH 028/333] adopt THREE.warn rather than THREE.warning to be more inline with console.warn standard. --- src/Three.js | 6 ++--- src/core/BufferAttribute.js | 18 ++++++------- src/core/BufferGeometry.js | 4 +-- src/core/Face4.js | 2 +- src/core/Object3D.js | 12 ++++----- src/core/Raycaster.js | 2 +- src/extras/FontUtils.js | 2 +- src/extras/GeometryUtils.js | 4 +-- src/extras/animation/AnimationHandler.js | 6 ++--- src/extras/core/Curve.js | 2 +- src/extras/core/Shape.js | 2 +- src/extras/geometries/CubeGeometry.js | 2 +- src/extras/objects/MorphBlendMesh.js | 2 +- src/loaders/JSONLoader.js | 2 +- src/loaders/ObjectLoader.js | 10 ++++---- src/materials/Material.js | 2 +- src/materials/PointCloudMaterial.js | 4 +-- src/math/Euler.js | 2 +- src/math/Matrix3.js | 6 ++--- src/math/Matrix4.js | 20 +++++++-------- src/math/Quaternion.js | 4 +-- src/math/Vector2.js | 4 +-- src/math/Vector3.js | 14 +++++------ src/math/Vector4.js | 4 +-- src/objects/Mesh.js | 2 +- src/objects/MorphAnimMesh.js | 2 +- src/objects/PointCloud.js | 2 +- src/objects/Skeleton.js | 2 +- src/objects/SkinnedMesh.js | 2 +- src/renderers/WebGLRenderer.js | 32 ++++++++++++------------ src/renderers/webgl/WebGLExtensions.js | 2 +- src/renderers/webgl/WebGLProgram.js | 6 ++--- src/renderers/webgl/WebGLShader.js | 2 +- 33 files changed, 94 insertions(+), 94 deletions(-) diff --git a/src/Three.js b/src/Three.js index 026b341651a258..2fdc445bde798c 100644 --- a/src/Three.js +++ b/src/Three.js @@ -27,7 +27,7 @@ if ( Math.sign === undefined ) { // set the default log handlers THREE.error = function() { console.error.apply( console, arguments ); } -THREE.warning = function() { console.warn.apply( console, arguments ); } +THREE.warn = function() { console.warn.apply( console, arguments ); } THREE.log = function() { console.log.apply( console, arguments ); } @@ -198,14 +198,14 @@ THREE.Projector = function () { this.projectVector = function ( vector, camera ) { - THREE.warning( 'THREE.Projector: .projectVector() is now vector.project().' ); + THREE.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); vector.project( camera ); }; this.unprojectVector = function ( vector, camera ) { - THREE.warning( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); + THREE.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); vector.unproject( camera ); }; diff --git a/src/core/BufferAttribute.js b/src/core/BufferAttribute.js index 8d891bce2acfa7..4592cf29b1a0e1 100644 --- a/src/core/BufferAttribute.js +++ b/src/core/BufferAttribute.js @@ -114,21 +114,21 @@ THREE.BufferAttribute.prototype = { THREE.Int8Attribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint8Attribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint8ClampedAttribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); @@ -136,42 +136,42 @@ THREE.Uint8ClampedAttribute = function ( data, itemSize ) { THREE.Int16Attribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint16Attribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Int32Attribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint32Attribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Float32Attribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Float64Attribute = function ( data, itemSize ) { - THREE.warning( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index 61648f6f4e2a6e..3fe6a10ea000d6 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -31,7 +31,7 @@ THREE.BufferGeometry.prototype = { if ( attribute instanceof THREE.BufferAttribute === false ) { - THREE.warning( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); + THREE.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); this.attributes[ name ] = { array: arguments[ 1 ], itemSize: arguments[ 2 ] }; @@ -476,7 +476,7 @@ THREE.BufferGeometry.prototype = { this.attributes.normal === undefined || this.attributes.uv === undefined ) { - THREE.warning( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); + THREE.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); return; } diff --git a/src/core/Face4.js b/src/core/Face4.js index 89545ffafabbed..31ab7f85f2796e 100644 --- a/src/core/Face4.js +++ b/src/core/Face4.js @@ -4,7 +4,7 @@ THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) { - THREE.warning( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ) + THREE.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ) return new THREE.Face3( a, b, c, normal, color, materialIndex ); }; diff --git a/src/core/Object3D.js b/src/core/Object3D.js index f2e24718abd475..efb471f6cbe24e 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -83,7 +83,7 @@ THREE.Object3D.prototype = { get eulerOrder () { - THREE.warning( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); + THREE.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); return this.rotation.order; @@ -91,7 +91,7 @@ THREE.Object3D.prototype = { set eulerOrder ( value ) { - THREE.warning( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); + THREE.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); this.rotation.order = value; @@ -99,13 +99,13 @@ THREE.Object3D.prototype = { get useQuaternion () { - THREE.warning( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); + THREE.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); }, set useQuaternion ( value ) { - THREE.warning( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); + THREE.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); }, @@ -223,7 +223,7 @@ THREE.Object3D.prototype = { translate: function ( distance, axis ) { - THREE.warning( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); + THREE.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); return this.translateOnAxis( axis, distance ); }, @@ -370,7 +370,7 @@ THREE.Object3D.prototype = { getChildByName: function ( name, recursive ) { - THREE.warning( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); + THREE.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); return this.getObjectByName( name, recursive ); }, diff --git a/src/core/Raycaster.js b/src/core/Raycaster.js index 0008a69bbe7bb7..104f487b2b09d2 100644 --- a/src/core/Raycaster.js +++ b/src/core/Raycaster.js @@ -105,7 +105,7 @@ if ( objects instanceof Array === false ) { - THREE.warning( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); + THREE.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); return intersects; } diff --git a/src/extras/FontUtils.js b/src/extras/FontUtils.js index 2d4d54c9fb34dc..2dbf79d5684f63 100644 --- a/src/extras/FontUtils.js +++ b/src/extras/FontUtils.js @@ -333,7 +333,7 @@ THREE.FontUtils.generateShapes = function ( text, parameters ) { //throw ( "Warning, unable to triangulate polygon!" ); //return null; // Sometimes warning is fine, especially polygons are triangulated in reverse. - THREE.warning( 'THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()' ); + THREE.warn( 'THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()' ); if ( indices ) return vertIndices; return result; diff --git a/src/extras/GeometryUtils.js b/src/extras/GeometryUtils.js index 419d38cc7f96a6..4284df3b976e45 100644 --- a/src/extras/GeometryUtils.js +++ b/src/extras/GeometryUtils.js @@ -6,7 +6,7 @@ THREE.GeometryUtils = { merge: function ( geometry1, geometry2, materialIndexOffset ) { - THREE.warning( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); + THREE.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); var matrix; @@ -25,7 +25,7 @@ THREE.GeometryUtils = { center: function ( geometry ) { - THREE.warning( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); + THREE.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); return geometry.center(); } diff --git a/src/extras/animation/AnimationHandler.js b/src/extras/animation/AnimationHandler.js index a7606b86ca7d16..e50ca2ed045596 100644 --- a/src/extras/animation/AnimationHandler.js +++ b/src/extras/animation/AnimationHandler.js @@ -10,9 +10,9 @@ THREE.AnimationHandler = { // - add: function () { THREE.warning( 'THREE.AnimationHandler.add() has been deprecated.' ); }, - get: function () { THREE.warning( 'THREE.AnimationHandler.get() has been deprecated.' ); }, - remove: function () { THREE.warning( 'THREE.AnimationHandler.remove() has been deprecated.' ); }, + add: function () { THREE.warn( 'THREE.AnimationHandler.add() has been deprecated.' ); }, + get: function () { THREE.warn( 'THREE.AnimationHandler.get() has been deprecated.' ); }, + remove: function () { THREE.warn( 'THREE.AnimationHandler.remove() has been deprecated.' ); }, // diff --git a/src/extras/core/Curve.js b/src/extras/core/Curve.js index 0289776eec906a..722e64bb2073cd 100644 --- a/src/extras/core/Curve.js +++ b/src/extras/core/Curve.js @@ -43,7 +43,7 @@ THREE.Curve = function () { THREE.Curve.prototype.getPoint = function ( t ) { - THREE.warning( "THREE.Curve: Warning, getPoint() not implemented!" ); + THREE.warn( "THREE.Curve: Warning, getPoint() not implemented!" ); return null; }; diff --git a/src/extras/core/Shape.js b/src/extras/core/Shape.js index c28f4d61e28777..568e9dec330f9a 100644 --- a/src/extras/core/Shape.js +++ b/src/extras/core/Shape.js @@ -462,7 +462,7 @@ THREE.Shape.Utils = { if ( allPointsMap[ key ] !== undefined ) { - THREE.warning( "THREE.Shape: Duplicate point", key ); + THREE.warn( "THREE.Shape: Duplicate point", key ); } diff --git a/src/extras/geometries/CubeGeometry.js b/src/extras/geometries/CubeGeometry.js index a52ff40b30d534..fdd0b1e5202508 100644 --- a/src/extras/geometries/CubeGeometry.js +++ b/src/extras/geometries/CubeGeometry.js @@ -5,7 +5,7 @@ THREE.CubeGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) { - THREE.warning( 'THREE.CubeGeometry has been renamed to THREE.BoxGeometry.' ); + THREE.warn( 'THREE.CubeGeometry has been renamed to THREE.BoxGeometry.' ); return new THREE.BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ); }; diff --git a/src/extras/objects/MorphBlendMesh.js b/src/extras/objects/MorphBlendMesh.js index a42d390d949b3d..9068259ae3817c 100644 --- a/src/extras/objects/MorphBlendMesh.js +++ b/src/extras/objects/MorphBlendMesh.js @@ -221,7 +221,7 @@ THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) { } else { - THREE.warning( "THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()" ); + THREE.warn( "THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()" ); } diff --git a/src/loaders/JSONLoader.js b/src/loaders/JSONLoader.js index 2908a21e6f8628..1e50214ea34d2f 100644 --- a/src/loaders/JSONLoader.js +++ b/src/loaders/JSONLoader.js @@ -454,7 +454,7 @@ THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - THREE.warning( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + + THREE.warn( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); } diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 264ceb8f5599c7..4d1d66177736da 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -274,13 +274,13 @@ THREE.ObjectLoader.prototype = { if ( geometry === undefined ) { - THREE.warning( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); + THREE.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); } if ( material === undefined ) { - THREE.warning( 'THREE.ObjectLoader: Undefined material', data.material ); + THREE.warn( 'THREE.ObjectLoader: Undefined material', data.material ); } @@ -295,13 +295,13 @@ THREE.ObjectLoader.prototype = { if ( geometry === undefined ) { - THREE.warning( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); + THREE.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); } if ( material === undefined ) { - THREE.warning( 'THREE.ObjectLoader: Undefined material', data.material ); + THREE.warn( 'THREE.ObjectLoader: Undefined material', data.material ); } @@ -315,7 +315,7 @@ THREE.ObjectLoader.prototype = { if ( material === undefined ) { - THREE.warning( 'THREE.ObjectLoader: Undefined material', data.material ); + THREE.warn( 'THREE.ObjectLoader: Undefined material', data.material ); } diff --git a/src/materials/Material.js b/src/materials/Material.js index 2b686a3c3f3896..d9b32943136bc7 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -54,7 +54,7 @@ THREE.Material.prototype = { if ( newValue === undefined ) { - THREE.warning( "THREE.Material: '" + key + "' parameter is undefined." ); + THREE.warn( "THREE.Material: '" + key + "' parameter is undefined." ); continue; } diff --git a/src/materials/PointCloudMaterial.js b/src/materials/PointCloudMaterial.js index 71cd07f87c4732..69f53df8e34bc4 100644 --- a/src/materials/PointCloudMaterial.js +++ b/src/materials/PointCloudMaterial.js @@ -69,14 +69,14 @@ THREE.PointCloudMaterial.prototype.clone = function () { THREE.ParticleBasicMaterial = function ( parameters ) { - THREE.warning( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointCloudMaterial.' ); + THREE.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointCloudMaterial.' ); return new THREE.PointCloudMaterial( parameters ); }; THREE.ParticleSystemMaterial = function ( parameters ) { - THREE.warning( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' ); + THREE.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' ); return new THREE.PointCloudMaterial( parameters ); }; diff --git a/src/math/Euler.js b/src/math/Euler.js index 11e717b70d894b..ee187993581170 100644 --- a/src/math/Euler.js +++ b/src/math/Euler.js @@ -212,7 +212,7 @@ THREE.Euler.prototype = { } else { - THREE.warning( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ) + THREE.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ) } diff --git a/src/math/Matrix3.js b/src/math/Matrix3.js index ebc400251b5482..e83957b0e8ae7e 100644 --- a/src/math/Matrix3.js +++ b/src/math/Matrix3.js @@ -70,14 +70,14 @@ THREE.Matrix3.prototype = { multiplyVector3: function ( vector ) { - THREE.warning( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); return vector.applyMatrix3( this ); }, multiplyVector3Array: function ( a ) { - THREE.warning( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); + THREE.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); return this.applyToVector3Array( a ); }, @@ -167,7 +167,7 @@ THREE.Matrix3.prototype = { } else { - THREE.warning( msg ); + THREE.warn( msg ); } diff --git a/src/math/Matrix4.js b/src/math/Matrix4.js index 06cb746f428174..34b088dc1bc5f2 100644 --- a/src/math/Matrix4.js +++ b/src/math/Matrix4.js @@ -72,7 +72,7 @@ THREE.Matrix4.prototype = { extractPosition: function ( m ) { - THREE.warning( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); + THREE.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); return this.copyPosition( m ); }, @@ -251,7 +251,7 @@ THREE.Matrix4.prototype = { setRotationFromQuaternion: function ( q ) { - THREE.warning( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); + THREE.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); return this.makeRotationFromQuaternion( q ); @@ -338,7 +338,7 @@ THREE.Matrix4.prototype = { if ( n !== undefined ) { - THREE.warning( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); + THREE.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); return this.multiplyMatrices( m, n ); } @@ -417,21 +417,21 @@ THREE.Matrix4.prototype = { multiplyVector3: function ( vector ) { - THREE.warning( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); return vector.applyProjection( this ); }, multiplyVector4: function ( vector ) { - THREE.warning( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); return vector.applyMatrix4( this ); }, multiplyVector3Array: function ( a ) { - THREE.warning( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); + THREE.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); return this.applyToVector3Array( a ); }, @@ -467,7 +467,7 @@ THREE.Matrix4.prototype = { rotateAxis: function ( v ) { - THREE.warning( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); v.transformDirection( this ); @@ -475,7 +475,7 @@ THREE.Matrix4.prototype = { crossVector: function ( vector ) { - THREE.warning( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); return vector.applyMatrix4( this ); }, @@ -581,7 +581,7 @@ THREE.Matrix4.prototype = { return function () { - THREE.warning( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); var te = this.elements; return v1.set( te[ 12 ], te[ 13 ], te[ 14 ] ); @@ -642,7 +642,7 @@ THREE.Matrix4.prototype = { } else { - THREE.warning( msg ); + THREE.warn( msg ); } diff --git a/src/math/Quaternion.js b/src/math/Quaternion.js index 8b6d486aa04ff2..861e99e0ddca70 100644 --- a/src/math/Quaternion.js +++ b/src/math/Quaternion.js @@ -363,7 +363,7 @@ THREE.Quaternion.prototype = { if ( p !== undefined ) { - THREE.warning( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); + THREE.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); return this.multiplyQuaternions( q, p ); } @@ -392,7 +392,7 @@ THREE.Quaternion.prototype = { multiplyVector3: function ( vector ) { - THREE.warning( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); + THREE.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); return vector.applyQuaternion( this ); }, diff --git a/src/math/Vector2.js b/src/math/Vector2.js index 4a1e91dea7b3c7..c22ff8facdd00c 100644 --- a/src/math/Vector2.js +++ b/src/math/Vector2.js @@ -78,7 +78,7 @@ THREE.Vector2.prototype = { if ( w !== undefined ) { - THREE.warning( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -112,7 +112,7 @@ THREE.Vector2.prototype = { if ( w !== undefined ) { - THREE.warning( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } diff --git a/src/math/Vector3.js b/src/math/Vector3.js index 5bb40a73dbf657..60633f97ec3a85 100644 --- a/src/math/Vector3.js +++ b/src/math/Vector3.js @@ -93,7 +93,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - THREE.warning( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -130,7 +130,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - THREE.warning( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } @@ -157,7 +157,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - THREE.warning( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); return this.multiplyVectors( v, w ); } @@ -601,7 +601,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - THREE.warning( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); return this.crossVectors( v, w ); } @@ -720,7 +720,7 @@ THREE.Vector3.prototype = { getPositionFromMatrix: function ( m ) { - THREE.warning( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); + THREE.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); return this.setFromMatrixPosition( m ); @@ -728,14 +728,14 @@ THREE.Vector3.prototype = { getScaleFromMatrix: function ( m ) { - THREE.warning( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); + THREE.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); return this.setFromMatrixScale( m ); }, getColumnFromMatrix: function ( index, matrix ) { - THREE.warning( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); + THREE.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); return this.setFromMatrixColumn( index, matrix ); diff --git a/src/math/Vector4.js b/src/math/Vector4.js index 6fce492b746a09..ee4106e0ce2024 100644 --- a/src/math/Vector4.js +++ b/src/math/Vector4.js @@ -105,7 +105,7 @@ THREE.Vector4.prototype = { if ( w !== undefined ) { - THREE.warning( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -145,7 +145,7 @@ THREE.Vector4.prototype = { if ( w !== undefined ) { - THREE.warning( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } diff --git a/src/objects/Mesh.js b/src/objects/Mesh.js index 775a0352826ca5..573b993f7610bc 100644 --- a/src/objects/Mesh.js +++ b/src/objects/Mesh.js @@ -49,7 +49,7 @@ THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) { } - THREE.warning( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); + THREE.warn( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); return 0; diff --git a/src/objects/MorphAnimMesh.js b/src/objects/MorphAnimMesh.js index 851ae51a905be8..08d26bc3007814 100644 --- a/src/objects/MorphAnimMesh.js +++ b/src/objects/MorphAnimMesh.js @@ -109,7 +109,7 @@ THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) { } else { - THREE.warning( 'THREE.MorphAnimMesh: animation[' + label + '] undefined in .playAnimation()' ); + THREE.warn( 'THREE.MorphAnimMesh: animation[' + label + '] undefined in .playAnimation()' ); } diff --git a/src/objects/PointCloud.js b/src/objects/PointCloud.js index 2ba51f4abd210f..a05a186f3ae0dd 100644 --- a/src/objects/PointCloud.js +++ b/src/objects/PointCloud.js @@ -157,7 +157,7 @@ THREE.PointCloud.prototype.clone = function ( object ) { THREE.ParticleSystem = function ( geometry, material ) { - THREE.warning( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' ); + THREE.warn( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' ); return new THREE.PointCloud( geometry, material ); }; diff --git a/src/objects/Skeleton.js b/src/objects/Skeleton.js index 41b6f0cdb4ad84..f3173c751cf253 100644 --- a/src/objects/Skeleton.js +++ b/src/objects/Skeleton.js @@ -69,7 +69,7 @@ THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) { } else { - THREE.warning( 'THREE.Skeleton bonInverses is the wrong length.' ); + THREE.warn( 'THREE.Skeleton bonInverses is the wrong length.' ); this.boneInverses = []; diff --git a/src/objects/SkinnedMesh.js b/src/objects/SkinnedMesh.js index c122109477ad6a..8f2ac780e8b737 100644 --- a/src/objects/SkinnedMesh.js +++ b/src/objects/SkinnedMesh.js @@ -148,7 +148,7 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) { } else { - THREE.warning( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode ); + THREE.warn( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode ); } diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d75afbe1c0721d..d1d3f1e731c842 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -362,12 +362,12 @@ THREE.WebGLRenderer = function ( parameters ) { if ( mediumpAvailable ) { _precision = 'mediump'; - THREE.warning( 'THREE.WebGLRenderer: highp not supported, using mediump.' ); + THREE.warn( 'THREE.WebGLRenderer: highp not supported, using mediump.' ); } else { _precision = 'lowp'; - THREE.warning( 'THREE.WebGLRenderer: highp and mediump not supported, using lowp.' ); + THREE.warn( 'THREE.WebGLRenderer: highp and mediump not supported, using lowp.' ); } @@ -376,7 +376,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _precision === 'mediump' && ! mediumpAvailable ) { _precision = 'lowp'; - THREE.warning( 'THREE.WebGLRenderer: mediump not supported, using lowp.' ); + THREE.warn( 'THREE.WebGLRenderer: mediump not supported, using lowp.' ); } @@ -535,7 +535,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.setClearColorHex = function ( hex, alpha ) { - THREE.warning( 'THREE.WebGLRenderer: .setClearColorHex() is being removed. Use .setClearColor() instead.' ); + THREE.warn( 'THREE.WebGLRenderer: .setClearColorHex() is being removed. Use .setClearColor() instead.' ); this.setClearColor( hex, alpha ); }; @@ -4802,7 +4802,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( textureUnit >= _maxTextures ) { - THREE.warning( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures ); + THREE.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures ); } @@ -5140,7 +5140,7 @@ THREE.WebGLRenderer = function ( parameters ) { default: - THREE.warning( 'THREE.WebGLRenderer: Unknown uniform type: ' + type ); + THREE.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type ); } @@ -5646,7 +5646,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) { - THREE.warning( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' ); + THREE.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' ); } @@ -5655,7 +5655,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) { - THREE.warning( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( ' + texture.sourceFile + ' )' ); + THREE.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( ' + texture.sourceFile + ' )' ); } @@ -5744,7 +5744,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - THREE.warning( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" ); + THREE.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" ); } @@ -5821,7 +5821,7 @@ THREE.WebGLRenderer = function ( parameters ) { var context = canvas.getContext( '2d' ); context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); - THREE.warning( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image ); + THREE.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image ); return canvas; @@ -5908,7 +5908,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - THREE.warning( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()" ); + THREE.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()" ); } @@ -6287,7 +6287,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( maxBones < object.skeleton.bones.length ) { - THREE.warning( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' ); + THREE.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' ); } @@ -6347,24 +6347,24 @@ THREE.WebGLRenderer = function ( parameters ) { this.initMaterial = function () { - THREE.warning( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); + THREE.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); }; this.addPrePlugin = function () { - THREE.warning( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); + THREE.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); }; this.addPostPlugin = function () { - THREE.warning( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); + THREE.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); }; this.updateShadowMap = function () { - THREE.warning( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); + THREE.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); }; diff --git a/src/renderers/webgl/WebGLExtensions.js b/src/renderers/webgl/WebGLExtensions.js index 9306d45e22dcb1..79b801a8e8b03b 100644 --- a/src/renderers/webgl/WebGLExtensions.js +++ b/src/renderers/webgl/WebGLExtensions.js @@ -37,7 +37,7 @@ THREE.WebGLExtensions = function ( gl ) { if ( extension === null ) { - THREE.warning( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); + THREE.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); } diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 238616e169ebcb..2c99a97d99d2ef 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -344,9 +344,9 @@ THREE.WebGLProgram = ( function () { if ( programLogInfo !== '' ) { - THREE.warning( 'THREE.WebGLProgram: gl.getProgramInfoLog()' + programLogInfo ); - // THREE.warning( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); - // THREE.warning( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); + THREE.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()' + programLogInfo ); + // THREE.warn( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); + // THREE.warn( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); } diff --git a/src/renderers/webgl/WebGLShader.js b/src/renderers/webgl/WebGLShader.js index ee1bebd0a56179..a6c1abbf8789cd 100644 --- a/src/renderers/webgl/WebGLShader.js +++ b/src/renderers/webgl/WebGLShader.js @@ -29,7 +29,7 @@ THREE.WebGLShader = ( function () { if ( gl.getShaderInfoLog( shader ) !== '' ) { - THREE.warning( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ), addLineNumbers( string ) ); + THREE.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ), addLineNumbers( string ) ); } From 389880030071389c8c19e8dbb743d9507c8bb425 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 1 Jan 2015 04:26:17 -0500 Subject: [PATCH 029/333] remove gamma "correction" on non-texture shader parameters per discussion here: https://github.com/mrdoob/three.js/issues/5838 examples are not yet updated. --- src/renderers/WebGLRenderer.js | 121 ++++----------------------------- 1 file changed, 15 insertions(+), 106 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 541c1111ebcffd..61e9f154e78c61 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -4523,15 +4523,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.opacity.value = material.opacity; - if ( _this.gammaInput ) { - - uniforms.diffuse.value.copyGammaToLinear( material.color, _this.gammaFactor ); - - } else { - - uniforms.diffuse.value = material.color; - - } + uniforms.diffuse.value = material.color; uniforms.map.value = material.map; uniforms.lightMap.value = material.lightMap; @@ -4595,17 +4587,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.envMap.value = material.envMap; uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1; - if ( _this.gammaInput ) { - - //uniforms.reflectivity.value = material.reflectivity * material.reflectivity; - uniforms.reflectivity.value = material.reflectivity; - - } else { - - uniforms.reflectivity.value = material.reflectivity; - - } - + uniforms.reflectivity.value = material.reflectivity; uniforms.refractionRatio.value = material.refractionRatio; } @@ -4657,20 +4639,9 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.shininess.value = material.shininess; - if ( _this.gammaInput ) { - - uniforms.ambient.value.copyGammaToLinear( material.ambient, _this.gammaFactor ); - uniforms.emissive.value.copyGammaToLinear( material.emissive, _this.gammaFactor ); - uniforms.specular.value.copyGammaToLinear( material.specular, _this.gammaFactor ); - - - } else { - - uniforms.ambient.value = material.ambient; - uniforms.emissive.value = material.emissive; - uniforms.specular.value = material.specular; - - } + uniforms.ambient.value = material.ambient; + uniforms.emissive.value = material.emissive; + uniforms.specular.value = material.specular; if ( material.wrapAround ) { @@ -4682,17 +4653,8 @@ THREE.WebGLRenderer = function ( parameters ) { function refreshUniformsLambert ( uniforms, material ) { - if ( _this.gammaInput ) { - - uniforms.ambient.value.copyGammaToLinear( material.ambient, _this.gammaFactor ); - uniforms.emissive.value.copyGammaToLinear( material.emissive, _this.gammaFactor ); - - } else { - - uniforms.ambient.value = material.ambient; - uniforms.emissive.value = material.emissive; - - } + uniforms.ambient.value = material.ambient; + uniforms.emissive.value = material.emissive; if ( material.wrapAround ) { @@ -5157,16 +5119,6 @@ THREE.WebGLRenderer = function ( parameters ) { } - // - - function setColorGamma( array, offset, color, intensity, gammaFactor ) { - - array[ offset ] = Math.pow( color.r * intensity, gammaFactor ); - array[ offset + 1 ] = Math.pow( color.g * intensity, gammaFactor ); - array[ offset + 2 ] = Math.pow( color.b * intensity, gammaFactor ); - - } - function setColorLinear( array, offset, color, intensity ) { array[ offset ] = color.r * intensity; @@ -5233,19 +5185,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! light.visible ) continue; - if ( _this.gammaInput ) { - - r += Math.pow( color.r, _this.gammaFactor ); - g += Math.pow( color.g, _this.gammaFactor ); - b += Math.pow( color.b, _this.gammaFactor ); - - } else { - - r += color.r; - g += color.g; - b += color.b; - - } + r += color.r; + g += color.g; + b += color.b; } else if ( light instanceof THREE.DirectionalLight ) { @@ -5264,15 +5206,7 @@ THREE.WebGLRenderer = function ( parameters ) { dirPositions[ dirOffset + 1 ] = _direction.y; dirPositions[ dirOffset + 2 ] = _direction.z; - if ( _this.gammaInput ) { - - setColorGamma( dirColors, dirOffset, color, intensity, _this.gammaFactor ); - - } else { - - setColorLinear( dirColors, dirOffset, color, intensity ); - - } + setColorLinear( dirColors, dirOffset, color, intensity ); dirLength += 1; @@ -5284,15 +5218,7 @@ THREE.WebGLRenderer = function ( parameters ) { pointOffset = pointLength * 3; - if ( _this.gammaInput ) { - - setColorGamma( pointColors, pointOffset, color, intensity, _this.gammaFactor ); - - } else { - - setColorLinear( pointColors, pointOffset, color, intensity ); - - } + setColorLinear( pointColors, pointOffset, color, intensity ); _vector3.setFromMatrixPosition( light.matrixWorld ); @@ -5312,15 +5238,7 @@ THREE.WebGLRenderer = function ( parameters ) { spotOffset = spotLength * 3; - if ( _this.gammaInput ) { - - setColorGamma( spotColors, spotOffset, color, intensity, _this.gammaFactor ); - - } else { - - setColorLinear( spotColors, spotOffset, color, intensity ); - - } + setColorLinear( spotColors, spotOffset, color, intensity ); _direction.setFromMatrixPosition( light.matrixWorld ); @@ -5361,17 +5279,8 @@ THREE.WebGLRenderer = function ( parameters ) { skyColor = light.color; groundColor = light.groundColor; - if ( _this.gammaInput ) { - - setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensity, _this.gammaFactor ); - setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensity, _this.gammaFactor ); - - } else { - - setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity ); - setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity ); - - } + setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity ); + setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity ); hemiLength += 1; From d8c7ce23ea2138c096983b983791cfaed6ac76f3 Mon Sep 17 00:00:00 2001 From: tsone Date: Tue, 20 Jan 2015 11:55:05 +0800 Subject: [PATCH 030/333] WebGLRenderer: Fixed bug where blending was always used with overrideMaterial -- even when material.transparent = false. This did not match material behavior when overrideMaterial was not used. Also refactored unnecessary useBlending parameter, as blending is only used if material.transparent === true. --- src/renderers/WebGLRenderer.js | 59 +++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 747c0cf1a3eaba..b596fe1405c7e4 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3368,32 +3368,29 @@ THREE.WebGLRenderer = function ( parameters ) { if ( scene.overrideMaterial ) { - var material = scene.overrideMaterial; + var overrideMaterial = scene.overrideMaterial; - this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); - this.setDepthTest( material.depthTest ); - this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + // Reset blending in case material.transparent = false. setMaterial() doesn't set blending in such case. + this.setBlending( THREE.NoBlending ); + this.setMaterial( overrideMaterial ); - renderObjects( opaqueObjects, camera, lights, fog, true, material ); - renderObjects( transparentObjects, camera, lights, fog, true, material ); - renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, false, material ); + renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial ); + renderObjects( transparentObjects, camera, lights, fog, overrideMaterial ); + renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, overrideMaterial ); } else { - var material = null; - // opaque pass (front-to-back order) this.setBlending( THREE.NoBlending ); - renderObjects( opaqueObjects, camera, lights, fog, false, material ); - renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, false, material ); + renderObjects( opaqueObjects, camera, lights, fog ); + renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog ); // transparent pass (back-to-front order) - renderObjects( transparentObjects, camera, lights, fog, true, material ); - renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, true, material ); + renderObjects( transparentObjects, camera, lights, fog ); + renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog ); } @@ -3482,7 +3479,23 @@ THREE.WebGLRenderer = function ( parameters ) { } - function renderObjects( renderList, camera, lights, fog, useBlending, overrideMaterial ) { + function setMaterial( material ) { + + if ( material.transparent === true ) { + + _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); + + } + + _this.setDepthTest( material.depthTest ); + _this.setDepthWrite( material.depthWrite ); + setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + + } + + function renderObjects( renderList, camera, lights, fog, overrideMaterial ) { + + overrideMaterial = overrideMaterial || null; var material; @@ -3505,11 +3518,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! material ) continue; - if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); - - _this.setDepthTest( material.depthTest ); - _this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + _this.setMaterial( material ); } @@ -3529,7 +3538,9 @@ THREE.WebGLRenderer = function ( parameters ) { } - function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) { + function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, overrideMaterial ) { + + overrideMaterial = overrideMaterial || null; var material; @@ -3550,11 +3561,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! material ) continue; - if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); - - _this.setDepthTest( material.depthTest ); - _this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + _this.setMaterial( material ); } From 02ee46097a4e3f417d1def83eb910795405033f0 Mon Sep 17 00:00:00 2001 From: tsone Date: Tue, 20 Jan 2015 12:00:31 +0800 Subject: [PATCH 031/333] WebGLRenderer: Parameter overrideMaterial in renderObjects() and renderObjectsImmediate() should not be optional. --- src/renderers/WebGLRenderer.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index b596fe1405c7e4..050fcefcb8d018 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3384,13 +3384,13 @@ THREE.WebGLRenderer = function ( parameters ) { this.setBlending( THREE.NoBlending ); - renderObjects( opaqueObjects, camera, lights, fog ); - renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog ); + renderObjects( opaqueObjects, camera, lights, fog, null ); + renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null ); // transparent pass (back-to-front order) - renderObjects( transparentObjects, camera, lights, fog ); - renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog ); + renderObjects( transparentObjects, camera, lights, fog, null ); + renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, null ); } @@ -3495,8 +3495,6 @@ THREE.WebGLRenderer = function ( parameters ) { function renderObjects( renderList, camera, lights, fog, overrideMaterial ) { - overrideMaterial = overrideMaterial || null; - var material; for ( var i = 0, l = renderList.length; i < l; i ++ ) { @@ -3540,8 +3538,6 @@ THREE.WebGLRenderer = function ( parameters ) { function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, overrideMaterial ) { - overrideMaterial = overrideMaterial || null; - var material; for ( var i = 0, l = renderList.length; i < l; i ++ ) { From ae71fb114672e7b17df2cf476e7b22dd9f1a4fca Mon Sep 17 00:00:00 2001 From: tsone Date: Tue, 20 Jan 2015 12:07:12 +0800 Subject: [PATCH 032/333] WebGLRenderer: Made renderObjects(), renderObjectsImmediate() and setMaterial() private with '_' prefix. --- src/renderers/WebGLRenderer.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 050fcefcb8d018..8503e0f5e1b3c9 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3370,13 +3370,13 @@ THREE.WebGLRenderer = function ( parameters ) { var overrideMaterial = scene.overrideMaterial; - // Reset blending in case material.transparent = false. setMaterial() doesn't set blending in such case. + // Reset blending in case material.transparent = false. _setMaterial() doesn't set blending in such case. this.setBlending( THREE.NoBlending ); - this.setMaterial( overrideMaterial ); + this._setMaterial( overrideMaterial ); - renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial ); - renderObjects( transparentObjects, camera, lights, fog, overrideMaterial ); - renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, overrideMaterial ); + _renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial ); + _renderObjects( transparentObjects, camera, lights, fog, overrideMaterial ); + _renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, overrideMaterial ); } else { @@ -3384,13 +3384,13 @@ THREE.WebGLRenderer = function ( parameters ) { this.setBlending( THREE.NoBlending ); - renderObjects( opaqueObjects, camera, lights, fog, null ); - renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null ); + _renderObjects( opaqueObjects, camera, lights, fog, null ); + _renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null ); // transparent pass (back-to-front order) - renderObjects( transparentObjects, camera, lights, fog, null ); - renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, null ); + _renderObjects( transparentObjects, camera, lights, fog, null ); + _renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, null ); } @@ -3479,7 +3479,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - function setMaterial( material ) { + function _setMaterial( material ) { if ( material.transparent === true ) { @@ -3493,7 +3493,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - function renderObjects( renderList, camera, lights, fog, overrideMaterial ) { + function _renderObjects( renderList, camera, lights, fog, overrideMaterial ) { var material; @@ -3516,7 +3516,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! material ) continue; - _this.setMaterial( material ); + _this._setMaterial( material ); } @@ -3536,7 +3536,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, overrideMaterial ) { + function _renderObjectsImmediate ( renderList, materialType, camera, lights, fog, overrideMaterial ) { var material; @@ -3557,7 +3557,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! material ) continue; - _this.setMaterial( material ); + _this._setMaterial( material ); } From aba5ccd6d2e64861a471e44190eacd0f1c9258d4 Mon Sep 17 00:00:00 2001 From: tsone Date: Tue, 20 Jan 2015 12:48:48 +0800 Subject: [PATCH 033/333] WebGLRenderer: Fixed _setMaterial(). --- src/renderers/WebGLRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 8503e0f5e1b3c9..657eb2ad941adc 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3479,7 +3479,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - function _setMaterial( material ) { + this._setMaterial = function ( material ) { if ( material.transparent === true ) { From bca2d44b1380c6f13adcbac63fc9d48d500df1e9 Mon Sep 17 00:00:00 2001 From: tsone Date: Tue, 20 Jan 2015 20:08:12 +0800 Subject: [PATCH 034/333] WebGLRenderer: Small fixed to not use '_'. --- src/renderers/WebGLRenderer.js | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 657eb2ad941adc..3a287d84c19f81 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3370,13 +3370,13 @@ THREE.WebGLRenderer = function ( parameters ) { var overrideMaterial = scene.overrideMaterial; - // Reset blending in case material.transparent = false. _setMaterial() doesn't set blending in such case. + // Reset blending in case material.transparent = false. setMaterial() doesn't set blending in such case. this.setBlending( THREE.NoBlending ); - this._setMaterial( overrideMaterial ); + setMaterial( overrideMaterial ); - _renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial ); - _renderObjects( transparentObjects, camera, lights, fog, overrideMaterial ); - _renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, overrideMaterial ); + renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial ); + renderObjects( transparentObjects, camera, lights, fog, overrideMaterial ); + renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, overrideMaterial ); } else { @@ -3384,13 +3384,13 @@ THREE.WebGLRenderer = function ( parameters ) { this.setBlending( THREE.NoBlending ); - _renderObjects( opaqueObjects, camera, lights, fog, null ); - _renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null ); + renderObjects( opaqueObjects, camera, lights, fog, null ); + renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null ); // transparent pass (back-to-front order) - _renderObjects( transparentObjects, camera, lights, fog, null ); - _renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, null ); + renderObjects( transparentObjects, camera, lights, fog, null ); + renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, null ); } @@ -3479,21 +3479,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - this._setMaterial = function ( material ) { - - if ( material.transparent === true ) { - - _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); - - } - - _this.setDepthTest( material.depthTest ); - _this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); - - } - - function _renderObjects( renderList, camera, lights, fog, overrideMaterial ) { + function renderObjects( renderList, camera, lights, fog, overrideMaterial ) { var material; @@ -3516,7 +3502,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! material ) continue; - _this._setMaterial( material ); + setMaterial( material ); } @@ -3536,7 +3522,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - function _renderObjectsImmediate ( renderList, materialType, camera, lights, fog, overrideMaterial ) { + function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, overrideMaterial ) { var material; @@ -3557,7 +3543,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! material ) continue; - _this._setMaterial( material ); + setMaterial( material ); } @@ -4314,6 +4300,20 @@ THREE.WebGLRenderer = function ( parameters ) { } + function setMaterial( material ) { + + if ( material.transparent === true ) { + + _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); + + } + + _this.setDepthTest( material.depthTest ); + _this.setDepthWrite( material.depthWrite ); + setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + + } + function setProgram( camera, lights, fog, material, object ) { _usedTextureUnits = 0; From 8be68fbb2b6629c4372d41e7c5d261c1ba3cddd1 Mon Sep 17 00:00:00 2001 From: George Gensure Date: Tue, 20 Jan 2015 15:58:09 -0500 Subject: [PATCH 035/333] Correctly labelling GL State 'Constants' From previous label of 'Conflicts' --- docs/api/constants/GLState.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/constants/GLState.html b/docs/api/constants/GLState.html index f75843f14fbd58..06e08e5c8dabb3 100644 --- a/docs/api/constants/GLState.html +++ b/docs/api/constants/GLState.html @@ -7,7 +7,7 @@ -

GL State Conflicts

+

GL State Constants

Cull Face

From 7b0022e7d6468bdd32f6b715cad0e8a9c40df686 Mon Sep 17 00:00:00 2001 From: sebasbaumh Date: Thu, 22 Jan 2015 10:45:28 +0100 Subject: [PATCH 036/333] Fix for type in ColladaLoader: kinematicsModel is already defined in line 11, but in line 28 it should be called kinematicsModels (plural) like the visualScene/visualScenes the line before it. --- examples/js/loaders/ColladaLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index 580e8308ad4f6b..c3f7701153879c 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -25,7 +25,7 @@ THREE.ColladaLoader = function () { var animData; var kinematics; var visualScenes; - var kinematicsModel; + var kinematicsModels; var baseUrl; var morphs; var skins; From 6764247d108e068451c5bd98e6760d90ce89ac98 Mon Sep 17 00:00:00 2001 From: WestLangley Date: Thu, 22 Jan 2015 17:53:35 -0500 Subject: [PATCH 037/333] Premultiply the clearColor if renderer.premultipliedAlpha is true --- src/renderers/WebGLRenderer.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 94810d0c1898ed..4f15e2fa2af004 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -253,6 +253,20 @@ THREE.WebGLRenderer = function ( parameters ) { // + var setClearColor = function ( r, g, b, a ) { + + if ( _premultipliedAlpha === true ) { + + _gl.clearColor( r * a, g * a, b * a, a ); + + } else { + + _gl.clearColor( r, g, b, a ); + + } + + }; + var setDefaultGLState = function () { _gl.clearColor( 0, 0, 0, 1 ); @@ -272,7 +286,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight ); - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + setClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; @@ -536,9 +550,10 @@ THREE.WebGLRenderer = function ( parameters ) { this.setClearColor = function ( color, alpha ) { _clearColor.set( color ); + _clearAlpha = alpha !== undefined ? alpha : 1; - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + setClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; @@ -552,7 +567,7 @@ THREE.WebGLRenderer = function ( parameters ) { _clearAlpha = alpha; - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + setClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; From bdb37625f7f39b08bd27aa6b009a2e321258db1d Mon Sep 17 00:00:00 2001 From: ben_a_adams Date: Fri, 23 Jan 2015 01:57:08 +0000 Subject: [PATCH 038/333] Dynamic buffer attribute Changes suggested for #5964 resolves #5042 and supersedes #5952, #5953 and #5964 --- src/core/BufferAttribute.js | 7 +- src/core/DynamicBufferAttribute.js | 155 +++++++++++++++++++++++++++++ src/renderers/WebGLRenderer.js | 28 ++++-- 3 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 src/core/DynamicBufferAttribute.js diff --git a/src/core/BufferAttribute.js b/src/core/BufferAttribute.js index d19a4aeed2d8a4..78476a7bff4a1e 100644 --- a/src/core/BufferAttribute.js +++ b/src/core/BufferAttribute.js @@ -34,9 +34,10 @@ THREE.BufferAttribute.prototype = { }, - set: function ( value ) { + set: function ( value, offset ) { - this.array.set( value ); + offset !== undefined ? offset : offset = 0; + this.array.set( value, offset ); return this; @@ -101,7 +102,7 @@ THREE.BufferAttribute.prototype = { return this; }, - + clone: function () { return new THREE.BufferAttribute( new this.array.constructor( this.array ), this.itemSize ); diff --git a/src/core/DynamicBufferAttribute.js b/src/core/DynamicBufferAttribute.js new file mode 100644 index 00000000000000..a3faa1e2d10536 --- /dev/null +++ b/src/core/DynamicBufferAttribute.js @@ -0,0 +1,155 @@ +/** + * @author benaadams / https://twitter.com/ben_a_adams + */ + +THREE.DynamicBufferAttribute = function ( array, itemSize ) { + + THREE.BufferAttribute.call( this, array, itemSize ); + + this.updateRange = { offset: 0, count: -1 }; + +}; + +THREE.DynamicBufferAttribute.prototype = { + + constructor: THREE.DynamicBufferAttribute, + + get length() { + + return this.array.length; + + }, + + copyAt: function ( index1, attribute, index2 ) { + + index1 *= this.itemSize; + index2 *= attribute.itemSize; + + for ( var i = 0, l = this.itemSize; i < l; i++ ) { + + this.array[index1 + i] = attribute.array[index2 + i]; + + } + + this.markForUpdate( index1, this.itemSize ); + + }, + + set: function ( value, offset ) { + + offset !== undefined ? offset : offset = 0; + + this.array.set( value, offset ); + + this.markForUpdate( offset, value.length ); + + return this; + + }, + + setX: function ( index, x ) { + + index *= this.itemSize; + + this.array[index] = x; + + this.markForUpdate( index, 1 ); + + return this; + + }, + + setY: function ( index, y ) { + + index = index * this.itemSize + 1; + + this.array[index * this.itemSize + 1] = y; + + this.markForUpdate( index, 1 ); + + return this; + + }, + + setZ: function ( index, z ) { + + index = index * this.itemSize + 2; + + this.array[index * this.itemSize + 2] = z; + + this.markForUpdate( index, 1 ); + + return this; + + }, + + setXY: function ( index, x, y ) { + + index *= this.itemSize; + + this.array[index] = x; + this.array[index + 1] = y; + + this.markForUpdate( index, 2 ); + + return this; + + }, + + setXYZ: function ( index, x, y, z ) { + + index *= this.itemSize; + + this.array[index] = x; + this.array[index + 1] = y; + this.array[index + 2] = z; + + this.markForUpdate( index, 3 ); + + return this; + + }, + + setXYZW: function ( index, x, y, z, w ) { + + index *= this.itemSize; + + this.array[index] = x; + this.array[index + 1] = y; + this.array[index + 2] = z; + this.array[index + 3] = w; + + this.markForUpdate( index, 4 ); + + return this; + + }, + + markForUpdate: function ( offset, count ) { + + if ( this.updateRange.count <= 0 ) { + + this.updateRange.offset = offset; + this.updateRange.count = count; + + } else { + + var end0 = offset + count; + var end1 = this.updateRange.offset + this.updateRange.count; + + this.updateRange.offset = ( offset <= this.updateRange.offset ) ? offset : this.updateRange.offset; + this.updateRange.count = ( ( end0 >= end1 ) ? end0 : end1 ) - this.updateRange.offset; + + } + + return this; + + }, + + clone: function () { + + return new THREE.DynamicBufferAttribute( new this.array.constructor( this.array ), this.itemSize ); + + } + +}; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 94810d0c1898ed..24dd04f1f535e4 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3926,20 +3926,36 @@ THREE.WebGLRenderer = function ( parameters ) { var key = attributesKeys[ i ]; var attribute = attributes[ key ]; + var bufferType = ( key === 'index' ) ? _gl.ELEMENT_ARRAY_BUFFER : _gl.ARRAY_BUFFER; if ( attribute.buffer === undefined ) { attribute.buffer = _gl.createBuffer(); - attribute.needsUpdate = true; - - } + _gl.bindBuffer( bufferType, attribute.buffer ); + _gl.bufferData( bufferType, attribute.array, ( attribute instanceof THREE.DynamicBufferAttribute ) ? _gl.DYNAMIC_DRAW : _gl.STATIC_DRAW ); - if ( attribute.needsUpdate === true ) { + attribute.needsUpdate = false; - var bufferType = ( key === 'index' ) ? _gl.ELEMENT_ARRAY_BUFFER : _gl.ARRAY_BUFFER; + } else if ( attribute.needsUpdate === true ) { _gl.bindBuffer( bufferType, attribute.buffer ); - _gl.bufferData( bufferType, attribute.array, _gl.STATIC_DRAW ); + + if ( attribute.updateRange === undefined || attribute.updateRange.count === -1 ) { // Not using update ranges + + _gl.bufferSubData( bufferType, 0, attribute.array ); + + } else if ( attribute.updateRange.count === 0 ) { + + console.error( 'THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' ); + + } else { + + _gl.bufferSubData( bufferType, attribute.updateRange.offset * attribute.array.BYTES_PER_ELEMENT, + attribute.array.subarray( attribute.updateRange.offset, attribute.updateRange.offset + attribute.updateRange.count ) ); + + attribute.updateRange.count = 0; // reset range + + } attribute.needsUpdate = false; From 810761b252e475d9b8689235c93b176eda31df9b Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 23 Jan 2015 13:53:40 +0100 Subject: [PATCH 039/333] WebGLRenderer: Simplified the new premultipliedAlpha code. --- src/renderers/WebGLRenderer.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 4f15e2fa2af004..64b0f836dd0630 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -257,14 +257,12 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _premultipliedAlpha === true ) { - _gl.clearColor( r * a, g * a, b * a, a ); - - } else { - - _gl.clearColor( r, g, b, a ); + r *= a; g *= a; b *= a; } + _gl.clearColor( r, g, b, a ); + }; var setDefaultGLState = function () { From 822f9c553c893ee9deb13ee0d1c8b25d8b3ea476 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 23 Jan 2015 13:58:58 +0100 Subject: [PATCH 040/333] WebGLRenderer: Renamed local setClearColor to glClearColor for clarity. --- src/renderers/WebGLRenderer.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 64b0f836dd0630..bd3b0f6e4bd7b8 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -253,7 +253,7 @@ THREE.WebGLRenderer = function ( parameters ) { // - var setClearColor = function ( r, g, b, a ) { + var glClearColor = function ( r, g, b, a ) { if ( _premultipliedAlpha === true ) { @@ -284,7 +284,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight ); - setClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; @@ -551,7 +551,7 @@ THREE.WebGLRenderer = function ( parameters ) { _clearAlpha = alpha !== undefined ? alpha : 1; - setClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; @@ -565,7 +565,7 @@ THREE.WebGLRenderer = function ( parameters ) { _clearAlpha = alpha; - setClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; From 4f3c0fdd57f5a1e1d31ad7f394140b4612d6296f Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 23 Jan 2015 13:59:35 +0100 Subject: [PATCH 041/333] Updated builds. --- build/three.js | 42 +++++++++++---- build/three.min.js | 132 ++++++++++++++++++++++----------------------- 2 files changed, 97 insertions(+), 77 deletions(-) diff --git a/build/three.js b/build/three.js index 4e506e39133e84..d9fffbb44e8fc9 100644 --- a/build/three.js +++ b/build/three.js @@ -7729,33 +7729,33 @@ THREE.Object3D.prototype = { }, - getChildByName: function ( name, recursive ) { + getChildByName: function ( name ) { console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); - return this.getObjectByName( name, recursive ); + return this.getObjectByName( name ); }, - getObjectById: function ( id, recursive ) { + getObjectById: function ( id ) { - return this.getObjectByProperty( 'id', id, recursive ); + return this.getObjectByProperty( 'id', id ); }, - getObjectByName: function ( name, recursive ) { + getObjectByName: function ( name ) { - return this.getObjectByProperty( 'name', name, recursive ); + return this.getObjectByProperty( 'name', name ); }, - getObjectByProperty: function ( name, value, recursive ) { + getObjectByProperty: function ( name, value ) { if ( this[ name ] === value ) return this; for ( var i = 0, l = this.children.length; i < l; i ++ ) { var child = this.children[ i ]; - var object = child.getObjectByProperty( name, value, recursive ); + var object = child.getObjectByProperty( name, value ); if ( object !== undefined ) { @@ -11476,10 +11476,17 @@ THREE.Loader.prototype = { if ( m.transparency ) { + console.warn( 'transparency has been renamed to opacity' ); mpars.opacity = m.transparency; } + if ( m.opacity ) { + + mpars.opacity = m.opacity; + + } + if ( m.specularCoef ) { mpars.shininess = m.specularCoef; @@ -17704,6 +17711,18 @@ THREE.WebGLRenderer = function ( parameters ) { // + var glClearColor = function ( r, g, b, a ) { + + if ( _premultipliedAlpha === true ) { + + r *= a; g *= a; b *= a; + + } + + _gl.clearColor( r, g, b, a ); + + }; + var setDefaultGLState = function () { _gl.clearColor( 0, 0, 0, 1 ); @@ -17723,7 +17742,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight ); - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; @@ -17987,9 +18006,10 @@ THREE.WebGLRenderer = function ( parameters ) { this.setClearColor = function ( color, alpha ) { _clearColor.set( color ); + _clearAlpha = alpha !== undefined ? alpha : 1; - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; @@ -18003,7 +18023,7 @@ THREE.WebGLRenderer = function ( parameters ) { _clearAlpha = alpha; - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); }; diff --git a/build/three.min.js b/build/three.min.js index e409bba567c7fc..f25352e600592e 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -162,17 +162,17 @@ applyMatrix:function(a){this.matrix.multiplyMatrices(a,this.matrix);this.matrix. c);this.quaternion.multiply(a);return this}}(),rotateX:function(){var a=new THREE.Vector3(1,0,0);return function(b){return this.rotateOnAxis(a,b)}}(),rotateY:function(){var a=new THREE.Vector3(0,1,0);return function(b){return this.rotateOnAxis(a,b)}}(),rotateZ:function(){var a=new THREE.Vector3(0,0,1);return function(b){return this.rotateOnAxis(a,b)}}(),translateOnAxis:function(){var a=new THREE.Vector3;return function(b,c){a.copy(b).applyQuaternion(this.quaternion);this.position.add(a.multiplyScalar(c)); return this}}(),translate:function(a,b){console.warn("THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.");return this.translateOnAxis(b,a)},translateX:function(){var a=new THREE.Vector3(1,0,0);return function(b){return this.translateOnAxis(a,b)}}(),translateY:function(){var a=new THREE.Vector3(0,1,0);return function(b){return this.translateOnAxis(a,b)}}(),translateZ:function(){var a=new THREE.Vector3(0,0,1);return function(b){return this.translateOnAxis(a, b)}}(),localToWorld:function(a){return a.applyMatrix4(this.matrixWorld)},worldToLocal:function(){var a=new THREE.Matrix4;return function(b){return b.applyMatrix4(a.getInverse(this.matrixWorld))}}(),lookAt:function(){var a=new THREE.Matrix4;return function(b){a.lookAt(b,this.position,this.up);this.quaternion.setFromRotationMatrix(a)}}(),add:function(a){if(1ya?-1:1;h[4*a]=ga.x;h[4*a+1]=ga.y;h[4*a+2]=ga.z;h[4*a+3]=$a}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, +3*a);H.copy(xa);pa=k[a];ga.copy(pa);ga.sub(xa.multiplyScalar(xa.dot(pa))).normalize();ea.crossVectors(H,pa);ya=ea.dot(n[a]);$a=0>ya?-1:1;h[4*a]=ga.x;h[4*a+1]=ga.y;h[4*a+2]=ga.z;h[4*a+3]=$a}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],n=[],p=0;pr;r++)s=a[3*c+r],-1==m[s]?(q[2*r]=s,q[2*r+1]=-1,p++):m[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),m[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;ha.opacity)h.transparent=a.transparent;void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide);void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe);void 0!==a.vertexColors&&("face"=== -a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));a.transparency&&(h.opacity=a.transparency);a.specularCoef&&(h.shininess=a.specularCoef);a.mapDiffuse&&b&&d(h,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&d(h,"lightMap", -a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&d(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&d(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&d(h,"specularMap",a.mapSpecular,a.mapSpecularRepeat,a.mapSpecularOffset,a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapAlpha&&b&&d(h,"alphaMap",a.mapAlpha,a.mapAlphaRepeat,a.mapAlphaOffset, -a.mapAlphaWrap,a.mapAlphaAnisotropy);a.mapBumpScale&&(h.bumpScale=a.mapBumpScale);a.mapNormalFactor&&(h.normalScale=new THREE.Vector2(a.mapNormalFactor,a.mapNormalFactor));g=new THREE[g](h);void 0!==a.DbgName&&(g.name=a.DbgName);return g}};THREE.Loader.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=0,c=this.handlers.length;bh&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(p={id:nc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:n},q[k]=p,r.push(p)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=r;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gh&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(p={id:oc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:n},q[k]=p,r.push(p)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=r;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gY;Y++)qa=P[Y],Pa[Va]=qa.x,Pa[Va+1]=qa.y,Pa[Va+2]=qa.z,Va+=3;else for(Y=0;3>Y;Y++)Pa[Va]=M.x,Pa[Va+1]=M.y,Pa[Va+2]=M.z,Va+=3;l.bindBuffer(l.ARRAY_BUFFER, +La,z))}if(Jb){w=0;for(F=V.length;wY;Y++)pa=P[Y],Pa[Va]=pa.x,Pa[Va+1]=pa.y,Pa[Va+2]=pa.z,Va+=3;else for(Y=0;3>Y;Y++)Pa[Va]=M.x,Pa[Va+1]=M.y,Pa[Va+2]=M.z,Va+=3;l.bindBuffer(l.ARRAY_BUFFER, v.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Pa,z)}if(Ma&&Wa){w=0;for(F=V.length;wY;Y++)Da=O[Y],xb[mb]=Da.x,xb[mb+1]=Da.y,mb+=2;0Y;Y++)Aa=U[Y],ob[ya]=Aa.x,ob[ya+1]=Aa.y,ya+=2;0ua;ua++)ib[ua]=!I.autoScaleCubemaps||Gb||ba?ba?ka.image[ua].image:ka.image[ua]:M(ka.image[ua],Gc);var Rb=ib[0],Sb=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height),qb=S(ka.format),Tb=S(ka.type);U(l.TEXTURE_CUBE_MAP,ka,Sb);for(ua=0;6>ua;ua++)if(Gb)for(var zb,Hb=ib[ua].mipmaps,rb=0,Yb=Hb.length;rbua;ua++)ib[ua]=!I.autoScaleCubemaps||Gb||ba?ba?ka.image[ua].image:ka.image[ua]:M(ka.image[ua],Hc);var Rb=ib[0],Sb=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height),qb=S(ka.format),Tb=S(ka.type);U(l.TEXTURE_CUBE_MAP,ka,Sb);for(ua=0;6>ua;ua++)if(Gb)for(var zb,Hb=ib[ua].mipmaps,rb=0,Yb=Hb.length;rb=sc&&console.warn("WebGLRenderer: trying to use "+ -a+" texture units while this GPU supports only "+sc);Nb+=1;return a}function G(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function E(a,b,c,d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function w(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function D(a){a*=O;a!==tc&&(l.lineWidth(a),tc=a)}function A(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c|| -(l.polygonOffset(b,c),vc=b,wc=c)}function U(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,S(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,S(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,S(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,S(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+ +b;a.pointLightColor.needsUpdate=b;a.pointLightPosition.needsUpdate=b;a.pointLightDistance.needsUpdate=b;a.spotLightColor.needsUpdate=b;a.spotLightPosition.needsUpdate=b;a.spotLightDistance.needsUpdate=b;a.spotLightDirection.needsUpdate=b;a.spotLightAngleCos.needsUpdate=b;a.spotLightExponent.needsUpdate=b;a.hemisphereLightSkyColor.needsUpdate=b;a.hemisphereLightGroundColor.needsUpdate=b;a.hemisphereLightDirection.needsUpdate=b}function z(){var a=Nb;a>=tc&&console.warn("WebGLRenderer: trying to use "+ +a+" texture units while this GPU supports only "+tc);Nb+=1;return a}function G(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function E(a,b,c,d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function w(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function D(a){a*=O;a!==uc&&(l.lineWidth(a),uc=a)}function A(a,b,c){vc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),vc=a);!a||wc===b&&xc===c|| +(l.polygonOffset(b,c),wc=b,xc=c)}function U(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,S(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,S(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,S(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,S(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+ b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,N(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,N(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function K(a,b){l.bindRenderbuffer(l.RENDERBUFFER, a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function L(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP, @@ -513,24 +513,24 @@ if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.Byt if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a===THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA; if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE;b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT; if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT; -if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var P=void 0!==a.canvas?a.canvas:document.createElement("canvas"),W=void 0!==a.context?a.context:null,O=1,ga=void 0!==a.precision?a.precision:"highp",ea=void 0!==a.alpha?a.alpha:!1,xa=void 0!==a.depth?a.depth:!0,H=void 0!==a.stencil?a.stencil:!0,$a=void 0!==a.antialias?a.antialias:!1,qa=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,ya=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer: -!1,X=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ta=new THREE.Color(0),Za=0,pa=[],Fa={},Ga=[],Ta=[],za=[],vb=[],gb=[];this.domElement=P;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps= -!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var I=this,Xa=[],Xb=null,jb=null,Ib=-1,Sa="",Jb=null,Nb=0,sb=-1,Yb=-1,Zb=-1,dc=-1,ec=-1,fc=-1,gc=-1,hc=-1,ic=-1,jc=-1,kc=-1,uc=null,vc=null,wc=null,tc=null,Ya=0,tb=0,kb=P.width,eb=P.height,xc=0,yc=0,ub=new Uint8Array(16),Ma=new Uint8Array(16),wb=new THREE.Frustum,Cb=new THREE.Matrix4;new THREE.Matrix4;var Da=new THREE.Vector3,ma=new THREE.Vector3,Pb=!0,qc={ambient:[0,0,0],directional:{length:0, -colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},l;try{var zc={alpha:ea,depth:xa,stencil:H,antialias:$a,premultipliedAlpha:qa,preserveDrawingBuffer:ya};l=W||P.getContext("webgl",zc)||P.getContext("experimental-webgl",zc);if(null===l){if(null!==P.getContext("webgl"))throw"Error creating WebGL context with your selected attributes."; -throw"Error creating WebGL context.";}P.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();Fa={}},!1)}catch(Hc){console.error(Hc)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_standard_derivatives");X&&aa.get("EXT_frag_depth");var Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0); -l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND);l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(Ya,tb,kb,eb);l.clearColor(ta.r,ta.g,ta.b,Za)},Ac=function(){Jb=Xb=null;Yb=sb=kc=jc=Zb=-1;Sa="";Ib=-1;Pb=!0;for(var a=0;ab;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}I.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b= +function(a,b){ta.set(a);Za=void 0!==b?b:1;lc(ta.r,ta.g,ta.b,Za)};this.getClearAlpha=function(){return Za};this.setClearAlpha=function(a){Za=a;lc(ta.r,ta.g,ta.b,Za)};this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=l.COLOR_BUFFER_BIT;if(void 0===b||b)d|=l.DEPTH_BUFFER_BIT;if(void 0===c||c)d|=l.STENCIL_BUFFER_BIT;l.clear(d)};this.clearColor=function(){l.clear(l.COLOR_BUFFER_BIT)};this.clearDepth=function(){l.clear(l.DEPTH_BUFFER_BIT)};this.clearStencil=function(){l.clear(l.STENCIL_BUFFER_BIT)}; +this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=Bc;var mc=function(a){a.target.traverse(function(a){a.removeEventListener("remove",mc);if(a instanceof THREE.Mesh||a instanceof THREE.PointCloud||a instanceof THREE.Line)delete Fa[a.id];else if(a instanceof THREE.ImmediateRenderObject||a.immediateRenderCallback)for(var b=Ga,c=b.length-1;0<=c;c--)b[c].object===a&&b.splice(c,1);delete a.__webglInit;delete a._modelViewMatrix;delete a._normalMatrix;delete a.__webglActive})}, +nc=function(a){a=a.target;a.removeEventListener("dispose",nc);delete a.__webglInit;if(a instanceof THREE.BufferGeometry){for(var b in a.attributes){var c=a.attributes[b];void 0!==c.buffer&&(l.deleteBuffer(c.buffer),delete c.buffer)}I.info.memory.geometries--}else if(b=fb[a.id],void 0!==b){for(var c=0,d=b.length;cb;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}I.info.memory.textures--},qc=function(a){a=a.target;a.removeEventListener("dispose",qc);pc(a)},Ec=function(a){for(var b= "__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;cf;f++){a.__webglFramebuffer[f]= -l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);K(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: +THREE.WebGLRenderTargetCube;if(a&&void 0===a.__webglFramebuffer){void 0===a.depthBuffer&&(a.depthBuffer=!0);void 0===a.stencilBuffer&&(a.stencilBuffer=!0);a.addEventListener("dispose",Fc);a.__webglTexture=l.createTexture();I.info.memory.textures++;var c=THREE.Math.isPowerOfTwo(a.width)&&THREE.Math.isPowerOfTwo(a.height),d=S(a.format),e=S(a.type);if(b){a.__webglFramebuffer=[];a.__webglRenderbuffer=[];l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture);U(l.TEXTURE_CUBE_MAP,a,c);for(var g=0;6>g;g++){a.__webglFramebuffer[g]= +l.createFramebuffer();a.__webglRenderbuffer[g]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+g,0,d,a.width,a.height,0,d,e,null);var f=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+g;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[g]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,f.__webglTexture,0);K(a.__webglRenderbuffer[g],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),U(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER, -l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):K(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=kb,a=eb,d=Ya,e=tb);b!==jb&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),jb=b);xc=c;yc=a};this.readRenderTargetPixels= -function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==jb&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== -l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,jb)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; +l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):K(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=kb,a=eb,d=Ya,e=tb);b!==jb&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),jb=b);yc=c;zc=a};this.readRenderTargetPixels= +function(a,b,c,d,e,g){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var f=!1;a.__webglFramebuffer!==jb&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),f=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== +l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,g):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");f&&l.bindFramebuffer(l.FRAMEBUFFER,jb)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; @@ -594,7 +594,7 @@ K=m.createProgram(),L=m.createShader(m.FRAGMENT_SHADER),N=m.createShader(m.VERTE G,D),N=b[K],C.set(N.matrixWorld.elements[12],N.matrixWorld.elements[13],N.matrixWorld.elements[14]),C.applyMatrix4(x.matrixWorldInverse),C.applyProjection(x.projectionMatrix),U.copy(C),M.x=U.x*E+E,M.y=U.y*w+w,u||0Math.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; -THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cm&&(g=b[f],k=-k,h=b[e],m=-m),!(a.yh.y))if(a.y==g.y){if(a.x==g.x)return!0}else{e=m*(a.x-g.x)-k*(a.y-g.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<= +THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cm&&(f=b[g],k=-k,h=b[e],m=-m),!(a.yh.y))if(a.y==f.y){if(a.x==f.x)return!0}else{e=m*(a.x-f.x)-k*(a.y-f.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==f.y&&(h.x<=a.x&&a.x<=f.x||f.x<=a.x&&a.x<= h.x))return!0}return d}var e=function(a){var b,c,d,e,f=[],g=new THREE.Path;b=0;for(c=a.length;bd&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;c Date: Sat, 24 Jan 2015 19:30:33 +0100 Subject: [PATCH 042/333] Utils: Added DynamicBufferAttribute to includes. --- src/core/BufferAttribute.js | 5 +++-- src/core/DynamicBufferAttribute.js | 2 +- utils/build/includes/common.json | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/BufferAttribute.js b/src/core/BufferAttribute.js index 78476a7bff4a1e..de1c11cabe7c23 100644 --- a/src/core/BufferAttribute.js +++ b/src/core/BufferAttribute.js @@ -36,7 +36,8 @@ THREE.BufferAttribute.prototype = { set: function ( value, offset ) { - offset !== undefined ? offset : offset = 0; + if ( offset === undefined ) offset = 0; + this.array.set( value, offset ); return this; @@ -102,7 +103,7 @@ THREE.BufferAttribute.prototype = { return this; }, - + clone: function () { return new THREE.BufferAttribute( new this.array.constructor( this.array ), this.itemSize ); diff --git a/src/core/DynamicBufferAttribute.js b/src/core/DynamicBufferAttribute.js index a3faa1e2d10536..c3484735f2e6fa 100644 --- a/src/core/DynamicBufferAttribute.js +++ b/src/core/DynamicBufferAttribute.js @@ -37,7 +37,7 @@ THREE.DynamicBufferAttribute.prototype = { set: function ( value, offset ) { - offset !== undefined ? offset : offset = 0; + if ( offset === undefined ) offset = 0; this.array.set( value, offset ); diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index f6b9992cda2705..a13220077d8465 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -25,6 +25,7 @@ "src/core/Face3.js", "src/core/Face4.js", "src/core/BufferAttribute.js", + "src/core/DynamicBufferAttribute.js", "src/core/BufferGeometry.js", "src/core/Geometry.js", "src/cameras/Camera.js", From 67686409e9e509f8ba309538f2b89d4e5d8e6734 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 24 Jan 2015 20:09:30 +0100 Subject: [PATCH 043/333] Reworked DynamicBufferAttribute. Related #5969. Sorry @benaadams but the automatic updateRange code was troublesome. Better to let the user deal with it I think. --- examples/webgl_buffergeometry_drawcalls.html | 43 +++--- src/core/BufferAttribute.js | 2 + src/core/DynamicBufferAttribute.js | 144 +------------------ 3 files changed, 33 insertions(+), 156 deletions(-) diff --git a/examples/webgl_buffergeometry_drawcalls.html b/examples/webgl_buffergeometry_drawcalls.html index 299dec0e0f5d62..6154ca71e7c49e 100644 --- a/examples/webgl_buffergeometry_drawcalls.html +++ b/examples/webgl_buffergeometry_drawcalls.html @@ -102,21 +102,28 @@ scene = new THREE.Scene(); - geometry = new THREE.BufferGeometry(); - var material = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors }); + + group = new THREE.Group(); + scene.add( group ); + + var helper = new THREE.BoxHelper( new THREE.Mesh( new THREE.BoxGeometry( r, r, r ) ) ); + helper.material.color.setHex( 0x080808 ); + helper.material.blending = THREE.AdditiveBlending; + helper.material.transparent = true; + group.add( helper ); var segments = maxParticleCount * maxParticleCount; positions = new Float32Array( segments * 3 ); colors = new Float32Array( segments * 3 ); - var pMaterial = new THREE.PointCloudMaterial({ + var pMaterial = new THREE.PointCloudMaterial( { color: 0xFFFFFF, size: 3, blending: THREE.AdditiveBlending, transparent: true, sizeAttenuation: false - }); + } ); particles = new THREE.BufferGeometry(); particlePositions = new Float32Array( maxParticleCount * 3 ); @@ -132,10 +139,10 @@ particlePositions[ i * 3 + 2 ] = z; // add it to the geometry - particlesData.push({ + particlesData.push( { velocity: new THREE.Vector3( -1 + Math.random() * 2, -1 + Math.random() * 2, -1 + Math.random() * 2 ), numConnections: 0 - }); + } ); } @@ -145,18 +152,16 @@ index: 0 } ); - particles.addAttribute( 'position', new THREE.BufferAttribute( particlePositions, 3 ) ); + particles.addAttribute( 'position', new THREE.DynamicBufferAttribute( particlePositions, 3 ) ); // create the particle system pointCloud = new THREE.PointCloud( particles, pMaterial ); - - group = new THREE.Object3D(); - - // add it to the scene group.add( pointCloud ); - geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); - geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); + var geometry = new THREE.BufferGeometry(); + + geometry.addAttribute( 'position', new THREE.DynamicBufferAttribute( positions, 3 ) ); + geometry.addAttribute( 'color', new THREE.DynamicBufferAttribute( colors, 3 ) ); geometry.computeBoundingSphere(); @@ -166,15 +171,19 @@ index: 0 } ); + var material = new THREE.LineBasicMaterial( { + vertexColors: THREE.VertexColors, + blending: THREE.AdditiveBlending, + transparent: true + } ); + linesMesh = new THREE.Line( geometry, material, THREE.LinePieces ); group.add( linesMesh ); - scene.add( group ); - // renderer = new THREE.WebGLRenderer( { antialias: true } ); - renderer.setPixelRatio( window.devicePixelRatio ) + renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.gammaInput = true; @@ -249,7 +258,7 @@ particleData.numConnections++; particleDataB.numConnections++; - var alpha = 1.0 - dist / effectController.minDistance + 0.2; + var alpha = 1.0 - dist / effectController.minDistance; positions[ vertexpos++ ] = particlePositions[ i * 3 ]; positions[ vertexpos++ ] = particlePositions[ i * 3 + 1 ]; diff --git a/src/core/BufferAttribute.js b/src/core/BufferAttribute.js index de1c11cabe7c23..5808eca92172eb 100644 --- a/src/core/BufferAttribute.js +++ b/src/core/BufferAttribute.js @@ -32,6 +32,8 @@ THREE.BufferAttribute.prototype = { } + return this; + }, set: function ( value, offset ) { diff --git a/src/core/DynamicBufferAttribute.js b/src/core/DynamicBufferAttribute.js index c3484735f2e6fa..17610aa25bb76a 100644 --- a/src/core/DynamicBufferAttribute.js +++ b/src/core/DynamicBufferAttribute.js @@ -1,5 +1,6 @@ /** * @author benaadams / https://twitter.com/ben_a_adams + * @author mrdoob / http://mrdoob.com/ */ THREE.DynamicBufferAttribute = function ( array, itemSize ) { @@ -10,146 +11,11 @@ THREE.DynamicBufferAttribute = function ( array, itemSize ) { }; -THREE.DynamicBufferAttribute.prototype = { +THREE.DynamicBufferAttribute.prototype = Object.create( THREE.BufferAttribute.prototype ); +THREE.DynamicBufferAttribute.prototype.constructor = THREE.DynamicBufferAttribute; - constructor: THREE.DynamicBufferAttribute, +THREE.DynamicBufferAttribute.prototype.clone = function () { - get length() { - - return this.array.length; - - }, - - copyAt: function ( index1, attribute, index2 ) { - - index1 *= this.itemSize; - index2 *= attribute.itemSize; - - for ( var i = 0, l = this.itemSize; i < l; i++ ) { - - this.array[index1 + i] = attribute.array[index2 + i]; - - } - - this.markForUpdate( index1, this.itemSize ); - - }, - - set: function ( value, offset ) { - - if ( offset === undefined ) offset = 0; - - this.array.set( value, offset ); - - this.markForUpdate( offset, value.length ); - - return this; - - }, - - setX: function ( index, x ) { - - index *= this.itemSize; - - this.array[index] = x; - - this.markForUpdate( index, 1 ); - - return this; - - }, - - setY: function ( index, y ) { - - index = index * this.itemSize + 1; - - this.array[index * this.itemSize + 1] = y; - - this.markForUpdate( index, 1 ); - - return this; - - }, - - setZ: function ( index, z ) { - - index = index * this.itemSize + 2; - - this.array[index * this.itemSize + 2] = z; - - this.markForUpdate( index, 1 ); - - return this; - - }, - - setXY: function ( index, x, y ) { - - index *= this.itemSize; - - this.array[index] = x; - this.array[index + 1] = y; - - this.markForUpdate( index, 2 ); - - return this; - - }, - - setXYZ: function ( index, x, y, z ) { - - index *= this.itemSize; - - this.array[index] = x; - this.array[index + 1] = y; - this.array[index + 2] = z; - - this.markForUpdate( index, 3 ); - - return this; - - }, - - setXYZW: function ( index, x, y, z, w ) { - - index *= this.itemSize; - - this.array[index] = x; - this.array[index + 1] = y; - this.array[index + 2] = z; - this.array[index + 3] = w; - - this.markForUpdate( index, 4 ); - - return this; - - }, - - markForUpdate: function ( offset, count ) { - - if ( this.updateRange.count <= 0 ) { - - this.updateRange.offset = offset; - this.updateRange.count = count; - - } else { - - var end0 = offset + count; - var end1 = this.updateRange.offset + this.updateRange.count; - - this.updateRange.offset = ( offset <= this.updateRange.offset ) ? offset : this.updateRange.offset; - this.updateRange.count = ( ( end0 >= end1 ) ? end0 : end1 ) - this.updateRange.offset; - - } - - return this; - - }, - - clone: function () { - - return new THREE.DynamicBufferAttribute( new this.array.constructor( this.array ), this.itemSize ); - - } + return new THREE.DynamicBufferAttribute( new this.array.constructor( this.array ), this.itemSize ); }; From 911b818029262a918ce243597ea511a5710623fc Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 24 Jan 2015 20:11:08 +0100 Subject: [PATCH 044/333] Updated builds. --- build/three.js | 60 +++++++++++++++++++++++++++++++++++++++------- build/three.min.js | 26 ++++++++++---------- 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/build/three.js b/build/three.js index d9fffbb44e8fc9..b111393a1e5b5c 100644 --- a/build/three.js +++ b/build/three.js @@ -8254,11 +8254,15 @@ THREE.BufferAttribute.prototype = { } + return this; + }, - set: function ( value ) { + set: function ( value, offset ) { + + if ( offset === undefined ) offset = 0; - this.array.set( value ); + this.array.set( value, offset ); return this; @@ -8398,6 +8402,30 @@ THREE.Float64Attribute = function ( data, itemSize ) { }; +// File:src/core/DynamicBufferAttribute.js + +/** + * @author benaadams / https://twitter.com/ben_a_adams + * @author mrdoob / http://mrdoob.com/ + */ + +THREE.DynamicBufferAttribute = function ( array, itemSize ) { + + THREE.BufferAttribute.call( this, array, itemSize ); + + this.updateRange = { offset: 0, count: -1 }; + +}; + +THREE.DynamicBufferAttribute.prototype = Object.create( THREE.BufferAttribute.prototype ); +THREE.DynamicBufferAttribute.prototype.constructor = THREE.DynamicBufferAttribute; + +THREE.DynamicBufferAttribute.prototype.clone = function () { + + return new THREE.DynamicBufferAttribute( new this.array.constructor( this.array ), this.itemSize ); + +}; + // File:src/core/BufferGeometry.js /** @@ -21397,20 +21425,36 @@ THREE.WebGLRenderer = function ( parameters ) { var key = attributesKeys[ i ]; var attribute = attributes[ key ]; + var bufferType = ( key === 'index' ) ? _gl.ELEMENT_ARRAY_BUFFER : _gl.ARRAY_BUFFER; if ( attribute.buffer === undefined ) { attribute.buffer = _gl.createBuffer(); - attribute.needsUpdate = true; - - } + _gl.bindBuffer( bufferType, attribute.buffer ); + _gl.bufferData( bufferType, attribute.array, ( attribute instanceof THREE.DynamicBufferAttribute ) ? _gl.DYNAMIC_DRAW : _gl.STATIC_DRAW ); - if ( attribute.needsUpdate === true ) { + attribute.needsUpdate = false; - var bufferType = ( key === 'index' ) ? _gl.ELEMENT_ARRAY_BUFFER : _gl.ARRAY_BUFFER; + } else if ( attribute.needsUpdate === true ) { _gl.bindBuffer( bufferType, attribute.buffer ); - _gl.bufferData( bufferType, attribute.array, _gl.STATIC_DRAW ); + + if ( attribute.updateRange === undefined || attribute.updateRange.count === -1 ) { // Not using update ranges + + _gl.bufferSubData( bufferType, 0, attribute.array ); + + } else if ( attribute.updateRange.count === 0 ) { + + console.error( 'THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' ); + + } else { + + _gl.bufferSubData( bufferType, attribute.updateRange.offset * attribute.array.BYTES_PER_ELEMENT, + attribute.array.subarray( attribute.updateRange.offset, attribute.updateRange.offset + attribute.updateRange.count ) ); + + attribute.updateRange.count = 0; // reset range + + } attribute.needsUpdate = false; diff --git a/build/three.min.js b/build/three.min.js index f25352e600592e..e7884961f155f7 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -175,13 +175,14 @@ a.matrixWorldNeedsUpdate=this.matrixWorldNeedsUpdate;a.visible=this.visible;a.ca THREE.Face3=function(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=d instanceof Array?d:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=e instanceof Array?e:[];this.vertexTangents=[];this.materialIndex=void 0!==f?f:0}; THREE.Face3.prototype={constructor:THREE.Face3,clone:function(){var a=new THREE.Face3(this.a,this.b,this.c);a.normal.copy(this.normal);a.color.copy(this.color);a.materialIndex=this.materialIndex;for(var b=0,c=this.vertexNormals.length;bh&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(p={id:oc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:n},q[k]=p,r.push(p)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=r;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gY;Y++)pa=P[Y],Pa[Va]=pa.x,Pa[Va+1]=pa.y,Pa[Va+2]=pa.z,Va+=3;else for(Y=0;3>Y;Y++)Pa[Va]=M.x,Pa[Va+1]=M.y,Pa[Va+2]=M.z,Va+=3;l.bindBuffer(l.ARRAY_BUFFER, +a.geometry;if(b instanceof THREE.BufferGeometry)for(var e=b.attributes,f=b.attributesKeys,g=0,h=f.length;gY;Y++)pa=P[Y],Pa[Va]=pa.x,Pa[Va+1]=pa.y,Pa[Va+2]=pa.z,Va+=3;else for(Y=0;3>Y;Y++)Pa[Va]=M.x,Pa[Va+1]=M.y,Pa[Va+2]=M.z,Va+=3;l.bindBuffer(l.ARRAY_BUFFER, v.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Pa,z)}if(Ma&&Wa){w=0;for(F=V.length;wY;Y++)Da=O[Y],xb[mb]=Da.x,xb[mb+1]=Da.y,mb+=2;0Y;Y++)Aa=U[Y],ob[ya]=Aa.x,ob[ya+1]=Aa.y,ya+=2;0 Date: Sat, 24 Jan 2015 20:38:37 +0100 Subject: [PATCH 045/333] *DecayExponent to *Decay --- examples/js/ShaderSkin.js | 14 +++++------ examples/js/ShaderTerrain.js | 4 ++-- examples/js/exporters/SceneExporter.js | 4 ++-- src/core/Object3D.js | 4 ++-- src/lights/PointLight.js | 8 +++---- src/lights/SpotLight.js | 8 +++---- src/renderers/WebGLRenderer.js | 24 +++++++++---------- .../lights_lambert_pars_vertex.glsl | 4 ++-- .../ShaderChunk/lights_lambert_vertex.glsl | 8 +++---- .../ShaderChunk/lights_phong_fragment.glsl | 6 ++--- .../lights_phong_pars_fragment.glsl | 6 ++--- src/renderers/shaders/UniformsLib.js | 4 ++-- 12 files changed, 47 insertions(+), 47 deletions(-) diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 223539a359ac61..51d38d55f60b90 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -103,7 +103,7 @@ THREE.ShaderSkin = { "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ];", + "uniform float pointLightDecay[ MAX_POINT_LIGHTS ];", "#endif", @@ -201,8 +201,8 @@ THREE.ShaderSkin = { "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", "vec3 lVector = lPosition.xyz + vViewPosition.xyz;", - - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] );", + + "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );", "lVector = normalize( lVector );", @@ -624,7 +624,7 @@ THREE.ShaderSkin = { "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ];", + "uniform float pointLightDecay[ MAX_POINT_LIGHTS ];", "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];", @@ -663,7 +663,7 @@ THREE.ShaderSkin = { "vec3 lVector = lPosition.xyz - mvPosition.xyz;", - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] );", + "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );", "lVector = normalize( lVector );", @@ -713,7 +713,7 @@ THREE.ShaderSkin = { "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ];", + "uniform float pointLightDecay[ MAX_POINT_LIGHTS ];", "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];", @@ -752,7 +752,7 @@ THREE.ShaderSkin = { "vec3 lVector = lPosition.xyz - mvPosition.xyz;", - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] );", + "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );", "lVector = normalize( lVector );", diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index 2b70b434c2cd70..a8acea32bbaafe 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -106,7 +106,7 @@ THREE.ShaderTerrain = { "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ];", + "uniform float pointLightDecay[ MAX_POINT_LIGHTS ];", "#endif", @@ -174,7 +174,7 @@ THREE.ShaderTerrain = { "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", "vec3 lVector = lPosition.xyz + vViewPosition.xyz;", - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] );" + "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );" "lVector = normalize( lVector );", diff --git a/examples/js/exporters/SceneExporter.js b/examples/js/exporters/SceneExporter.js index e83ac551a3317f..169b1d093bb0f0 100644 --- a/examples/js/exporters/SceneExporter.js +++ b/examples/js/exporters/SceneExporter.js @@ -242,7 +242,7 @@ THREE.SceneExporter.prototype = { ' "color" : ' + o.color.getHex() + ',', ' "intensity" : ' + o.intensity + ',', ' "position" : ' + Vector3String( o.position ) + ',', - ' "decayExponent" : ' + o.decayExponent + ',', + ' "decay" : ' + o.decay + ',', ' "distance" : ' + o.distance + ( o.children.length ? ',' : '' ) ]; @@ -259,7 +259,7 @@ THREE.SceneExporter.prototype = { ' "distance" : ' + o.distance + ',', ' "angle" : ' + o.angle + ',', ' "exponent" : ' + o.exponent + ',', - ' "decayExponent" : ' + o.decayExponent + ',', + ' "decay" : ' + o.decay + ',', ' "target" : ' + LabelString( getObjectName( o.target ) ) + ( o.children.length ? ',' : '' ) ]; diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 05eebc050ebe15..ff25a2368be8d3 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -677,7 +677,7 @@ THREE.Object3D.prototype = { data.color = object.color.getHex(); data.intensity = object.intensity; data.distance = object.distance; - data.decayExponent = object.decayExponent || 0; + data.decay = object.decay; } else if ( object instanceof THREE.SpotLight ) { @@ -686,7 +686,7 @@ THREE.Object3D.prototype = { data.distance = object.distance; data.angle = object.angle; data.exponent = object.exponent; - data.decayExponent = object.decayExponent || 0; + data.decay = object.decay; } else if ( object instanceof THREE.HemisphereLight ) { diff --git a/src/lights/PointLight.js b/src/lights/PointLight.js index fb21de59a09ff4..15e309ac9d3d11 100644 --- a/src/lights/PointLight.js +++ b/src/lights/PointLight.js @@ -2,7 +2,7 @@ * @author mrdoob / http://mrdoob.com/ */ -THREE.PointLight = function ( color, intensity, distance, decayExponent ) { +THREE.PointLight = function ( color, intensity, distance, decay ) { THREE.Light.call( this, color ); @@ -10,7 +10,7 @@ THREE.PointLight = function ( color, intensity, distance, decayExponent ) { this.intensity = ( intensity !== undefined ) ? intensity : 1; this.distance = ( distance !== undefined ) ? distance : 0; - this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 1; // for physically correct lights, should be 2. + this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. }; @@ -25,8 +25,8 @@ THREE.PointLight.prototype.clone = function () { light.intensity = this.intensity; light.distance = this.distance; - light.decayExponent = this.decayExponent; - + light.decay = this.decay; + return light; }; diff --git a/src/lights/SpotLight.js b/src/lights/SpotLight.js index f409bbccc76879..50384adb6bb141 100644 --- a/src/lights/SpotLight.js +++ b/src/lights/SpotLight.js @@ -2,7 +2,7 @@ * @author alteredq / http://alteredqualia.com/ */ -THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decayExponent ) { +THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decay ) { THREE.Light.call( this, color ); @@ -15,7 +15,7 @@ THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decayE this.distance = ( distance !== undefined ) ? distance : 0; this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; this.exponent = ( exponent !== undefined ) ? exponent : 10; - this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 1; // for physically correct lights, should be 2. + this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. this.castShadow = false; this.onlyShadow = false; @@ -58,8 +58,8 @@ THREE.SpotLight.prototype.clone = function () { light.distance = this.distance; light.angle = this.angle; light.exponent = this.exponent; - light.decayExponent = this.decayExponent; - + light.decay = this.decay; + light.castShadow = this.castShadow; light.onlyShadow = this.onlyShadow; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 960dd0317d0a89..4d5873e43737f3 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -171,8 +171,8 @@ THREE.WebGLRenderer = function ( parameters ) { ambient: [ 0, 0, 0 ], directional: { length: 0, colors:[], positions: [] }, - point: { length: 0, colors: [], positions: [], distances: [], decayExponents: [] }, - spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [], decayExponents: [] }, + point: { length: 0, colors: [], positions: [], distances: [], decays: [] }, + spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [], decays: [] }, hemi: { length: 0, skyColors: [], groundColors: [], positions: [] } }; @@ -3464,7 +3464,7 @@ THREE.WebGLRenderer = function ( parameters ) { for ( var i = 0, l = webglObjects.length; i < l; i ++ ) { - var webglObject = webglObjects[i]; + var webglObject = webglObjects[ i ]; unrollBufferMaterial( webglObject ); @@ -4776,7 +4776,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.pointLightColor.value = lights.point.colors; uniforms.pointLightPosition.value = lights.point.positions; uniforms.pointLightDistance.value = lights.point.distances; - uniforms.pointLightDecayExponent.value = lights.point.decayExponents; + uniforms.pointLightDecay.value = lights.point.decays; uniforms.spotLightColor.value = lights.spot.colors; uniforms.spotLightPosition.value = lights.spot.positions; @@ -4784,7 +4784,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.spotLightDirection.value = lights.spot.directions; uniforms.spotLightAngleCos.value = lights.spot.anglesCos; uniforms.spotLightExponent.value = lights.spot.exponents; - uniforms.spotLightDecayExponent.value = lights.spot.decayExponents; + uniforms.spotLightDecay.value = lights.spot.decays; uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors; uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors; @@ -4804,7 +4804,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.pointLightColor.needsUpdate = boolean; uniforms.pointLightPosition.needsUpdate = boolean; uniforms.pointLightDistance.needsUpdate = boolean; - uniforms.pointLightDecayExponent.needsUpdate = boolean; + uniforms.pointLightDecay.needsUpdate = boolean; uniforms.spotLightColor.needsUpdate = boolean; uniforms.spotLightPosition.needsUpdate = boolean; @@ -4812,7 +4812,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.spotLightDirection.needsUpdate = boolean; uniforms.spotLightAngleCos.needsUpdate = boolean; uniforms.spotLightExponent.needsUpdate = boolean; - uniforms.spotLightDecayExponent.needsUpdate = boolean; + uniforms.spotLightDecay.needsUpdate = boolean; uniforms.hemisphereLightSkyColor.needsUpdate = boolean; uniforms.hemisphereLightGroundColor.needsUpdate = boolean; @@ -5260,7 +5260,7 @@ THREE.WebGLRenderer = function ( parameters ) { pointColors = zlights.point.colors, pointPositions = zlights.point.positions, pointDistances = zlights.point.distances, - pointDecayExponents = zlights.point.decayExponents, + pointDecays = zlights.point.decays, spotColors = zlights.spot.colors, spotPositions = zlights.spot.positions, @@ -5268,7 +5268,7 @@ THREE.WebGLRenderer = function ( parameters ) { spotDirections = zlights.spot.directions, spotAnglesCos = zlights.spot.anglesCos, spotExponents = zlights.spot.exponents, - spotDecayExponents = zlights.spot.decayExponents, + spotDecays = zlights.spot.decays, hemiSkyColors = zlights.hemi.skyColors, hemiGroundColors = zlights.hemi.groundColors, @@ -5370,9 +5370,9 @@ THREE.WebGLRenderer = function ( parameters ) { pointPositions[ pointOffset + 1 ] = _vector3.y; pointPositions[ pointOffset + 2 ] = _vector3.z; - // distance is 0 if decayExponent is 0, because there is no attenuation at all. + // distance is 0 if decay is 0, because there is no attenuation at all. pointDistances[ pointLength ] = distance; - pointDecayExponents[ pointLength ] = ( light.distance === 0 ) ? 0.0 : light.decayExponent; + pointDecays[ pointLength ] = ( light.distance === 0 ) ? 0.0 : light.decay; pointLength += 1; @@ -5412,7 +5412,7 @@ THREE.WebGLRenderer = function ( parameters ) { spotAnglesCos[ spotLength ] = Math.cos( light.angle ); spotExponents[ spotLength ] = light.exponent; - spotDecayExponents[ spotLength ] = ( light.distance === 0 ) ? 0.0 : light.decayExponent; + spotDecays[ spotLength ] = ( light.distance === 0 ) ? 0.0 : light.decay; spotLength += 1; diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl index cfae0ef52cea46..bbebfac755763c 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl @@ -23,7 +23,7 @@ uniform vec3 ambientLightColor; uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; - uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ]; + uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; #endif @@ -35,7 +35,7 @@ uniform vec3 ambientLightColor; uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; - uniform float spotLightDecayExponent[ MAX_SPOT_LIGHTS ]; + uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index ed14c836f9531b..1fddd3e2aeeef4 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -61,7 +61,7 @@ for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 ); vec3 lVector = lPosition.xyz - mvPosition.xyz; - float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] ); + float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] ); lVector = normalize( lVector ); float dotProduct = dot( transformedNormal, lVector ); @@ -118,7 +118,7 @@ for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 ); - float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecayExponent[i] ); + float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] ); lVector = normalize( lVector ); @@ -192,5 +192,5 @@ vLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive; #ifdef DOUBLE_SIDED vLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive; - -#endif \ No newline at end of file + +#endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 19319a90fada17..ddcbbdb00fd7d6 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -27,7 +27,7 @@ vec3 viewPosition = normalize( vViewPosition ); vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 ); vec3 lVector = lPosition.xyz + vViewPosition.xyz; - float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] ); + float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] ); lVector = normalize( lVector ); @@ -75,7 +75,7 @@ vec3 viewPosition = normalize( vViewPosition ); vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 ); vec3 lVector = lPosition.xyz + vViewPosition.xyz; - float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecayExponent[i] ); + float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] ); lVector = normalize( lVector ); @@ -269,4 +269,4 @@ vec3 totalSpecular = vec3( 0.0 ); gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular; -#endif \ No newline at end of file +#endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 11e00995c7d225..cc78d8166e9cf8 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -21,7 +21,7 @@ uniform vec3 ambientLightColor; uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; - uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ]; + uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; #endif @@ -33,7 +33,7 @@ uniform vec3 ambientLightColor; uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; - uniform float spotLightDecayExponent[ MAX_SPOT_LIGHTS ]; + uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; #endif @@ -50,4 +50,4 @@ uniform vec3 ambientLightColor; #endif varying vec3 vViewPosition; -varying vec3 vNormal; \ No newline at end of file +varying vec3 vNormal; diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index 2302425dfb2f07..d8dcf771e91ef2 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -61,7 +61,7 @@ THREE.UniformsLib = { "pointLightColor" : { type: "fv", value: [] }, "pointLightPosition" : { type: "fv", value: [] }, "pointLightDistance" : { type: "fv1", value: [] }, - "pointLightDecayExponent" : { type: "fv1", value: [] }, + "pointLightDecay" : { type: "fv1", value: [] }, "spotLightColor" : { type: "fv", value: [] }, "spotLightPosition" : { type: "fv", value: [] }, @@ -69,7 +69,7 @@ THREE.UniformsLib = { "spotLightDistance" : { type: "fv1", value: [] }, "spotLightAngleCos" : { type: "fv1", value: [] }, "spotLightExponent" : { type: "fv1", value: [] }, - "spotLightDecayExponent" : { type: "fv1", value: [] } + "spotLightDecay" : { type: "fv1", value: [] } }, From 8a1823a51b6ef4df5d4440eb397d670313474281 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 24 Jan 2015 20:40:36 +0100 Subject: [PATCH 046/333] Updated builds. --- build/three.js | 39 ++++-- build/three.min.js | 336 ++++++++++++++++++++++----------------------- 2 files changed, 196 insertions(+), 179 deletions(-) diff --git a/build/three.js b/build/three.js index b111393a1e5b5c..088e7f1051a8ae 100644 --- a/build/three.js +++ b/build/three.js @@ -8038,6 +8038,7 @@ THREE.Object3D.prototype = { data.color = object.color.getHex(); data.intensity = object.intensity; data.distance = object.distance; + data.decay = object.decay; } else if ( object instanceof THREE.SpotLight ) { @@ -8046,6 +8047,7 @@ THREE.Object3D.prototype = { data.distance = object.distance; data.angle = object.angle; data.exponent = object.exponent; + data.decay = object.decay; } else if ( object instanceof THREE.HemisphereLight ) { @@ -11034,7 +11036,7 @@ THREE.HemisphereLight.prototype.clone = function () { * @author mrdoob / http://mrdoob.com/ */ -THREE.PointLight = function ( color, intensity, distance ) { +THREE.PointLight = function ( color, intensity, distance, decay ) { THREE.Light.call( this, color ); @@ -11042,6 +11044,7 @@ THREE.PointLight = function ( color, intensity, distance ) { this.intensity = ( intensity !== undefined ) ? intensity : 1; this.distance = ( distance !== undefined ) ? distance : 0; + this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. }; @@ -11056,6 +11059,7 @@ THREE.PointLight.prototype.clone = function () { light.intensity = this.intensity; light.distance = this.distance; + light.decay = this.decay; return light; @@ -11067,7 +11071,7 @@ THREE.PointLight.prototype.clone = function () { * @author alteredq / http://alteredqualia.com/ */ -THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) { +THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decay ) { THREE.Light.call( this, color ); @@ -11080,6 +11084,7 @@ THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) { this.distance = ( distance !== undefined ) ? distance : 0; this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; this.exponent = ( exponent !== undefined ) ? exponent : 10; + this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. this.castShadow = false; this.onlyShadow = false; @@ -11122,6 +11127,7 @@ THREE.SpotLight.prototype.clone = function () { light.distance = this.distance; light.angle = this.angle; light.exponent = this.exponent; + light.decay = this.decay; light.castShadow = this.castShadow; light.onlyShadow = this.onlyShadow; @@ -16315,7 +16321,7 @@ THREE.ShaderChunk = {}; // File:src/renderers/shaders/ShaderChunk/common.glsl -THREE.ShaderChunk[ 'common'] = "#define PI 3.14159\n#define PI2 6.28318\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n\nfloat square( in float a ) { return a*a; }\nvec2 square( in vec2 a ) { return vec2( a.x*a.x, a.y*a.y ); }\nvec3 square( in vec3 a ) { return vec3( a.x*a.x, a.y*a.y, a.z*a.z ); }\nvec4 square( in vec4 a ) { return vec4( a.x*a.x, a.y*a.y, a.z*a.z, a.w*a.w ); }\nfloat saturate( in float a ) { return clamp( a, 0.0, 1.0 ); }\nvec2 saturate( in vec2 a ) { return clamp( a, 0.0, 1.0 ); }\nvec3 saturate( in vec3 a ) { return clamp( a, 0.0, 1.0 ); }\nvec4 saturate( in vec4 a ) { return clamp( a, 0.0, 1.0 ); }\nfloat average( in float a ) { return a; }\nfloat average( in vec2 a ) { return ( a.x + a.y) * 0.5; }\nfloat average( in vec3 a ) { return ( a.x + a.y + a.z) / 3.0; }\nfloat average( in vec4 a ) { return ( a.x + a.y + a.z + a.w) * 0.25; }\nfloat whiteCompliment( in float a ) { return saturate( 1.0 - a ); }\nvec2 whiteCompliment( in vec2 a ) { return saturate( vec2(1.0) - a ); }\nvec3 whiteCompliment( in vec3 a ) { return saturate( vec3(1.0) - a ); }\nvec4 whiteCompliment( in vec4 a ) { return saturate( vec4(1.0) - a ); }\nvec3 transformDirection( in vec3 normal, in mat4 matrix ) {\n return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz );\n}\n// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations\nvec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {\n return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal) {\n float distance = dot( planeNormal, point-pointOnPlane );\n return point - distance * planeNormal;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) );\n}"; +THREE.ShaderChunk[ 'common'] = "#define PI 3.14159\n#define PI2 6.28318\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n\nfloat square( in float a ) { return a*a; }\nvec2 square( in vec2 a ) { return vec2( a.x*a.x, a.y*a.y ); }\nvec3 square( in vec3 a ) { return vec3( a.x*a.x, a.y*a.y, a.z*a.z ); }\nvec4 square( in vec4 a ) { return vec4( a.x*a.x, a.y*a.y, a.z*a.z, a.w*a.w ); }\nfloat saturate( in float a ) { return clamp( a, 0.0, 1.0 ); }\nvec2 saturate( in vec2 a ) { return clamp( a, 0.0, 1.0 ); }\nvec3 saturate( in vec3 a ) { return clamp( a, 0.0, 1.0 ); }\nvec4 saturate( in vec4 a ) { return clamp( a, 0.0, 1.0 ); }\nfloat average( in float a ) { return a; }\nfloat average( in vec2 a ) { return ( a.x + a.y) * 0.5; }\nfloat average( in vec3 a ) { return ( a.x + a.y + a.z) / 3.0; }\nfloat average( in vec4 a ) { return ( a.x + a.y + a.z + a.w) * 0.25; }\nfloat whiteCompliment( in float a ) { return saturate( 1.0 - a ); }\nvec2 whiteCompliment( in vec2 a ) { return saturate( vec2(1.0) - a ); }\nvec3 whiteCompliment( in vec3 a ) { return saturate( vec3(1.0) - a ); }\nvec4 whiteCompliment( in vec4 a ) { return saturate( vec4(1.0) - a ); }\nvec3 transformDirection( in vec3 normal, in mat4 matrix ) {\n return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz );\n}\n// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations\nvec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {\n return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal) {\n float distance = dot( planeNormal, point-pointOnPlane );\n return point - distance * planeNormal;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) );\n}\nfloat calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {\n if ( decayExponent > 0.0 ) {\n return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent );\n }\n return 1.0;\n}\n\n"; // File:src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl @@ -16323,7 +16329,7 @@ THREE.ShaderChunk[ 'alphatest_fragment'] = "#ifdef ALPHATEST\n\n if ( gl_FragCol // File:src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl -THREE.ShaderChunk[ 'lights_lambert_vertex'] = "vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n vLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n float dotProduct = dot( transformedNormal, dirVector );\n vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n #endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n float lDistance = 1.0;\n if ( pointLightDistance[ i ] > 0.0 )\n lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\n\n lVector = normalize( lVector );\n float dotProduct = dot( transformedNormal, lVector );\n\n vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;\n\n #endif\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n float lDistance = 1.0;\n if ( spotLightDistance[ i ] > 0.0 )\n lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\n\n lVector = normalize( lVector );\n\n float dotProduct = dot( transformedNormal, lVector );\n vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;\n\n #endif\n\n }\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n float dotProduct = dot( transformedNormal, lVector );\n\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n #endif\n\n }\n\n#endif\n\nvLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive;\n\n#ifdef DOUBLE_SIDED\n\n vLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive;\n \n#endif"; +THREE.ShaderChunk[ 'lights_lambert_vertex'] = "vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n vLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n float dotProduct = dot( transformedNormal, dirVector );\n vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n #endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n float dotProduct = dot( transformedNormal, lVector );\n\n vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n #endif\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float dotProduct = dot( transformedNormal, lVector );\n vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n #endif\n\n }\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n float dotProduct = dot( transformedNormal, lVector );\n\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n #endif\n\n }\n\n#endif\n\nvLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive;\n\n#ifdef DOUBLE_SIDED\n\n vLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/map_particle_pars_fragment.glsl @@ -16351,7 +16357,7 @@ THREE.ShaderChunk[ 'lightmap_pars_vertex'] = "#ifdef USE_LIGHTMAP\n\n varying ve // File:src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_fragment'] = "vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n#endif\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n vec3 pointDiffuse = vec3( 0.0 );\n vec3 pointSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float lDistance = 1.0;\n if ( pointLightDistance[ i ] > 0.0 )\n lDistance = saturate( 1.0 - ( length( lVector ) / pointLightDistance[ i ] ) );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n vec3 spotDiffuse = vec3( 0.0 );\n vec3 spotSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float lDistance = 1.0;\n if ( spotLightDistance[ i ] > 0.0 )\n lDistance = saturate( 1.0 - ( length( lVector ) / spotLightDistance[ i ] ) );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n vec3 dirDiffuse = vec3( 0.0 );\n vec3 dirSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n vec3 hemiDiffuse = vec3( 0.0 );\n vec3 hemiSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n hemiDiffuse += diffuse * hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n totalDiffuse += dirDiffuse;\n totalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n totalDiffuse += hemiDiffuse;\n totalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n totalDiffuse += pointDiffuse;\n totalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n totalDiffuse += spotDiffuse;\n totalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif"; +THREE.ShaderChunk[ 'lights_phong_fragment'] = "vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n#endif\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n vec3 pointDiffuse = vec3( 0.0 );\n vec3 pointSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n vec3 spotDiffuse = vec3( 0.0 );\n vec3 spotSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n vec3 dirDiffuse = vec3( 0.0 );\n vec3 dirSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n vec3 hemiDiffuse = vec3( 0.0 );\n vec3 hemiSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n hemiDiffuse += diffuse * hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n totalDiffuse += dirDiffuse;\n totalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n totalDiffuse += hemiDiffuse;\n totalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n totalDiffuse += pointDiffuse;\n totalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n totalDiffuse += spotDiffuse;\n totalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl @@ -16427,7 +16433,7 @@ THREE.ShaderChunk[ 'color_pars_vertex'] = "#ifdef USE_COLOR\n\n varying vec3 vCo // File:src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl -THREE.ShaderChunk[ 'lights_lambert_pars_vertex'] = "uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n uniform vec3 wrapRGB;\n\n#endif\n"; +THREE.ShaderChunk[ 'lights_lambert_pars_vertex'] = "uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n uniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n uniform vec3 wrapRGB;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/map_pars_vertex.glsl @@ -16467,7 +16473,7 @@ THREE.ShaderChunk[ 'defaultnormal_vertex'] = "#ifdef USE_SKINNING\n\n vec3 objec // File:src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_pars_fragment'] = "uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n varying vec3 vWorldPosition;\n\n#endif\n\n#ifdef WRAP_AROUND\n\n uniform vec3 wrapRGB;\n\n#endif\n\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;"; +THREE.ShaderChunk[ 'lights_phong_pars_fragment'] = "uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n uniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n varying vec3 vWorldPosition;\n\n#endif\n\n#ifdef WRAP_AROUND\n\n uniform vec3 wrapRGB;\n\n#endif\n\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;\n"; // File:src/renderers/shaders/ShaderChunk/skinbase_vertex.glsl @@ -16659,13 +16665,15 @@ THREE.UniformsLib = { "pointLightColor" : { type: "fv", value: [] }, "pointLightPosition" : { type: "fv", value: [] }, "pointLightDistance" : { type: "fv1", value: [] }, + "pointLightDecay" : { type: "fv1", value: [] }, "spotLightColor" : { type: "fv", value: [] }, "spotLightPosition" : { type: "fv", value: [] }, "spotLightDirection" : { type: "fv", value: [] }, "spotLightDistance" : { type: "fv1", value: [] }, "spotLightAngleCos" : { type: "fv1", value: [] }, - "spotLightExponent" : { type: "fv1", value: [] } + "spotLightExponent" : { type: "fv1", value: [] }, + "spotLightDecay" : { type: "fv1", value: [] } }, @@ -17657,8 +17665,8 @@ THREE.WebGLRenderer = function ( parameters ) { ambient: [ 0, 0, 0 ], directional: { length: 0, colors:[], positions: [] }, - point: { length: 0, colors: [], positions: [], distances: [] }, - spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [] }, + point: { length: 0, colors: [], positions: [], distances: [], decays: [] }, + spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [], decays: [] }, hemi: { length: 0, skyColors: [], groundColors: [], positions: [] } }; @@ -20950,7 +20958,7 @@ THREE.WebGLRenderer = function ( parameters ) { for ( var i = 0, l = webglObjects.length; i < l; i ++ ) { - var webglObject = webglObjects[i]; + var webglObject = webglObjects[ i ]; unrollBufferMaterial( webglObject ); @@ -22262,6 +22270,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.pointLightColor.value = lights.point.colors; uniforms.pointLightPosition.value = lights.point.positions; uniforms.pointLightDistance.value = lights.point.distances; + uniforms.pointLightDecay.value = lights.point.decays; uniforms.spotLightColor.value = lights.spot.colors; uniforms.spotLightPosition.value = lights.spot.positions; @@ -22269,6 +22278,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.spotLightDirection.value = lights.spot.directions; uniforms.spotLightAngleCos.value = lights.spot.anglesCos; uniforms.spotLightExponent.value = lights.spot.exponents; + uniforms.spotLightDecay.value = lights.spot.decays; uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors; uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors; @@ -22288,6 +22298,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.pointLightColor.needsUpdate = boolean; uniforms.pointLightPosition.needsUpdate = boolean; uniforms.pointLightDistance.needsUpdate = boolean; + uniforms.pointLightDecay.needsUpdate = boolean; uniforms.spotLightColor.needsUpdate = boolean; uniforms.spotLightPosition.needsUpdate = boolean; @@ -22295,6 +22306,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.spotLightDirection.needsUpdate = boolean; uniforms.spotLightAngleCos.needsUpdate = boolean; uniforms.spotLightExponent.needsUpdate = boolean; + uniforms.spotLightDecay.needsUpdate = boolean; uniforms.hemisphereLightSkyColor.needsUpdate = boolean; uniforms.hemisphereLightGroundColor.needsUpdate = boolean; @@ -22742,6 +22754,7 @@ THREE.WebGLRenderer = function ( parameters ) { pointColors = zlights.point.colors, pointPositions = zlights.point.positions, pointDistances = zlights.point.distances, + pointDecays = zlights.point.decays, spotColors = zlights.spot.colors, spotPositions = zlights.spot.positions, @@ -22749,6 +22762,7 @@ THREE.WebGLRenderer = function ( parameters ) { spotDirections = zlights.spot.directions, spotAnglesCos = zlights.spot.anglesCos, spotExponents = zlights.spot.exponents, + spotDecays = zlights.spot.decays, hemiSkyColors = zlights.hemi.skyColors, hemiGroundColors = zlights.hemi.groundColors, @@ -22850,7 +22864,9 @@ THREE.WebGLRenderer = function ( parameters ) { pointPositions[ pointOffset + 1 ] = _vector3.y; pointPositions[ pointOffset + 2 ] = _vector3.z; + // distance is 0 if decay is 0, because there is no attenuation at all. pointDistances[ pointLength ] = distance; + pointDecays[ pointLength ] = ( light.distance === 0 ) ? 0.0 : light.decay; pointLength += 1; @@ -22890,6 +22906,7 @@ THREE.WebGLRenderer = function ( parameters ) { spotAnglesCos[ spotLength ] = Math.cos( light.angle ); spotExponents[ spotLength ] = light.exponent; + spotDecays[ spotLength ] = ( light.distance === 0 ) ? 0.0 : light.decay; spotLength += 1; diff --git a/build/three.min.js b/build/three.min.js index e7884961f155f7..6a4e978ba170e5 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -100,8 +100,8 @@ e,n=c*h,p=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=k+n*d;b[5]=a-p*d;b[9]=-c*g;b[2]=p-a "YZX"===a.order?(a=f*g,k=f*d,n=c*g,p=c*d,b[0]=g*h,b[4]=p-a*e,b[8]=n*e+k,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=k*e+n,b[10]=a-p*e):"XZY"===a.order&&(a=f*g,k=f*d,n=c*g,p=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+p,b[5]=f*h,b[9]=k*e-n,b[2]=n*e-k,b[6]=c*h,b[10]=p*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},setRotationFromQuaternion:function(a){console.warn("THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().");return this.makeRotationFromQuaternion(a)}, makeRotationFromQuaternion:function(a){var b=this.elements,c=a.x,d=a.y,e=a.z,f=a.w,g=c+c,h=d+d,k=e+e;a=c*g;var n=c*h,c=c*k,p=d*h,d=d*k,e=e*k,g=f*g,h=f*h,f=f*k;b[0]=1-(p+e);b[4]=n-f;b[8]=c+h;b[1]=n+f;b[5]=1-(a+e);b[9]=d-g;b[2]=c-h;b[6]=d+g;b[10]=1-(a+p);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},lookAt:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,f){var g=this.elements;c.subVectors(d,e).normalize();0===c.length()&&(c.z=1);a.crossVectors(f, c).normalize();0===a.length()&&(c.x+=1E-4,a.crossVectors(f,c).normalize());b.crossVectors(c,a);g[0]=a.x;g[4]=b.x;g[8]=c.x;g[1]=a.y;g[5]=b.y;g[9]=c.y;g[2]=a.z;g[6]=b.z;g[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements,e=this.elements,f=c[0],g=c[4],h=c[8], -k=c[12],n=c[1],p=c[5],q=c[9],m=c[13],t=c[2],s=c[6],r=c[10],u=c[14],v=c[3],y=c[7],C=c[11],c=c[15],x=d[0],F=d[4],z=d[8],G=d[12],E=d[1],w=d[5],D=d[9],A=d[13],U=d[2],M=d[6],K=d[10],L=d[14],N=d[3],S=d[7],P=d[11],d=d[15];e[0]=f*x+g*E+h*U+k*N;e[4]=f*F+g*w+h*M+k*S;e[8]=f*z+g*D+h*K+k*P;e[12]=f*G+g*A+h*L+k*d;e[1]=n*x+p*E+q*U+m*N;e[5]=n*F+p*w+q*M+m*S;e[9]=n*z+p*D+q*K+m*P;e[13]=n*G+p*A+q*L+m*d;e[2]=t*x+s*E+r*U+u*N;e[6]=t*F+s*w+r*M+u*S;e[10]=t*z+s*D+r*K+u*P;e[14]=t*G+s*A+r*L+u*d;e[3]=v*x+y*E+C*U+c*N;e[7]=v*F+ -y*w+C*M+c*S;e[11]=v*z+y*D+C*K+c*P;e[15]=v*G+y*A+C*L+c*d;return this},multiplyToArray:function(a,b,c){var d=this.elements;this.multiplyMatrices(a,b);c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[5]=d[5];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[11]=d[11];c[12]=d[12];c[13]=d[13];c[14]=d[14];c[15]=d[15];return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*= +k=c[12],n=c[1],p=c[5],q=c[9],m=c[13],t=c[2],s=c[6],r=c[10],u=c[14],v=c[3],y=c[7],C=c[11],c=c[15],x=d[0],F=d[4],z=d[8],G=d[12],E=d[1],w=d[5],D=d[9],A=d[13],T=d[2],M=d[6],K=d[10],L=d[14],N=d[3],S=d[7],Q=d[11],d=d[15];e[0]=f*x+g*E+h*T+k*N;e[4]=f*F+g*w+h*M+k*S;e[8]=f*z+g*D+h*K+k*Q;e[12]=f*G+g*A+h*L+k*d;e[1]=n*x+p*E+q*T+m*N;e[5]=n*F+p*w+q*M+m*S;e[9]=n*z+p*D+q*K+m*Q;e[13]=n*G+p*A+q*L+m*d;e[2]=t*x+s*E+r*T+u*N;e[6]=t*F+s*w+r*M+u*S;e[10]=t*z+s*D+r*K+u*Q;e[14]=t*G+s*A+r*L+u*d;e[3]=v*x+y*E+C*T+c*N;e[7]=v*F+ +y*w+C*M+c*S;e[11]=v*z+y*D+C*K+c*Q;e[15]=v*G+y*A+C*L+c*d;return this},multiplyToArray:function(a,b,c){var d=this.elements;this.multiplyMatrices(a,b);c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[5]=d[5];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[11]=d[11];c[12]=d[12];c[13]=d[13];c[14]=d[14];c[15]=d[15];return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*= a;b[15]*=a;return this},multiplyVector3:function(a){console.warn("THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.");return a.applyProjection(this)},multiplyVector4:function(a){console.warn("THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)},multiplyVector3Array:function(a){console.warn("THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead."); return this.applyToVector3Array(a)},applyToVector3Array:function(){var a=new THREE.Vector3;return function(b,c,d){void 0===c&&(c=0);void 0===d&&(d=b.length);for(var e=0;eya?-1:1;h[4*a]=ga.x;h[4*a+1]=ga.y;h[4*a+2]=ga.z;h[4*a+3]=$a}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],n=[],p=0;pAa?-1:1;h[4*a]=ia.x;h[4*a+1]=ia.y;h[4*a+2]=ia.z;h[4*a+3]=Ua}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, +e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],n=[],p=0;pr;r++)s=a[3*c+r],-1==m[s]?(q[2*r]=s,q[2*r+1]=-1,p++):m[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),m[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;h 0.0 ) {\n\t return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent );\n\t}\n\treturn 1.0;\n}\n\n"; +THREE.ShaderChunk.alphatest_fragment="#ifdef ALPHATEST\n\n\tif ( gl_FragColor.a < ALPHATEST ) discard;\n\n#endif\n";THREE.ShaderChunk.lights_lambert_vertex="vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\tfloat dotProduct = dot( transformedNormal, dirVector );\n\tvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t#endif\n\n\t#endif\n\n\t#ifdef WRAP_AROUND\n\n\t\tvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\tdirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tdirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n\t\t#endif\n\n\t#endif\n\n\tvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n\t#endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\tpointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tpointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\tvLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n\t\t#endif\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\t\tlVector = normalize( lVector );\n\n\t\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\t\t\tvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\t\tvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\t\tspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n\t\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\t\tspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\tvLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n\t\t\t#endif\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\t\tfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n\t\tvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n\t\t#endif\n\n\t}\n\n#endif\n\nvLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive;\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive;\n\n#endif\n"; THREE.ShaderChunk.map_particle_pars_fragment="#ifdef USE_MAP\n\n\tuniform sampler2D map;\n\n#endif";THREE.ShaderChunk.default_vertex="#ifdef USE_SKINNING\n\n\tvec4 mvPosition = modelViewMatrix * skinned;\n\n#elif defined( USE_MORPHTARGETS )\n\n\tvec4 mvPosition = modelViewMatrix * vec4( morphed, 1.0 );\n\n#else\n\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\n#endif\n\ngl_Position = projectionMatrix * mvPosition;\n";THREE.ShaderChunk.map_pars_fragment="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\n#endif\n\n#ifdef USE_MAP\n\n\tuniform sampler2D map;\n\n#endif"; THREE.ShaderChunk.skinnormal_vertex="#ifdef USE_SKINNING\n\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\n\t#ifdef USE_MORPHNORMALS\n\n\tvec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );\n\n\t#else\n\n\tvec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );\n\n\t#endif\n\n#endif\n"; -THREE.ShaderChunk.logdepthbuf_pars_vertex="#ifdef USE_LOGDEPTHBUF\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n\tuniform float logDepthBufFC;\n\n#endif";THREE.ShaderChunk.lightmap_pars_vertex="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\n#endif";THREE.ShaderChunk.lights_phong_fragment="vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef DOUBLE_SIDED\n\n\tnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n#endif\n\n#ifdef USE_NORMALMAP\n\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tvec3 pointDiffuse = vec3( 0.0 );\n\tvec3 pointSpecular = vec3( 0.0 );\n\n\tfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat lDistance = 1.0;\n\t\tif ( pointLightDistance[ i ] > 0.0 )\n\t\t\tlDistance = saturate( 1.0 - ( length( lVector ) / pointLightDistance[ i ] ) );\n\n\t\tlVector = normalize( lVector );\n\n\t\t\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\tpointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;\n\n\t\t\t\t// specular\n\n\t\tvec3 pointHalfVector = normalize( lVector + viewPosition );\n\t\tfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n\t\tfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n\t\tpointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tvec3 spotDiffuse = vec3( 0.0 );\n\tvec3 spotSpecular = vec3( 0.0 );\n\n\tfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat lDistance = 1.0;\n\t\tif ( spotLightDistance[ i ] > 0.0 )\n\t\t\tlDistance = saturate( 1.0 - ( length( lVector ) / spotLightDistance[ i ] ) );\n\n\t\tlVector = normalize( lVector );\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\t\t\t// diffuse\n\n\t\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\t\tfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\t\tvec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n\t\t\t#else\n\n\t\t\t\tfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t\t#endif\n\n\t\t\tspotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;\n\n\t\t\t\t\t// specular\n\n\t\t\tvec3 spotHalfVector = normalize( lVector + viewPosition );\n\t\t\tfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n\t\t\tfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n\t\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n\t\t\tspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n\tvec3 dirDiffuse = vec3( 0.0 );\n\tvec3 dirSpecular = vec3( 0.0 );\n\n\tfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\t\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\t\t\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, dirVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\tdirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n\t\t// specular\n\n\t\tvec3 dirHalfVector = normalize( dirVector + viewPosition );\n\t\tfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n\t\tfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n\t\t/*\n\t\t// fresnel term from skin shader\n\t\tconst float F0 = 0.128;\n\n\t\tfloat base = 1.0 - dot( viewPosition, dirHalfVector );\n\t\tfloat exponential = pow( base, 5.0 );\n\n\t\tfloat fresnel = exponential + F0 * ( 1.0 - exponential );\n\t\t*/\n\n\t\t/*\n\t\t// fresnel term from fresnel shader\n\t\tconst float mFresnelBias = 0.08;\n\t\tconst float mFresnelScale = 0.3;\n\t\tconst float mFresnelPower = 5.0;\n\n\t\tfloat fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n\t\t*/\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t// \t\tdirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n\t\tdirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tvec3 hemiDiffuse = vec3( 0.0 );\n\tvec3 hemiSpecular = vec3( 0.0 );\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n\t\tvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\themiDiffuse += diffuse * hemiColor;\n\n\t\t// specular (sky light)\n\n\t\tvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n\t\tfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n\t\tfloat hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n\t\t// specular (ground light)\n\n\t\tvec3 lVectorGround = -lVector;\n\n\t\tvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n\t\tfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n\t\tfloat hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n\t\tfloat dotProductGround = dot( normal, lVectorGround );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n\t\tvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n\t\themiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n\t}\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n\ttotalDiffuse += dirDiffuse;\n\ttotalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\ttotalDiffuse += hemiDiffuse;\n\ttotalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\ttotalDiffuse += pointDiffuse;\n\ttotalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\ttotalDiffuse += spotDiffuse;\n\ttotalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif"; +THREE.ShaderChunk.logdepthbuf_pars_vertex="#ifdef USE_LOGDEPTHBUF\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n\tuniform float logDepthBufFC;\n\n#endif";THREE.ShaderChunk.lightmap_pars_vertex="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\n#endif";THREE.ShaderChunk.lights_phong_fragment="vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef DOUBLE_SIDED\n\n\tnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n#endif\n\n#ifdef USE_NORMALMAP\n\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tvec3 pointDiffuse = vec3( 0.0 );\n\tvec3 pointSpecular = vec3( 0.0 );\n\n\tfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\t\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\tpointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n\t\t\t\t// specular\n\n\t\tvec3 pointHalfVector = normalize( lVector + viewPosition );\n\t\tfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n\t\tfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n\t\tpointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tvec3 spotDiffuse = vec3( 0.0 );\n\tvec3 spotSpecular = vec3( 0.0 );\n\n\tfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\t\t\t// diffuse\n\n\t\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\t\tfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\t\tvec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n\t\t\t#else\n\n\t\t\t\tfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t\t#endif\n\n\t\t\tspotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n\t\t\t\t\t// specular\n\n\t\t\tvec3 spotHalfVector = normalize( lVector + viewPosition );\n\t\t\tfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n\t\t\tfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n\t\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n\t\t\tspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n\tvec3 dirDiffuse = vec3( 0.0 );\n\tvec3 dirSpecular = vec3( 0.0 );\n\n\tfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\t\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\t\t\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, dirVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\tdirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n\t\t// specular\n\n\t\tvec3 dirHalfVector = normalize( dirVector + viewPosition );\n\t\tfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n\t\tfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n\t\t/*\n\t\t// fresnel term from skin shader\n\t\tconst float F0 = 0.128;\n\n\t\tfloat base = 1.0 - dot( viewPosition, dirHalfVector );\n\t\tfloat exponential = pow( base, 5.0 );\n\n\t\tfloat fresnel = exponential + F0 * ( 1.0 - exponential );\n\t\t*/\n\n\t\t/*\n\t\t// fresnel term from fresnel shader\n\t\tconst float mFresnelBias = 0.08;\n\t\tconst float mFresnelScale = 0.3;\n\t\tconst float mFresnelPower = 5.0;\n\n\t\tfloat fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n\t\t*/\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t// \t\tdirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n\t\tdirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tvec3 hemiDiffuse = vec3( 0.0 );\n\tvec3 hemiSpecular = vec3( 0.0 );\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n\t\tvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\themiDiffuse += diffuse * hemiColor;\n\n\t\t// specular (sky light)\n\n\t\tvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n\t\tfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n\t\tfloat hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n\t\t// specular (ground light)\n\n\t\tvec3 lVectorGround = -lVector;\n\n\t\tvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n\t\tfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n\t\tfloat hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n\t\tfloat dotProductGround = dot( normal, lVectorGround );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n\t\tvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n\t\themiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n\t}\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n\ttotalDiffuse += dirDiffuse;\n\ttotalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\ttotalDiffuse += hemiDiffuse;\n\ttotalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\ttotalDiffuse += pointDiffuse;\n\ttotalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\ttotalDiffuse += spotDiffuse;\n\ttotalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif\n"; THREE.ShaderChunk.fog_pars_fragment="#ifdef USE_FOG\n\n\tuniform vec3 fogColor;\n\n\t#ifdef FOG_EXP2\n\n\t\tuniform float fogDensity;\n\n\t#else\n\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n\n#endif";THREE.ShaderChunk.morphnormal_vertex="#ifdef USE_MORPHNORMALS\n\n\tvec3 morphedNormal = vec3( 0.0 );\n\n\tmorphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tmorphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tmorphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tmorphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n\n\tmorphedNormal += normal;\n\n#endif"; THREE.ShaderChunk.envmap_pars_fragment="#ifdef USE_ENVMAP\n\n\tuniform float reflectivity;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tuniform float refractionRatio;\n\n\t#else\n\n\t\tvarying vec3 vReflect;\n\n\t#endif\n\n#endif\n";THREE.ShaderChunk.logdepthbuf_fragment="#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n\n#endif"; THREE.ShaderChunk.normalmap_pars_fragment="#ifdef USE_NORMALMAP\n\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\n\t\t\t// Per-Pixel Tangent Space Normal Mapping\n\t\t\t// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html\n\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\n\t}\n\n#endif\n"; THREE.ShaderChunk.lights_phong_pars_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvarying vec3 vWorldPosition;\n\n#endif\n";THREE.ShaderChunk.lightmap_pars_fragment="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\tuniform sampler2D lightMap;\n\n#endif";THREE.ShaderChunk.shadowmap_vertex="#ifdef USE_SHADOWMAP\n\n\tfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n\t\tvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n\n\t}\n\n#endif"; THREE.ShaderChunk.lights_phong_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvWorldPosition = worldPosition.xyz;\n\n#endif";THREE.ShaderChunk.map_fragment="#ifdef USE_MAP\n\n\tvec4 texelColor = texture2D( map, vUv );\n\n\t#ifdef GAMMA_INPUT\n\n\t\ttexelColor.xyz *= texelColor.xyz;\n\n\t#endif\n\n\tgl_FragColor = gl_FragColor * texelColor;\n\n#endif";THREE.ShaderChunk.lightmap_vertex="#ifdef USE_LIGHTMAP\n\n\tvUv2 = uv2;\n\n#endif"; THREE.ShaderChunk.map_particle_fragment="#ifdef USE_MAP\n\n\tgl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );\n\n#endif";THREE.ShaderChunk.color_pars_fragment="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif\n";THREE.ShaderChunk.color_vertex="#ifdef USE_COLOR\n\n\t#ifdef GAMMA_INPUT\n\n\t\tvColor = square( color );\n\n\t#else\n\n\t\tvColor = color;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.skinning_vertex="#ifdef USE_SKINNING\n\n\t#ifdef USE_MORPHTARGETS\n\n\tvec4 skinVertex = bindMatrix * vec4( morphed, 1.0 );\n\n\t#else\n\n\tvec4 skinVertex = bindMatrix * vec4( position, 1.0 );\n\n\t#endif\n\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\tskinned = bindMatrixInverse * skinned;\n\n#endif\n"; -THREE.ShaderChunk.envmap_pars_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvarying vec3 vReflect;\n\n\tuniform float refractionRatio;\n\n#endif\n";THREE.ShaderChunk.linear_to_gamma_fragment="#ifdef GAMMA_OUTPUT\n\n\tgl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n\n#endif";THREE.ShaderChunk.color_pars_vertex="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif";THREE.ShaderChunk.lights_lambert_pars_vertex="uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n"; +THREE.ShaderChunk.envmap_pars_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvarying vec3 vReflect;\n\n\tuniform float refractionRatio;\n\n#endif\n";THREE.ShaderChunk.linear_to_gamma_fragment="#ifdef GAMMA_OUTPUT\n\n\tgl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n\n#endif";THREE.ShaderChunk.color_pars_vertex="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif";THREE.ShaderChunk.lights_lambert_pars_vertex="uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n"; THREE.ShaderChunk.map_pars_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n\n#endif\n";THREE.ShaderChunk.envmap_fragment="#ifdef USE_ENVMAP\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n\t\t// Transforming Normal Vectors with the Inverse Transformation\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n\t\t#else\n\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t\t#endif\n\n\t#else\n\n\t\tvec3 reflectVec = vReflect;\n\n\t#endif\n\n\t#ifdef DOUBLE_SIDED\n\t\tfloat flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\t#else\n\t\tfloat flipNormal = 1.0;\n\t#endif\n\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t\t\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#endif\n\n\t#ifdef GAMMA_INPUT\n\n\t\tenvColor.xyz *= envColor.xyz;\n\n\t#endif\n\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\n\t\tgl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\n\t\tgl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\n\t\tgl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;\n\n\t#endif\n\n#endif\n"; THREE.ShaderChunk.specularmap_pars_fragment="#ifdef USE_SPECULARMAP\n\n\tuniform sampler2D specularMap;\n\n#endif";THREE.ShaderChunk.logdepthbuf_vertex="#ifdef USE_LOGDEPTHBUF\n\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\n#else\n\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.morphtarget_pars_vertex="#ifdef USE_MORPHTARGETS\n\n\t#ifndef USE_MORPHNORMALS\n\n\tuniform float morphTargetInfluences[ 8 ];\n\n\t#else\n\n\tuniform float morphTargetInfluences[ 4 ];\n\n\t#endif\n\n#endif"; THREE.ShaderChunk.specularmap_fragment="float specularStrength;\n\n#ifdef USE_SPECULARMAP\n\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n\n#else\n\n\tspecularStrength = 1.0;\n\n#endif";THREE.ShaderChunk.fog_fragment="#ifdef USE_FOG\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\n\t#else\n\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\n\t#endif\n\n\t#ifdef FOG_EXP2\n\n\t\tfloat fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 );\n\t\tfogFactor = whiteCompliment( fogFactor );\n\n\t#else\n\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n\n\t#endif\n\t\n\tgl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n\n#endif"; THREE.ShaderChunk.bumpmap_pars_fragment="#ifdef USE_BUMPMAP\n\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\n\t\t\t// Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen\n\t\t\t//\thttp://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html\n\n\t\t\t// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)\n\n\tvec2 dHdxy_fwd() {\n\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\n\t\treturn vec2( dBx, dBy );\n\n\t}\n\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\n\t\tvec3 vSigmaX = dFdx( surf_pos );\n\t\tvec3 vSigmaY = dFdy( surf_pos );\n\t\tvec3 vN = surf_norm;\t\t// normalized\n\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\n\t}\n\n#endif"; -THREE.ShaderChunk.defaultnormal_vertex="#ifdef USE_SKINNING\n\n\tvec3 objectNormal = skinnedNormal.xyz;\n\n#elif defined( USE_MORPHNORMALS )\n\n\tvec3 objectNormal = morphedNormal;\n\n#else\n\n\tvec3 objectNormal = normal;\n\n#endif\n\n#ifdef FLIP_SIDED\n\n\tobjectNormal = -objectNormal;\n\n#endif\n\nvec3 transformedNormal = normalMatrix * objectNormal;\n";THREE.ShaderChunk.lights_phong_pars_fragment="uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvarying vec3 vWorldPosition;\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;"; +THREE.ShaderChunk.defaultnormal_vertex="#ifdef USE_SKINNING\n\n\tvec3 objectNormal = skinnedNormal.xyz;\n\n#elif defined( USE_MORPHNORMALS )\n\n\tvec3 objectNormal = morphedNormal;\n\n#else\n\n\tvec3 objectNormal = normal;\n\n#endif\n\n#ifdef FLIP_SIDED\n\n\tobjectNormal = -objectNormal;\n\n#endif\n\nvec3 transformedNormal = normalMatrix * objectNormal;\n";THREE.ShaderChunk.lights_phong_pars_fragment="uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvarying vec3 vWorldPosition;\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;\n"; THREE.ShaderChunk.skinbase_vertex="#ifdef USE_SKINNING\n\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n\n#endif";THREE.ShaderChunk.map_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n\n#endif"; THREE.ShaderChunk.lightmap_fragment="#ifdef USE_LIGHTMAP\n\n\tgl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );\n\n#endif";THREE.ShaderChunk.shadowmap_pars_vertex="#ifdef USE_SHADOWMAP\n\n\tvarying vec4 vShadowCoord[ MAX_SHADOWS ];\n\tuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n\n#endif";THREE.ShaderChunk.color_fragment="#ifdef USE_COLOR\n\n\tgl_FragColor = gl_FragColor * vec4( vColor, 1.0 );\n\n#endif";THREE.ShaderChunk.morphtarget_vertex="#ifdef USE_MORPHTARGETS\n\n\tvec3 morphed = vec3( 0.0 );\n\tmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\tmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\tmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\tmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\n\t#ifndef USE_MORPHNORMALS\n\n\tmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\tmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\tmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\tmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\n\t#endif\n\n\tmorphed += position;\n\n#endif"; THREE.ShaderChunk.envmap_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvec3 worldNormal = transformDirection( objectNormal, modelMatrix );\n\n\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\n\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\n\t#else\n\n\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t#endif\n\n#endif\n"; @@ -405,8 +405,8 @@ THREE.ShaderChunk.logdepthbuf_pars_fragment="#ifdef USE_LOGDEPTHBUF\n\n\tuniform THREE.UniformsUtils={merge:function(a){for(var b={},c=0;ch&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(p={id:oc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:n},q[k]=p,r.push(p)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=r;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gh&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(p={id:nc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:n},q[k]=p,r.push(p)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=r;b.groupsNeedUpdate=!1}f=nb[b.id];g=0;for(d=f.length;gY;Y++)pa=P[Y],Pa[Va]=pa.x,Pa[Va+1]=pa.y,Pa[Va+2]=pa.z,Va+=3;else for(Y=0;3>Y;Y++)Pa[Va]=M.x,Pa[Va+1]=M.y,Pa[Va+2]=M.z,Va+=3;l.bindBuffer(l.ARRAY_BUFFER, -v.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Pa,z)}if(Ma&&Wa){w=0;for(F=V.length;wY;Y++)Da=O[Y],xb[mb]=Da.x,xb[mb+1]=Da.y,mb+=2;0Y;Y++)Aa=U[Y],ob[ya]=Aa.x,ob[ya+1]=Aa.y,ya+=2;0V;V++)ra=Q[V],fb[ib]=ra.x,fb[ib+1]=ra.y,fb[ib+2]=ra.z,ib+=3;else for(V=0;3>V;V++)fb[ib]=M.x,fb[ib+1]=M.y,fb[ib+2]=M.z,ib+=3;l.bindBuffer(l.ARRAY_BUFFER, +v.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,fb,z)}if(pb&&Ya){w=0;for(F=W.length;wV;V++)Fa=O[V],Ua[rb]=Fa.x,Ua[rb+1]=Fa.y,rb+=2;0V;V++)Ca=T[V],qa[Aa]=Ca.x,qa[Aa+1]=Ca.y,Aa+=2;0ua;ua++)ib[ua]=!I.autoScaleCubemaps||Gb||ba?ba?ka.image[ua].image:ka.image[ua]:M(ka.image[ua],Hc);var Rb=ib[0],Sb=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height),qb=S(ka.format),Tb=S(ka.type);U(l.TEXTURE_CUBE_MAP,ka,Sb);for(ua=0;6>ua;ua++)if(Gb)for(var zb,Hb=ib[ua].mipmaps,rb=0,Yb=Hb.length;rb=tc&&console.warn("WebGLRenderer: trying to use "+ -a+" texture units while this GPU supports only "+tc);Nb+=1;return a}function G(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function E(a,b,c,d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function w(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function D(a){a*=O;a!==uc&&(l.lineWidth(a),uc=a)}function A(a,b,c){vc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),vc=a);!a||wc===b&&xc===c|| -(l.polygonOffset(b,c),wc=b,xc=c)}function U(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,S(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,S(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,S(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,S(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+ -b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,N(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,N(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function K(a,b){l.bindRenderbuffer(l.RENDERBUFFER, -a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function L(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP, -a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function N(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?l.NEAREST:l.LINEAR}function S(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT; -if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1; -if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT;if(a===THREE.FloatType)return l.FLOAT;if(a===THREE.AlphaFormat)return l.ALPHA;if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA; -if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a===THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA; -if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE;b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT; -if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT; -if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var P=void 0!==a.canvas?a.canvas:document.createElement("canvas"),W=void 0!==a.context?a.context:null,O=1,ga=void 0!==a.precision?a.precision:"highp",ea=void 0!==a.alpha?a.alpha:!1,xa=void 0!==a.depth?a.depth:!0,H=void 0!==a.stencil?a.stencil:!0,$a=void 0!==a.antialias?a.antialias:!1,pa=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,ya=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer: -!1,X=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ta=new THREE.Color(0),Za=0,qa=[],Fa={},Ga=[],Ta=[],za=[],vb=[],gb=[];this.domElement=P;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps= -!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var I=this,Xa=[],Xb=null,jb=null,Ib=-1,Sa="",Jb=null,Nb=0,sb=-1,Yb=-1,Zb=-1,dc=-1,ec=-1,fc=-1,gc=-1,hc=-1,ic=-1,jc=-1,kc=-1,vc=null,wc=null,xc=null,uc=null,Ya=0,tb=0,kb=P.width,eb=P.height,yc=0,zc=0,ub=new Uint8Array(16),Ma=new Uint8Array(16),wb=new THREE.Frustum,Cb=new THREE.Matrix4;new THREE.Matrix4;var Da=new THREE.Vector3,ma=new THREE.Vector3,Pb=!0,rc={ambient:[0,0,0],directional:{length:0, -colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},l;try{var Ac={alpha:ea,depth:xa,stencil:H,antialias:$a,premultipliedAlpha:pa,preserveDrawingBuffer:ya};l=W||P.getContext("webgl",Ac)||P.getContext("experimental-webgl",Ac);if(null===l){if(null!==P.getContext("webgl"))throw"Error creating WebGL context with your selected attributes."; -throw"Error creating WebGL context.";}P.addEventListener("webglcontextlost",function(a){a.preventDefault();Bc();Cc();Fa={}},!1)}catch(Ic){console.error(Ic)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_standard_derivatives");X&&aa.get("EXT_frag_depth");var lc=function(a,b,c,d){!0===pa&&(a*=d,b*=d,c*=d);l.clearColor(a, -b,c,d)},Cc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND);l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(Ya,tb,kb,eb);lc(ta.r,ta.g,ta.b,Za)},Bc=function(){Jb=Xb=null;Yb=sb=kc=jc=Zb=-1;Sa="";Ib=-1;Pb=!0;for(var a=0;ab;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}I.info.memory.textures--},qc=function(a){a=a.target;a.removeEventListener("dispose",qc);pc(a)},Ec=function(a){for(var b= -"__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;cd.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r= -d.numSupportedMorphTargets;mg;g++){a.__webglFramebuffer[g]= -l.createFramebuffer();a.__webglRenderbuffer[g]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+g,0,d,a.width,a.height,0,d,e,null);var f=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+g;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[g]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,f.__webglTexture,0);K(a.__webglRenderbuffer[g],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: -l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),U(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER, -l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):K(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=kb,a=eb,d=Ya,e=tb);b!==jb&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),jb=b);yc=c;zc=a};this.readRenderTargetPixels= -function(a,b,c,d,e,g){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var f=!1;a.__webglFramebuffer!==jb&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),f=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== -l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,g):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");f&&l.bindFramebuffer(l.FRAMEBUFFER,jb)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; -this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +wrapAround:d.wrapAround,doubleSided:d.side===THREE.DoubleSide,flipSided:d.side===THREE.BackSide},N=[];m?N.push(m):(N.push(d.fragmentShader),N.push(d.vertexShader));if(void 0!==d.defines)for(var O in d.defines)N.push(O),N.push(d.defines[O]);for(O in K)N.push(O),N.push(K[O]);for(var U=N.join(),sa,ua=0,bb=Za.length;uawa;wa++)tb[wa]=!I.autoScaleCubemaps||Db||Kb?Kb?ma.image[wa].image:ma.image[wa]:M(ma.image[wa],Gc);var Rb=tb[0],Sb=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height),ub=S(ma.format),Cb=S(ma.type);T(l.TEXTURE_CUBE_MAP, +ma,Sb);for(wa=0;6>wa;wa++)if(Db)for(var kb,Vb=tb[wa].mipmaps,Eb=0,ac=Vb.length;Eb=sc&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Nb+=1;return a}function G(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function E(a,b,c,d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function w(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function D(a){a*= +O;a!==tc&&(l.lineWidth(a),tc=a)}function A(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function T(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,S(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,S(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,S(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,S(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE), +b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,N(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,N(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+ +b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height); +console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function K(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, +l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function L(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function N(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? +l.NEAREST:l.LINEAR}function S(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a=== +THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT; +if(a===THREE.FloatType)return l.FLOAT;if(a===THREE.AlphaFormat)return l.ALPHA;if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a=== +THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE; +b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; +if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var Q=void 0!==a.canvas?a.canvas:document.createElement("canvas"),U=void 0!==a.context?a.context:null,O=1,ia=void 0!==a.precision?a.precision:"highp", +ga=void 0!==a.alpha?a.alpha:!1,za=void 0!==a.depth?a.depth:!0,H=void 0!==a.stencil?a.stencil:!0,Ua=void 0!==a.antialias?a.antialias:!1,ra=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,Aa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,X=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ua=new THREE.Color(0),bb=0,sa=[],Ja={},Ka=[],Va=[],Ba=[],wb=[],hb=[];this.domElement=Q;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor= +this.autoClear=!0;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var I=this,Za=[],$b=null,$a=null,Fb=-1,qa="",Gb=null,Nb=0,vb=-1,Qb=-1,Rb=-1,Sb=-1,ac=-1,ec=-1,fc=-1,gc=-1,hc=-1,ic=-1,jc=-1,uc= +null,vc=null,wc=null,tc=null,yb=0,lb=0,ab=Q.width,gb=Q.height,xc=0,yc=0,mb=new Uint8Array(16),Pa=new Uint8Array(16),qb=new THREE.Frustum,zb=new THREE.Matrix4;new THREE.Matrix4;var Fa=new THREE.Vector3,na=new THREE.Vector3,Pb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[], +positions:[]}},l;try{var zc={alpha:ga,depth:za,stencil:H,antialias:Ua,premultipliedAlpha:ra,preserveDrawingBuffer:Aa};l=U||Q.getContext("webgl",zc)||Q.getContext("experimental-webgl",zc);if(null===l){if(null!==Q.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}Q.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();Ja={}},!1)}catch(Hc){console.error(Hc)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat= +function(){return{rangeMin:1,rangeMax:1,precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_standard_derivatives");X&&aa.get("EXT_frag_depth");var kc=function(a,b,c,d){!0===ra&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND);l.blendEquation(l.FUNC_ADD); +l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(yb,lb,ab,gb);kc(ua.r,ua.g,ua.b,bb)},Ac=function(){Gb=$b=null;Qb=vb=jc=ic=Rb=-1;qa="";Fb=-1;Pb=!0;for(var a=0;a +b;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}I.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), +c=0,d=b.length;cd.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+ +f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);K(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),T(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D, +0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):K(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D); +b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=ab,a=gb,d=yb,e=lb);b!==$a&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),$a=b);xc=c;yc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); +else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==$a&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)===l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."); +g&&l.bindFramebuffer(l.FRAMEBUFFER,$a)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; @@ -586,36 +586,36 @@ b=["precision "+e.precision+" float;","precision "+e.precision+" int;",e.bumpMap e.useVertexTexture?(q.push("boneTexture"),q.push("boneTextureWidth"),q.push("boneTextureHeight")):q.push("boneGlobalMatrices");e.logarithmicDepthBuffer&&q.push("logDepthBufFC");for(var C in h)q.push(C);h=q;C={};q=0;for(b=h.length;qL;L++)A[L]=new THREE.Vector3,w[L]=new THREE.Vector3;A=D.shadowCascadeNearZ[K];D=D.shadowCascadeFarZ[K];w[0].set(-1,-1,A);w[1].set(1,-1,A);w[2].set(-1,1,A);w[3].set(1,1,A);w[4].set(-1,-1,D);w[5].set(1,-1,D);w[6].set(-1,1,D);w[7].set(1,1,D);M.originalCamera=v;w=new THREE.Gyroscope;w.position.copy(z.shadowCascadeOffset);w.add(M);w.add(M.target);v.add(w);z.shadowCascadeArray[E]=M;console.log("Created virtualLight",M)}K= -z;A=E;D=K.shadowCascadeArray[A];D.position.copy(K.position);D.target.position.copy(K.target.position);D.lookAt(D.target);D.shadowCameraVisible=K.shadowCameraVisible;D.shadowDarkness=K.shadowDarkness;D.shadowBias=K.shadowCascadeBias[A];w=K.shadowCascadeNearZ[A];K=K.shadowCascadeFarZ[A];D=D.pointsFrustum;D[0].z=w;D[1].z=w;D[2].z=w;D[3].z=w;D[4].z=K;D[5].z=K;D[6].z=K;D[7].z=K;U[G]=M;G++}else U[G]=z,G++;u=0;for(F=U.length;uK;K++)A=D[K],A.copy(w[K]),A.unproject(E),A.applyMatrix4(G.matrixWorldInverse),A.xt.x&&(t.x=A.x),A.yt.y&&(t.y=A.y),A.zt.z&&(t.z=A.z);G.left=m.x;G.right=t.x;G.top=t.y;G.bottom=m.y;G.updateProjectionMatrix()}G=z.shadowMap;w=z.shadowMatrix;E=z.shadowCamera;E.position.setFromMatrixPosition(z.matrixWorld);s.setFromMatrixPosition(z.target.matrixWorld);E.lookAt(s);E.updateMatrixWorld();E.matrixWorldInverse.getInverse(E.matrixWorld);z.cameraHelper&& (z.cameraHelper.visible=z.shadowCameraVisible);z.shadowCameraVisible&&z.cameraHelper.update();w.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);w.multiply(E.projectionMatrix);w.multiply(E.matrixWorldInverse);q.multiplyMatrices(E.projectionMatrix,E.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(G);a.clear();r.length=0;e(c,c,E);z=0;for(G=r.length;z 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); x.compileShader(L);x.compileShader(N);x.attachShader(K,L);x.attachShader(K,N);x.linkProgram(K);G=K;v=x.getAttribLocation(G,"position");y=x.getAttribLocation(G,"uv");c=x.getUniformLocation(G,"uvOffset");d=x.getUniformLocation(G,"uvScale");e=x.getUniformLocation(G,"rotation");f=x.getUniformLocation(G,"scale");g=x.getUniformLocation(G,"color");h=x.getUniformLocation(G,"map");k=x.getUniformLocation(G,"opacity");n=x.getUniformLocation(G,"modelViewMatrix");p=x.getUniformLocation(G,"projectionMatrix");q= x.getUniformLocation(G,"fogType");m=x.getUniformLocation(G,"fogDensity");t=x.getUniformLocation(G,"fogNear");s=x.getUniformLocation(G,"fogFar");r=x.getUniformLocation(G,"fogColor");u=x.getUniformLocation(G,"alphaTest");K=document.createElement("canvas");K.width=8;K.height=8;L=K.getContext("2d");L.fillStyle="white";L.fillRect(0,0,8,8);E=new THREE.Texture(K);E.needsUpdate=!0}x.useProgram(G);x.enableVertexAttribArray(v);x.enableVertexAttribArray(y);x.disable(x.CULL_FACE);x.enable(x.BLEND);x.bindBuffer(x.ARRAY_BUFFER, -F);x.vertexAttribPointer(v,2,x.FLOAT,!1,16,0);x.vertexAttribPointer(y,2,x.FLOAT,!1,16,8);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,z);x.uniformMatrix4fv(p,!1,M.projectionMatrix.elements);x.activeTexture(x.TEXTURE0);x.uniform1i(h,0);L=K=0;(N=U.fog)?(x.uniform3f(r,N.color.r,N.color.g,N.color.b),N instanceof THREE.Fog?(x.uniform1f(t,N.near),x.uniform1f(s,N.far),x.uniform1i(q,1),L=K=1):N instanceof THREE.FogExp2&&(x.uniform1f(m,N.density),x.uniform1i(q,2),L=K=2)):(x.uniform1i(q,0),L=K=0);for(var N=0,S=b.length;N< -S;N++){var P=b[N];P._modelViewMatrix.multiplyMatrices(M.matrixWorldInverse,P.matrixWorld);P.z=-P._modelViewMatrix.elements[14]}b.sort(C);for(var W=[],N=0,S=b.length;Ne)return null;var f=[],g=[],h=[],k,n,p;if(0=q--){console.log("Warning, unable to triangulate polygon!");break}k=n;e<=k&&(k=0);n=k+1;e<=n&&(n=0);p=n+1;e<=p&&(p=0);var m;a:{var t=m=void 0,s=void 0,r=void 0,u=void 0,v=void 0,y=void 0,C=void 0,x=void 0, -t=a[g[k]].x,s=a[g[k]].y,r=a[g[n]].x,u=a[g[n]].y,v=a[g[p]].x,y=a[g[p]].y;if(1E-10>(r-t)*(y-s)-(u-s)*(v-t))m=!1;else{var F=void 0,z=void 0,G=void 0,E=void 0,w=void 0,D=void 0,A=void 0,U=void 0,M=void 0,K=void 0,M=U=A=x=C=void 0,F=v-r,z=y-u,G=t-v,E=s-y,w=r-t,D=u-s;for(m=0;m(r-t)*(y-s)-(u-s)*(v-t))m=!1;else{var F=void 0,z=void 0,G=void 0,E=void 0,w=void 0,D=void 0,A=void 0,T=void 0,M=void 0,K=void 0,M=T=A=x=C=void 0,F=v-r,z=y-u,G=t-v,E=s-y,w=r-t,D=u-s;for(m=0;mMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; -THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cm&&(f=b[g],k=-k,h=b[e],m=-m),!(a.yh.y))if(a.y==f.y){if(a.x==f.x)return!0}else{e=m*(a.x-f.x)-k*(a.y-f.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==f.y&&(h.x<=a.x&&a.x<=f.x||f.x<=a.x&&a.x<= +THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cm&&(g=b[f],k=-k,h=b[e],m=-m),!(a.yh.y))if(a.y==g.y){if(a.x==g.x)return!0}else{e=m*(a.x-g.x)-k*(a.y-g.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<= h.x))return!0}return d}var e=function(a){var b,c,d,e,f=[],g=new THREE.Path;b=0;for(c=a.length;bE||E>G)return[];k=n*p-k*q;if(0>k||k>G)return[]}else{if(0d?[]:k==d?g?[]:[f]:a<=d?[f,h]: [f,n]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]);if(!d)return!1; -d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;cK){console.log("Infinite Loop! Holes left:"+ -n.length+", Probably Hole outside Shape!");break}for(q=D;qh;h++)n=k[h].x+":"+k[h].y, +d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;cK){console.log("Infinite Loop! Holes left:"+ +n.length+", Probably Hole outside Shape!");break}for(q=D;qh;h++)n=k[h].x+":"+k[h].y, n=p[n],void 0!==n&&(k[h]=n);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a, b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)};THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()}; THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve;THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b=new THREE.Vector2;b.x=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);return b}; @@ -723,13 +723,13 @@ C=h.clone(),x=h.clone(),F=m[p][n].clone(),z=m[p+1][n].clone(),G=m[p+1][n+1].clon z,G]);this.computeFaceNormals()};THREE.CylinderGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CylinderGeometry.prototype.constructor=THREE.CylinderGeometry;THREE.ExtrudeGeometry=function(a,b){"undefined"!==typeof a&&(THREE.Geometry.call(this),this.type="ExtrudeGeometry",a=a instanceof Array?a:[a],this.addShapeList(a,b),this.computeFaceNormals())};THREE.ExtrudeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ExtrudeGeometry.prototype.constructor=THREE.ExtrudeGeometry; THREE.ExtrudeGeometry.prototype.addShapeList=function(a,b){for(var c=a.length,d=0;d=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)== -Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(H=a.length;0<=--H;){c=H;d=H-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;ed&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;c Date: Sat, 24 Jan 2015 20:50:19 +0100 Subject: [PATCH 047/333] Editor: Added decay support. --- editor/js/Sidebar.Object3D.js | 29 ++++++++++++++++++++++++++--- src/loaders/ObjectLoader.js | 4 ++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/editor/js/Sidebar.Object3D.js b/editor/js/Sidebar.Object3D.js index d6f205f71fbb84..c82348a6b642f7 100644 --- a/editor/js/Sidebar.Object3D.js +++ b/editor/js/Sidebar.Object3D.js @@ -48,14 +48,14 @@ Sidebar.Object3D = function ( editor ) { break; } - + this.setValue( 'Actions' ); signals.objectChanged.dispatch( object ); } ); container.addStatic( objectActions ); - + container.add( new UI.Break() ); // uuid @@ -228,6 +228,16 @@ Sidebar.Object3D = function ( editor ) { container.add( objectExponentRow ); + // decay + + var objectDecayRow = new UI.Panel(); + var objectDecay = new UI.Number().setRange( 0, Infinity ).onChange( update ); + + objectDecayRow.add( new UI.Text( 'Decay' ).setWidth( '90px' ) ); + objectDecayRow.add( objectDecay ); + + container.add( objectDecayRow ); + // visible var objectVisibleRow = new UI.Panel(); @@ -406,6 +416,12 @@ Sidebar.Object3D = function ( editor ) { } + if ( object.decay !== undefined ) { + + object.decay = objectDecay.getValue(); + + } + object.visible = objectVisible.getValue(); try { @@ -436,7 +452,8 @@ Sidebar.Object3D = function ( editor ) { 'groundColor': objectGroundColorRow, 'distance' : objectDistanceRow, 'angle' : objectAngleRow, - 'exponent' : objectExponentRow + 'exponent' : objectExponentRow, + 'decay' : objectDecayRow }; for ( var property in properties ) { @@ -585,6 +602,12 @@ Sidebar.Object3D = function ( editor ) { } + if ( object.decay !== undefined ) { + + objectDecay.setValue( object.decay ); + + } + objectVisible.setValue( object.visible ); try { diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 741dd72575baca..b7794c426e2cfd 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -251,13 +251,13 @@ THREE.ObjectLoader.prototype = { case 'PointLight': - object = new THREE.PointLight( data.color, data.intensity, data.distance ); + object = new THREE.PointLight( data.color, data.intensity, data.distance, data.decay ); break; case 'SpotLight': - object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent ); + object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent, data.decay ); break; From 6ccd8f2b09d8770e35a59f61b40ca0066c36f33f Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 24 Jan 2015 20:50:35 +0100 Subject: [PATCH 048/333] Updated builds. --- build/three.js | 4 ++-- build/three.min.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/three.js b/build/three.js index 088e7f1051a8ae..8e8322d76cd91e 100644 --- a/build/three.js +++ b/build/three.js @@ -12795,13 +12795,13 @@ THREE.ObjectLoader.prototype = { case 'PointLight': - object = new THREE.PointLight( data.color, data.intensity, data.distance ); + object = new THREE.PointLight( data.color, data.intensity, data.distance, data.decay ); break; case 'SpotLight': - object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent ); + object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent, data.decay ); break; diff --git a/build/three.min.js b/build/three.min.js index 6a4e978ba170e5..9b6136eb299905 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -281,7 +281,7 @@ THREE.ObjectLoader.prototype={constructor:THREE.ObjectLoader,load:function(a,b,c e=0,f=a.length;e Date: Sat, 24 Jan 2015 21:00:43 +0100 Subject: [PATCH 049/333] Improved example lighting. --- examples/webgl_loader_collada_kinematics.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/webgl_loader_collada_kinematics.html b/examples/webgl_loader_collada_kinematics.html index 81145f06e5249d..cdce4bbee0de23 100644 --- a/examples/webgl_loader_collada_kinematics.html +++ b/examples/webgl_loader_collada_kinematics.html @@ -120,9 +120,7 @@ // Lights - scene.add( new THREE.AmbientLight( 0xcccccc ) ); - - var directionalLight = new THREE.DirectionalLight( 0xeeeeee ); + var directionalLight = new THREE.HemisphereLight( 0xffeeee, 0x111122 ); directionalLight.position.x = Math.random() - 0.5; directionalLight.position.y = Math.random() - 0.5; directionalLight.position.z = Math.random() - 0.5; From 5395ea117681a764ba9fe543da9c9f30a78d7362 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 25 Jan 2015 00:44:05 +0300 Subject: [PATCH 050/333] User friendly file saving User friendly file saving --- editor/js/Menubar.File.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/editor/js/Menubar.File.js b/editor/js/Menubar.File.js index 2a4efe36e4396a..913096b4d5b614 100644 --- a/editor/js/Menubar.File.js +++ b/editor/js/Menubar.File.js @@ -89,7 +89,7 @@ Menubar.File = function ( editor ) { output = JSON.stringify( output, null, '\t' ); output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' ); - exportString( output ); + exportString( output, "geometry.json" ); } ); options.add( option ); @@ -114,7 +114,7 @@ Menubar.File = function ( editor ) { output = JSON.stringify( output, null, '\t' ); output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' ); - exportString( output ); + exportString( output, "model.json" ); } ); options.add( option ); @@ -130,7 +130,7 @@ Menubar.File = function ( editor ) { output = JSON.stringify( output, null, '\t' ); output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' ); - exportString( output ); + exportString( output, "scene.json" ); } ); options.add( option ); @@ -153,7 +153,7 @@ Menubar.File = function ( editor ) { var exporter = new THREE.OBJExporter(); - exportString( exporter.parse( object ) ); + exportString( exporter.parse( object ), "model.obj" ); } ); options.add( option ); @@ -167,7 +167,7 @@ Menubar.File = function ( editor ) { var exporter = new THREE.STLExporter(); - exportString( exporter.parse( editor.scene ) ); + exportString( exporter.parse( editor.scene ), "model.stl" ); } ); options.add( option ); @@ -274,13 +274,16 @@ Menubar.File = function ( editor ) { // - var exportString = function ( output ) { + var exportString = function ( output, filename ) { var blob = new Blob( [ output ], { type: 'text/plain' } ); var objectURL = URL.createObjectURL( blob ); - window.open( objectURL, '_blank' ); - window.focus(); + var link = document.createElement('a'); + link.href = objectURL; + link.download = filename || "data.json"; + link.target = "_blank"; + link.click(); }; From 4d35ea7f91b52d97f40e675d4042dfb13292dcdd Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 24 Jan 2015 23:05:46 +0100 Subject: [PATCH 051/333] Updated builds. --- build/three.js | 155 +++++------------- build/three.min.js | 393 ++++++++++++++++++++++----------------------- 2 files changed, 234 insertions(+), 314 deletions(-) diff --git a/build/three.js b/build/three.js index 8e8322d76cd91e..3a8bfa62b10b0c 100644 --- a/build/three.js +++ b/build/three.js @@ -402,21 +402,27 @@ THREE.Color.prototype = { }, - copyGammaToLinear: function ( color ) { + copyGammaToLinear: function ( color, gammaFactor ) { - this.r = color.r * color.r; - this.g = color.g * color.g; - this.b = color.b * color.b; + if ( gammaFactor === undefined ) gammaFactor = 2.0; + + this.r = Math.pow( color.r, gammaFactor ); + this.g = Math.pow( color.g, gammaFactor ); + this.b = Math.pow( color.b, gammaFactor ); return this; }, - copyLinearToGamma: function ( color ) { + copyLinearToGamma: function ( color, gammaFactor ) { + + if ( gammaFactor === undefined ) gammaFactor = 2.0; + + var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; - this.r = Math.sqrt( color.r ); - this.g = Math.sqrt( color.g ); - this.b = Math.sqrt( color.b ); + this.r = Math.pow( color.r, safeInverse ); + this.g = Math.pow( color.g, safeInverse ); + this.b = Math.pow( color.b, safeInverse ); return this; @@ -16321,7 +16327,7 @@ THREE.ShaderChunk = {}; // File:src/renderers/shaders/ShaderChunk/common.glsl -THREE.ShaderChunk[ 'common'] = "#define PI 3.14159\n#define PI2 6.28318\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n\nfloat square( in float a ) { return a*a; }\nvec2 square( in vec2 a ) { return vec2( a.x*a.x, a.y*a.y ); }\nvec3 square( in vec3 a ) { return vec3( a.x*a.x, a.y*a.y, a.z*a.z ); }\nvec4 square( in vec4 a ) { return vec4( a.x*a.x, a.y*a.y, a.z*a.z, a.w*a.w ); }\nfloat saturate( in float a ) { return clamp( a, 0.0, 1.0 ); }\nvec2 saturate( in vec2 a ) { return clamp( a, 0.0, 1.0 ); }\nvec3 saturate( in vec3 a ) { return clamp( a, 0.0, 1.0 ); }\nvec4 saturate( in vec4 a ) { return clamp( a, 0.0, 1.0 ); }\nfloat average( in float a ) { return a; }\nfloat average( in vec2 a ) { return ( a.x + a.y) * 0.5; }\nfloat average( in vec3 a ) { return ( a.x + a.y + a.z) / 3.0; }\nfloat average( in vec4 a ) { return ( a.x + a.y + a.z + a.w) * 0.25; }\nfloat whiteCompliment( in float a ) { return saturate( 1.0 - a ); }\nvec2 whiteCompliment( in vec2 a ) { return saturate( vec2(1.0) - a ); }\nvec3 whiteCompliment( in vec3 a ) { return saturate( vec3(1.0) - a ); }\nvec4 whiteCompliment( in vec4 a ) { return saturate( vec4(1.0) - a ); }\nvec3 transformDirection( in vec3 normal, in mat4 matrix ) {\n return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz );\n}\n// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations\nvec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {\n return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal) {\n float distance = dot( planeNormal, point-pointOnPlane );\n return point - distance * planeNormal;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) );\n}\nfloat calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {\n if ( decayExponent > 0.0 ) {\n return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent );\n }\n return 1.0;\n}\n\n"; +THREE.ShaderChunk[ 'common'] = "#define PI 3.14159\n#define PI2 6.28318\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n\nfloat square( in float a ) { return a*a; }\nvec2 square( in vec2 a ) { return vec2( a.x*a.x, a.y*a.y ); }\nvec3 square( in vec3 a ) { return vec3( a.x*a.x, a.y*a.y, a.z*a.z ); }\nvec4 square( in vec4 a ) { return vec4( a.x*a.x, a.y*a.y, a.z*a.z, a.w*a.w ); }\nfloat saturate( in float a ) { return clamp( a, 0.0, 1.0 ); }\nvec2 saturate( in vec2 a ) { return clamp( a, 0.0, 1.0 ); }\nvec3 saturate( in vec3 a ) { return clamp( a, 0.0, 1.0 ); }\nvec4 saturate( in vec4 a ) { return clamp( a, 0.0, 1.0 ); }\nfloat average( in float a ) { return a; }\nfloat average( in vec2 a ) { return ( a.x + a.y) * 0.5; }\nfloat average( in vec3 a ) { return ( a.x + a.y + a.z) / 3.0; }\nfloat average( in vec4 a ) { return ( a.x + a.y + a.z + a.w) * 0.25; }\nfloat whiteCompliment( in float a ) { return saturate( 1.0 - a ); }\nvec2 whiteCompliment( in vec2 a ) { return saturate( vec2(1.0) - a ); }\nvec3 whiteCompliment( in vec3 a ) { return saturate( vec3(1.0) - a ); }\nvec4 whiteCompliment( in vec4 a ) { return saturate( vec4(1.0) - a ); }\nvec3 transformDirection( in vec3 normal, in mat4 matrix ) {\n return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz );\n}\n// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations\nvec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {\n return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal) {\n float distance = dot( planeNormal, point-pointOnPlane );\n return point - distance * planeNormal;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) );\n}\nfloat calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {\n if ( decayExponent > 0.0 ) {\n return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent );\n }\n return 1.0;\n}\n\nvec3 inputToLinear( in vec3 a ) {\n#ifdef GAMMA_INPUT\n return pow( a, vec3( float( GAMMA_FACTOR ) ) );\n#else\n return a;\n#endif\n}\nvec3 linearToOutput( in vec3 a ) {\n#ifdef GAMMA_OUTPUT\n return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );\n#else\n return a;\n#endif\n}\n"; // File:src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl @@ -16397,7 +16403,7 @@ THREE.ShaderChunk[ 'lights_phong_vertex'] = "#if MAX_SPOT_LIGHTS > 0 || defined( // File:src/renderers/shaders/ShaderChunk/map_fragment.glsl -THREE.ShaderChunk[ 'map_fragment'] = "#ifdef USE_MAP\n\n vec4 texelColor = texture2D( map, vUv );\n\n #ifdef GAMMA_INPUT\n\n texelColor.xyz *= texelColor.xyz;\n\n #endif\n\n gl_FragColor = gl_FragColor * texelColor;\n\n#endif"; +THREE.ShaderChunk[ 'map_fragment'] = "#ifdef USE_MAP\n\n vec4 texelColor = texture2D( map, vUv );\n\n texelColor.xyz = inputToLinear( texelColor.xyz );\n\n gl_FragColor = gl_FragColor * texelColor;\n\n#endif"; // File:src/renderers/shaders/ShaderChunk/lightmap_vertex.glsl @@ -16413,7 +16419,7 @@ THREE.ShaderChunk[ 'color_pars_fragment'] = "#ifdef USE_COLOR\n\n varying vec3 v // File:src/renderers/shaders/ShaderChunk/color_vertex.glsl -THREE.ShaderChunk[ 'color_vertex'] = "#ifdef USE_COLOR\n\n #ifdef GAMMA_INPUT\n\n vColor = square( color );\n\n #else\n\n vColor = color;\n\n #endif\n\n#endif"; +THREE.ShaderChunk[ 'color_vertex'] = "#ifdef USE_COLOR\n\n vColor.xyz = inputToLinear( color.xyz );\n\n#endif"; // File:src/renderers/shaders/ShaderChunk/skinning_vertex.glsl @@ -16425,7 +16431,7 @@ THREE.ShaderChunk[ 'envmap_pars_vertex'] = "#if defined( USE_ENVMAP ) && ! defin // File:src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl -THREE.ShaderChunk[ 'linear_to_gamma_fragment'] = "#ifdef GAMMA_OUTPUT\n\n gl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n\n#endif"; +THREE.ShaderChunk[ 'linear_to_gamma_fragment'] = "\n gl_FragColor.xyz = linearToOutput( gl_FragColor.xyz );\n"; // File:src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl @@ -16441,7 +16447,7 @@ THREE.ShaderChunk[ 'map_pars_vertex'] = "#if defined( USE_MAP ) || defined( USE_ // File:src/renderers/shaders/ShaderChunk/envmap_fragment.glsl -THREE.ShaderChunk[ 'envmap_fragment'] = "#ifdef USE_ENVMAP\n\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n // Transforming Normal Vectors with the Inverse Transformation\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n #ifdef ENVMAP_MODE_REFLECTION\n\n vec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n #else\n\n vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n #endif\n\n #else\n\n vec3 reflectVec = vReflect;\n\n #endif\n\n #ifdef DOUBLE_SIDED\n float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n #else\n float flipNormal = 1.0;\n #endif\n\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n vec4 envColor = texture2D( envMap, sampleUV );\n \n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n #endif\n\n #ifdef GAMMA_INPUT\n\n envColor.xyz *= envColor.xyz;\n\n #endif\n\n #ifdef ENVMAP_BLENDING_MULTIPLY\n\n gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_MIX )\n\n gl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_ADD )\n\n gl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;\n\n #endif\n\n#endif\n"; +THREE.ShaderChunk[ 'envmap_fragment'] = "#ifdef USE_ENVMAP\n\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n // Transforming Normal Vectors with the Inverse Transformation\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n #ifdef ENVMAP_MODE_REFLECTION\n\n vec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n #else\n\n vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n #endif\n\n #else\n\n vec3 reflectVec = vReflect;\n\n #endif\n\n #ifdef DOUBLE_SIDED\n float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n #else\n float flipNormal = 1.0;\n #endif\n\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n vec4 envColor = texture2D( envMap, sampleUV );\n \n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n #endif\n\n envColor.xyz = inputToLinear( envColor.xyz );\n\n #ifdef ENVMAP_BLENDING_MULTIPLY\n\n gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_MIX )\n\n gl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_ADD )\n\n gl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;\n\n #endif\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl @@ -16505,7 +16511,7 @@ THREE.ShaderChunk[ 'envmap_vertex'] = "#if defined( USE_ENVMAP ) && ! defined( U // File:src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl -THREE.ShaderChunk[ 'shadowmap_fragment'] = "#ifdef USE_SHADOWMAP\n\n #ifdef SHADOWMAP_DEBUG\n\n vec3 frustumColors[3];\n frustumColors[0] = vec3( 1.0, 0.5, 0.0 );\n frustumColors[1] = vec3( 0.0, 1.0, 0.8 );\n frustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n\n #endif\n\n #ifdef SHADOWMAP_CASCADE\n\n int inFrustumCount = 0;\n\n #endif\n\n float fDepth;\n vec3 shadowColor = vec3( 1.0 );\n\n for( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n // if ( something && something ) breaks ATI OpenGL shader compiler\n // if ( all( something, something ) ) using this instead\n\n bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n bool inFrustum = all( inFrustumVec );\n\n // don't shadow pixels outside of light frustum\n // use just first frustum (for cascades)\n // don't shadow pixels behind far plane of light frustum\n\n #ifdef SHADOWMAP_CASCADE\n\n inFrustumCount += int( inFrustum );\n bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n\n #else\n\n bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n #endif\n\n bool frustumTest = all( frustumTestVec );\n\n if ( frustumTest ) {\n\n shadowCoord.z += shadowBias[ i ];\n\n #if defined( SHADOWMAP_TYPE_PCF )\n\n // Percentage-close filtering\n // (9 pixel kernel)\n // http://fabiensanglard.net/shadowmappingPCF/\n\n float shadow = 0.0;\n\n /*\n // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL\n // must enroll loop manually\n\n for ( float y = -1.25; y <= 1.25; y += 1.25 )\n for ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n\n // doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup\n //vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );\n\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n shadow += 1.0;\n\n }\n\n shadow /= 9.0;\n\n */\n\n const float shadowDelta = 1.0 / 9.0;\n\n float xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n float yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n float dx0 = -1.25 * xPixelOffset;\n float dy0 = -1.25 * yPixelOffset;\n float dx1 = 1.25 * xPixelOffset;\n float dy1 = 1.25 * yPixelOffset;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n // Percentage-close filtering\n // (9 pixel kernel)\n // http://fabiensanglard.net/shadowmappingPCF/\n\n float shadow = 0.0;\n\n float xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n float yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n float dx0 = -1.0 * xPixelOffset;\n float dy0 = -1.0 * yPixelOffset;\n float dx1 = 1.0 * xPixelOffset;\n float dy1 = 1.0 * yPixelOffset;\n\n mat3 shadowKernel;\n mat3 depthKernel;\n\n depthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n depthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n depthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n depthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n depthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n depthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n depthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n depthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n depthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n vec3 shadowZ = vec3( shadowCoord.z );\n shadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\n shadowKernel[0] *= vec3(0.25);\n\n shadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\n shadowKernel[1] *= vec3(0.25);\n\n shadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\n shadowKernel[2] *= vec3(0.25);\n\n vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\n\n shadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\n shadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\n\n vec4 shadowValues;\n shadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\n shadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\n shadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\n shadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\n\n shadow = dot( shadowValues, vec4( 1.0 ) );\n\n shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n #else\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n\n // spot with multiple shadows is darker\n\n shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n\n // spot with multiple shadows has the same color as single shadow spot\n\n // shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );\n\n #endif\n\n }\n\n\n #ifdef SHADOWMAP_DEBUG\n\n #ifdef SHADOWMAP_CASCADE\n\n if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n\n #else\n\n if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n\n #endif\n\n #endif\n\n }\n\n #ifdef GAMMA_OUTPUT\n\n shadowColor *= shadowColor;\n\n #endif\n\n gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n\n#endif\n"; +THREE.ShaderChunk[ 'shadowmap_fragment'] = "#ifdef USE_SHADOWMAP\n\n #ifdef SHADOWMAP_DEBUG\n\n vec3 frustumColors[3];\n frustumColors[0] = vec3( 1.0, 0.5, 0.0 );\n frustumColors[1] = vec3( 0.0, 1.0, 0.8 );\n frustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n\n #endif\n\n #ifdef SHADOWMAP_CASCADE\n\n int inFrustumCount = 0;\n\n #endif\n\n float fDepth;\n vec3 shadowColor = vec3( 1.0 );\n\n for( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n // if ( something && something ) breaks ATI OpenGL shader compiler\n // if ( all( something, something ) ) using this instead\n\n bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n bool inFrustum = all( inFrustumVec );\n\n // don't shadow pixels outside of light frustum\n // use just first frustum (for cascades)\n // don't shadow pixels behind far plane of light frustum\n\n #ifdef SHADOWMAP_CASCADE\n\n inFrustumCount += int( inFrustum );\n bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n\n #else\n\n bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n #endif\n\n bool frustumTest = all( frustumTestVec );\n\n if ( frustumTest ) {\n\n shadowCoord.z += shadowBias[ i ];\n\n #if defined( SHADOWMAP_TYPE_PCF )\n\n // Percentage-close filtering\n // (9 pixel kernel)\n // http://fabiensanglard.net/shadowmappingPCF/\n\n float shadow = 0.0;\n\n /*\n // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL\n // must enroll loop manually\n\n for ( float y = -1.25; y <= 1.25; y += 1.25 )\n for ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n\n // doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup\n //vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );\n\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n shadow += 1.0;\n\n }\n\n shadow /= 9.0;\n\n */\n\n const float shadowDelta = 1.0 / 9.0;\n\n float xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n float yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n float dx0 = -1.25 * xPixelOffset;\n float dy0 = -1.25 * yPixelOffset;\n float dx1 = 1.25 * xPixelOffset;\n float dy1 = 1.25 * yPixelOffset;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n // Percentage-close filtering\n // (9 pixel kernel)\n // http://fabiensanglard.net/shadowmappingPCF/\n\n float shadow = 0.0;\n\n float xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n float yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n float dx0 = -1.0 * xPixelOffset;\n float dy0 = -1.0 * yPixelOffset;\n float dx1 = 1.0 * xPixelOffset;\n float dy1 = 1.0 * yPixelOffset;\n\n mat3 shadowKernel;\n mat3 depthKernel;\n\n depthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n depthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n depthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n depthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n depthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n depthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n depthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n depthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n depthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n vec3 shadowZ = vec3( shadowCoord.z );\n shadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\n shadowKernel[0] *= vec3(0.25);\n\n shadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\n shadowKernel[1] *= vec3(0.25);\n\n shadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\n shadowKernel[2] *= vec3(0.25);\n\n vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\n\n shadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\n shadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\n\n vec4 shadowValues;\n shadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\n shadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\n shadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\n shadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\n\n shadow = dot( shadowValues, vec4( 1.0 ) );\n\n shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n #else\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n\n // spot with multiple shadows is darker\n\n shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n\n // spot with multiple shadows has the same color as single shadow spot\n\n // shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );\n\n #endif\n\n }\n\n\n #ifdef SHADOWMAP_DEBUG\n\n #ifdef SHADOWMAP_CASCADE\n\n if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n\n #else\n\n if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n\n #endif\n\n #endif\n\n }\n\n // NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014\n shadowColor = inputToLinear( shadowColor );\n\n gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl @@ -17552,6 +17558,7 @@ THREE.WebGLRenderer = function ( parameters ) { // physically based shading + this.gammaFactor = 2.0; // for backwards compatibility this.gammaInput = false; this.gammaOutput = false; @@ -22086,15 +22093,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.opacity.value = material.opacity; - if ( _this.gammaInput ) { - - uniforms.diffuse.value.copyGammaToLinear( material.color ); - - } else { - - uniforms.diffuse.value = material.color; - - } + uniforms.diffuse.value = material.color; uniforms.map.value = material.map; uniforms.lightMap.value = material.lightMap; @@ -22158,17 +22157,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.envMap.value = material.envMap; uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1; - if ( _this.gammaInput ) { - - //uniforms.reflectivity.value = material.reflectivity * material.reflectivity; - uniforms.reflectivity.value = material.reflectivity; - - } else { - - uniforms.reflectivity.value = material.reflectivity; - - } - + uniforms.reflectivity.value = material.reflectivity; uniforms.refractionRatio.value = material.refractionRatio; } @@ -22220,17 +22209,8 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.shininess.value = material.shininess; - if ( _this.gammaInput ) { - - uniforms.emissive.value.copyGammaToLinear( material.emissive ); - uniforms.specular.value.copyGammaToLinear( material.specular ); - - } else { - - uniforms.emissive.value = material.emissive; - uniforms.specular.value = material.specular; - - } + uniforms.emissive.value = material.emissive; + uniforms.specular.value = material.specular; if ( material.wrapAround ) { @@ -22242,15 +22222,7 @@ THREE.WebGLRenderer = function ( parameters ) { function refreshUniformsLambert ( uniforms, material ) { - if ( _this.gammaInput ) { - - uniforms.emissive.value.copyGammaToLinear( material.emissive ); - - } else { - - uniforms.emissive.value = material.emissive; - - } + uniforms.emissive.value = material.emissive; if ( material.wrapAround ) { @@ -22719,16 +22691,6 @@ THREE.WebGLRenderer = function ( parameters ) { } - // - - function setColorGamma( array, offset, color, intensitySq ) { - - array[ offset ] = color.r * color.r * intensitySq; - array[ offset + 1 ] = color.g * color.g * intensitySq; - array[ offset + 2 ] = color.b * color.b * intensitySq; - - } - function setColorLinear( array, offset, color, intensity ) { array[ offset ] = color.r * intensity; @@ -22797,19 +22759,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! light.visible ) continue; - if ( _this.gammaInput ) { - - r += color.r * color.r; - g += color.g * color.g; - b += color.b * color.b; - - } else { - - r += color.r; - g += color.g; - b += color.b; - - } + r += color.r; + g += color.g; + b += color.b; } else if ( light instanceof THREE.DirectionalLight ) { @@ -22828,15 +22780,7 @@ THREE.WebGLRenderer = function ( parameters ) { dirPositions[ dirOffset + 1 ] = _direction.y; dirPositions[ dirOffset + 2 ] = _direction.z; - if ( _this.gammaInput ) { - - setColorGamma( dirColors, dirOffset, color, intensity * intensity ); - - } else { - - setColorLinear( dirColors, dirOffset, color, intensity ); - - } + setColorLinear( dirColors, dirOffset, color, intensity ); dirLength += 1; @@ -22848,15 +22792,7 @@ THREE.WebGLRenderer = function ( parameters ) { pointOffset = pointLength * 3; - if ( _this.gammaInput ) { - - setColorGamma( pointColors, pointOffset, color, intensity * intensity ); - - } else { - - setColorLinear( pointColors, pointOffset, color, intensity ); - - } + setColorLinear( pointColors, pointOffset, color, intensity ); _vector3.setFromMatrixPosition( light.matrixWorld ); @@ -22878,15 +22814,7 @@ THREE.WebGLRenderer = function ( parameters ) { spotOffset = spotLength * 3; - if ( _this.gammaInput ) { - - setColorGamma( spotColors, spotOffset, color, intensity * intensity ); - - } else { - - setColorLinear( spotColors, spotOffset, color, intensity ); - - } + setColorLinear( spotColors, spotOffset, color, intensity ); _direction.setFromMatrixPosition( light.matrixWorld ); @@ -22928,19 +22856,8 @@ THREE.WebGLRenderer = function ( parameters ) { skyColor = light.color; groundColor = light.groundColor; - if ( _this.gammaInput ) { - - intensitySq = intensity * intensity; - - setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq ); - setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq ); - - } else { - - setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity ); - setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity ); - - } + setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity ); + setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity ); hemiLength += 1; @@ -24293,6 +24210,8 @@ THREE.WebGLProgram = ( function () { } + var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; + // console.log( 'building new program ' ); // @@ -24323,6 +24242,7 @@ THREE.WebGLProgram = ( function () { _this.gammaInput ? '#define GAMMA_INPUT' : '', _this.gammaOutput ? '#define GAMMA_OUTPUT' : '', + '#define GAMMA_FACTOR ' + gammaFactorDefine, '#define MAX_DIR_LIGHTS ' + parameters.maxDirLights, '#define MAX_POINT_LIGHTS ' + parameters.maxPointLights, @@ -24437,6 +24357,7 @@ THREE.WebGLProgram = ( function () { _this.gammaInput ? '#define GAMMA_INPUT' : '', _this.gammaOutput ? '#define GAMMA_OUTPUT' : '', + '#define GAMMA_FACTOR ' + gammaFactorDefine, ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', diff --git a/build/three.min.js b/build/three.min.js index 9b6136eb299905..043050dd5c8cbe 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -9,10 +9,10 @@ THREE.CanvasRenderer=function(){console.error("THREE.CanvasRenderer has been mov THREE.Color.prototype={constructor:THREE.Color,r:1,g:1,b:1,set:function(a){a instanceof THREE.Color?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){if(0===b)this.r=this.g=this.b=c;else{var d=function(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a};b=.5>=c?c*(1+b):c+b-c*b;c=2*c-b;this.r=d(c,b,a+1/3);this.g=d(c,b,a);this.b=d(c,b,a-1/3)}return this},setStyle:function(a){if(/^rgb\((\d+), ?(\d+), ?(\d+)\)$/i.test(a))return a=/^rgb\((\d+), ?(\d+), ?(\d+)\)$/i.exec(a),this.r=Math.min(255,parseInt(a[1],10))/255,this.g=Math.min(255,parseInt(a[2],10))/255,this.b=Math.min(255,parseInt(a[3],10))/255,this;if(/^rgb\((\d+)\%, ?(\d+)\%, ?(\d+)\%\)$/i.test(a))return a=/^rgb\((\d+)\%, ?(\d+)\%, ?(\d+)\%\)$/i.exec(a),this.r= Math.min(100,parseInt(a[1],10))/100,this.g=Math.min(100,parseInt(a[2],10))/100,this.b=Math.min(100,parseInt(a[3],10))/100,this;if(/^\#([0-9a-f]{6})$/i.test(a))return a=/^\#([0-9a-f]{6})$/i.exec(a),this.setHex(parseInt(a[1],16)),this;if(/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.test(a))return a=/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(a),this.setHex(parseInt(a[1]+a[1]+a[2]+a[2]+a[3]+a[3],16)),this;if(/^(\w+)$/i.test(a))return this.setHex(THREE.ColorKeywords[a]),this},copy:function(a){this.r=a.r;this.g= -a.g;this.b=a.b;return this},copyGammaToLinear:function(a){this.r=a.r*a.r;this.g=a.g*a.g;this.b=a.b*a.b;return this},copyLinearToGamma:function(a){this.r=Math.sqrt(a.r);this.g=Math.sqrt(a.g);this.b=Math.sqrt(a.b);return this},convertGammaToLinear:function(){var a=this.r,b=this.g,c=this.b;this.r=a*a;this.g=b*b;this.b=c*c;return this},convertLinearToGamma:function(){this.r=Math.sqrt(this.r);this.g=Math.sqrt(this.g);this.b=Math.sqrt(this.b);return this},getHex:function(){return 255*this.r<<16^255*this.g<< -8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(a){a=a||{h:0,s:0,l:0};var b=this.r,c=this.g,d=this.b,e=Math.max(b,c,d),f=Math.min(b,c,d),g,h=(f+e)/2;if(f===e)f=g=0;else{var k=e-f,f=.5>=h?k/(e+f):k/(2-e-f);switch(e){case b:g=(c-d)/k+(c=h?k/(e+f):k/(2-e-f);switch(e){case b:g=(c-d)/k+(cAa?-1:1;h[4*a]=ia.x;h[4*a+1]=ia.y;h[4*a+2]=ia.z;h[4*a+3]=Ua}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],n=[],p=0;pXa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=Ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, +e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],n=[],p=0;pr;r++)s=a[3*c+r],-1==m[s]?(q[2*r]=s,q[2*r+1]=-1,p++):m[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),m[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(x.x,x.y,x.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd?-1:1,e.vertexTangents[c]=new THREE.Vector4(x.x,x.y,x.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cg;g++)m=y[k++],v=u[2*m],m=u[2*m+1],v=new THREE.Vector2(v,m),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*y[k++],t.normal.set(C[q++],C[q++],C[q]),r.normal.copy(t.normal));if(s)for(d=0;4>d;d++)q=3*y[k++],s=new THREE.Vector3(C[q++], -C[q++],C[q]),2!==d&&t.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);p&&(p=y[k++],p=x[p],t.color.setHex(p),r.color.setHex(p));if(b)for(d=0;4>d;d++)p=y[k++],p=x[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&r.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(r)}else{t=new THREE.Face3;t.a=y[k++];t.b=y[k++];t.c=y[k++];h&&(h=y[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)m=y[k++],v=u[2*m],m=u[2*m+1], -v=new THREE.Vector2(v,m),c.faceVertexUvs[d][h].push(v);q&&(q=3*y[k++],t.normal.set(C[q++],C[q++],C[q]));if(s)for(d=0;3>d;d++)q=3*y[k++],s=new THREE.Vector3(C[q++],C[q++],C[q]),t.vertexNormals.push(s);p&&(p=y[k++],t.color.setHex(x[p]));if(b)for(d=0;3>d;d++)p=y[k++],t.vertexColors.push(new THREE.Color(x[p]));c.faces.push(t)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;dg;g++)m=y[k++],v=u[2*m],m=u[2*m+1],v=new THREE.Vector2(v,m),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*y[k++],t.normal.set(E[q++],E[q++],E[q]),r.normal.copy(t.normal));if(s)for(d=0;4>d;d++)q=3*y[k++],s=new THREE.Vector3(E[q++], +E[q++],E[q]),2!==d&&t.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);p&&(p=y[k++],p=x[p],t.color.setHex(p),r.color.setHex(p));if(b)for(d=0;4>d;d++)p=y[k++],p=x[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&r.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(r)}else{t=new THREE.Face3;t.a=y[k++];t.b=y[k++];t.c=y[k++];h&&(h=y[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)m=y[k++],v=u[2*m],m=u[2*m+1], +v=new THREE.Vector2(v,m),c.faceVertexUvs[d][h].push(v);q&&(q=3*y[k++],t.normal.set(E[q++],E[q++],E[q]));if(s)for(d=0;3>d;d++)q=3*y[k++],s=new THREE.Vector3(E[q++],E[q++],E[q]),t.vertexNormals.push(s);p&&(p=y[k++],t.color.setHex(x[p]));if(b)for(d=0;3>d;d++)p=y[k++],t.vertexColors.push(new THREE.Color(x[p]));c.faces.push(t)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;df||(C=b.origin.distanceTo(p),Cd.far||e.push({distance:C,point:n.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, -object:this}))}}else for(m=m.position.array,g=0;gf||(C=b.origin.distanceTo(p),Cd.far||e.push({distance:C,point:n.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(C=b.origin.distanceTo(p),Cd.far||e.push({distance:C,point:n.clone().applyMatrix4(this.matrixWorld), +THREE.BufferGeometry){var m=g.attributes;if(void 0!==m.index){var t=m.index.array,m=m.position.array,s=g.offsets;0===s.length&&(s=[{start:0,count:t.length,index:0}]);for(var r=0;rf||(E=b.origin.distanceTo(p),Ed.far||e.push({distance:E,point:n.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, +object:this}))}}else for(m=m.position.array,g=0;gf||(E=b.origin.distanceTo(p),Ed.far||e.push({distance:E,point:n.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(E=b.origin.distanceTo(p),Ed.far||e.push({distance:E,point:n.clone().applyMatrix4(this.matrixWorld), index:g,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(a){void 0===a&&(a=new THREE.Line(this.geometry,this.material,this.mode));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype); THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0g.far||h.push({distance:z,point:F,face:new THREE.Face3(p,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=p.position.array,s=k=0,x=r.length;k -g.far||h.push({distance:z,point:F,face:new THREE.Face3(p,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(s=this.material instanceof THREE.MeshFaceMaterial,r=!0===s?this.material.materials:null,t=g.precision,u=k.vertices,v=0,y=k.faces.length;vg.far||h.push({distance:z,point:F,face:C,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; +this.material;if(void 0!==n){var p=k.attributes,q,m,t=g.precision;if(void 0!==p.index){var s=p.index.array,r=p.position.array,u=k.offsets;0===u.length&&(u=[{start:0,count:s.length,index:0}]);for(var v=0,y=u.length;vg.far||h.push({distance:z,point:O,face:new THREE.Face3(p,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=p.position.array,s=k=0,x=r.length;k +g.far||h.push({distance:z,point:O,face:new THREE.Face3(p,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(s=this.material instanceof THREE.MeshFaceMaterial,r=!0===s?this.material.materials:null,t=g.precision,u=k.vertices,v=0,y=k.faces.length;vg.far||h.push({distance:z,point:O,face:E,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(this.boneTextureHeight=this.boneTextureWidth=a=256 0.0 ) {\n\t return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent );\n\t}\n\treturn 1.0;\n}\n\n"; +THREE.Fog.prototype.clone=function(){return new THREE.Fog(this.color.getHex(),this.near,this.far)};THREE.FogExp2=function(a,b){this.name="";this.color=new THREE.Color(a);this.density=void 0!==b?b:2.5E-4};THREE.FogExp2.prototype.clone=function(){return new THREE.FogExp2(this.color.getHex(),this.density)};THREE.ShaderChunk={};THREE.ShaderChunk.common="#define PI 3.14159\n#define PI2 6.28318\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n\nfloat square( in float a ) { return a*a; }\nvec2 square( in vec2 a ) { return vec2( a.x*a.x, a.y*a.y ); }\nvec3 square( in vec3 a ) { return vec3( a.x*a.x, a.y*a.y, a.z*a.z ); }\nvec4 square( in vec4 a ) { return vec4( a.x*a.x, a.y*a.y, a.z*a.z, a.w*a.w ); }\nfloat saturate( in float a ) { return clamp( a, 0.0, 1.0 ); }\nvec2 saturate( in vec2 a ) { return clamp( a, 0.0, 1.0 ); }\nvec3 saturate( in vec3 a ) { return clamp( a, 0.0, 1.0 ); }\nvec4 saturate( in vec4 a ) { return clamp( a, 0.0, 1.0 ); }\nfloat average( in float a ) { return a; }\nfloat average( in vec2 a ) { return ( a.x + a.y) * 0.5; }\nfloat average( in vec3 a ) { return ( a.x + a.y + a.z) / 3.0; }\nfloat average( in vec4 a ) { return ( a.x + a.y + a.z + a.w) * 0.25; }\nfloat whiteCompliment( in float a ) { return saturate( 1.0 - a ); }\nvec2 whiteCompliment( in vec2 a ) { return saturate( vec2(1.0) - a ); }\nvec3 whiteCompliment( in vec3 a ) { return saturate( vec3(1.0) - a ); }\nvec4 whiteCompliment( in vec4 a ) { return saturate( vec4(1.0) - a ); }\nvec3 transformDirection( in vec3 normal, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( normal, 0.0 ) ).xyz );\n}\n// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations\nvec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {\n\treturn normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal) {\n\tfloat distance = dot( planeNormal, point-pointOnPlane );\n\treturn point - distance * planeNormal;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) );\n}\nfloat calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {\n\tif ( decayExponent > 0.0 ) {\n\t return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent );\n\t}\n\treturn 1.0;\n}\n\nvec3 inputToLinear( in vec3 a ) {\n#ifdef GAMMA_INPUT\n\treturn pow( a, vec3( float( GAMMA_FACTOR ) ) );\n#else\n\treturn a;\n#endif\n}\nvec3 linearToOutput( in vec3 a ) {\n#ifdef GAMMA_OUTPUT\n\treturn pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );\n#else\n\treturn a;\n#endif\n}\n"; THREE.ShaderChunk.alphatest_fragment="#ifdef ALPHATEST\n\n\tif ( gl_FragColor.a < ALPHATEST ) discard;\n\n#endif\n";THREE.ShaderChunk.lights_lambert_vertex="vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\tfloat dotProduct = dot( transformedNormal, dirVector );\n\tvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t#endif\n\n\t#endif\n\n\t#ifdef WRAP_AROUND\n\n\t\tvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\tdirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tdirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n\t\t#endif\n\n\t#endif\n\n\tvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n\t#endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\tpointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tpointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\tvLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n\t\t#endif\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\t\tlVector = normalize( lVector );\n\n\t\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\t\t\tvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\t\tvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\t\tspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n\t\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\t\tspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\tvLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n\t\t\t#endif\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\t\tfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n\t\tvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n\t\t#endif\n\n\t}\n\n#endif\n\nvLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive;\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive;\n\n#endif\n"; THREE.ShaderChunk.map_particle_pars_fragment="#ifdef USE_MAP\n\n\tuniform sampler2D map;\n\n#endif";THREE.ShaderChunk.default_vertex="#ifdef USE_SKINNING\n\n\tvec4 mvPosition = modelViewMatrix * skinned;\n\n#elif defined( USE_MORPHTARGETS )\n\n\tvec4 mvPosition = modelViewMatrix * vec4( morphed, 1.0 );\n\n#else\n\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\n#endif\n\ngl_Position = projectionMatrix * mvPosition;\n";THREE.ShaderChunk.map_pars_fragment="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\n#endif\n\n#ifdef USE_MAP\n\n\tuniform sampler2D map;\n\n#endif"; THREE.ShaderChunk.skinnormal_vertex="#ifdef USE_SKINNING\n\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\n\t#ifdef USE_MORPHNORMALS\n\n\tvec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );\n\n\t#else\n\n\tvec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );\n\n\t#endif\n\n#endif\n"; @@ -387,10 +387,10 @@ THREE.ShaderChunk.fog_pars_fragment="#ifdef USE_FOG\n\n\tuniform vec3 fogColor;\ THREE.ShaderChunk.envmap_pars_fragment="#ifdef USE_ENVMAP\n\n\tuniform float reflectivity;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tuniform float refractionRatio;\n\n\t#else\n\n\t\tvarying vec3 vReflect;\n\n\t#endif\n\n#endif\n";THREE.ShaderChunk.logdepthbuf_fragment="#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n\n#endif"; THREE.ShaderChunk.normalmap_pars_fragment="#ifdef USE_NORMALMAP\n\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\n\t\t\t// Per-Pixel Tangent Space Normal Mapping\n\t\t\t// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html\n\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\n\t}\n\n#endif\n"; THREE.ShaderChunk.lights_phong_pars_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvarying vec3 vWorldPosition;\n\n#endif\n";THREE.ShaderChunk.lightmap_pars_fragment="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\tuniform sampler2D lightMap;\n\n#endif";THREE.ShaderChunk.shadowmap_vertex="#ifdef USE_SHADOWMAP\n\n\tfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n\t\tvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n\n\t}\n\n#endif"; -THREE.ShaderChunk.lights_phong_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvWorldPosition = worldPosition.xyz;\n\n#endif";THREE.ShaderChunk.map_fragment="#ifdef USE_MAP\n\n\tvec4 texelColor = texture2D( map, vUv );\n\n\t#ifdef GAMMA_INPUT\n\n\t\ttexelColor.xyz *= texelColor.xyz;\n\n\t#endif\n\n\tgl_FragColor = gl_FragColor * texelColor;\n\n#endif";THREE.ShaderChunk.lightmap_vertex="#ifdef USE_LIGHTMAP\n\n\tvUv2 = uv2;\n\n#endif"; -THREE.ShaderChunk.map_particle_fragment="#ifdef USE_MAP\n\n\tgl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );\n\n#endif";THREE.ShaderChunk.color_pars_fragment="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif\n";THREE.ShaderChunk.color_vertex="#ifdef USE_COLOR\n\n\t#ifdef GAMMA_INPUT\n\n\t\tvColor = square( color );\n\n\t#else\n\n\t\tvColor = color;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.skinning_vertex="#ifdef USE_SKINNING\n\n\t#ifdef USE_MORPHTARGETS\n\n\tvec4 skinVertex = bindMatrix * vec4( morphed, 1.0 );\n\n\t#else\n\n\tvec4 skinVertex = bindMatrix * vec4( position, 1.0 );\n\n\t#endif\n\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\tskinned = bindMatrixInverse * skinned;\n\n#endif\n"; -THREE.ShaderChunk.envmap_pars_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvarying vec3 vReflect;\n\n\tuniform float refractionRatio;\n\n#endif\n";THREE.ShaderChunk.linear_to_gamma_fragment="#ifdef GAMMA_OUTPUT\n\n\tgl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n\n#endif";THREE.ShaderChunk.color_pars_vertex="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif";THREE.ShaderChunk.lights_lambert_pars_vertex="uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n"; -THREE.ShaderChunk.map_pars_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n\n#endif\n";THREE.ShaderChunk.envmap_fragment="#ifdef USE_ENVMAP\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n\t\t// Transforming Normal Vectors with the Inverse Transformation\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n\t\t#else\n\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t\t#endif\n\n\t#else\n\n\t\tvec3 reflectVec = vReflect;\n\n\t#endif\n\n\t#ifdef DOUBLE_SIDED\n\t\tfloat flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\t#else\n\t\tfloat flipNormal = 1.0;\n\t#endif\n\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t\t\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#endif\n\n\t#ifdef GAMMA_INPUT\n\n\t\tenvColor.xyz *= envColor.xyz;\n\n\t#endif\n\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\n\t\tgl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\n\t\tgl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\n\t\tgl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;\n\n\t#endif\n\n#endif\n"; +THREE.ShaderChunk.lights_phong_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvWorldPosition = worldPosition.xyz;\n\n#endif";THREE.ShaderChunk.map_fragment="#ifdef USE_MAP\n\n\tvec4 texelColor = texture2D( map, vUv );\n\n\ttexelColor.xyz = inputToLinear( texelColor.xyz );\n\n\tgl_FragColor = gl_FragColor * texelColor;\n\n#endif";THREE.ShaderChunk.lightmap_vertex="#ifdef USE_LIGHTMAP\n\n\tvUv2 = uv2;\n\n#endif";THREE.ShaderChunk.map_particle_fragment="#ifdef USE_MAP\n\n\tgl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );\n\n#endif"; +THREE.ShaderChunk.color_pars_fragment="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif\n";THREE.ShaderChunk.color_vertex="#ifdef USE_COLOR\n\n\tvColor.xyz = inputToLinear( color.xyz );\n\n#endif";THREE.ShaderChunk.skinning_vertex="#ifdef USE_SKINNING\n\n\t#ifdef USE_MORPHTARGETS\n\n\tvec4 skinVertex = bindMatrix * vec4( morphed, 1.0 );\n\n\t#else\n\n\tvec4 skinVertex = bindMatrix * vec4( position, 1.0 );\n\n\t#endif\n\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\tskinned = bindMatrixInverse * skinned;\n\n#endif\n"; +THREE.ShaderChunk.envmap_pars_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvarying vec3 vReflect;\n\n\tuniform float refractionRatio;\n\n#endif\n";THREE.ShaderChunk.linear_to_gamma_fragment="\n\tgl_FragColor.xyz = linearToOutput( gl_FragColor.xyz );\n";THREE.ShaderChunk.color_pars_vertex="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif";THREE.ShaderChunk.lights_lambert_pars_vertex="uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n"; +THREE.ShaderChunk.map_pars_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n\n#endif\n";THREE.ShaderChunk.envmap_fragment="#ifdef USE_ENVMAP\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n\t\t// Transforming Normal Vectors with the Inverse Transformation\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n\t\t#else\n\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t\t#endif\n\n\t#else\n\n\t\tvec3 reflectVec = vReflect;\n\n\t#endif\n\n\t#ifdef DOUBLE_SIDED\n\t\tfloat flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\t#else\n\t\tfloat flipNormal = 1.0;\n\t#endif\n\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t\t\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#endif\n\n\tenvColor.xyz = inputToLinear( envColor.xyz );\n\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\n\t\tgl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\n\t\tgl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\n\t\tgl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;\n\n\t#endif\n\n#endif\n"; THREE.ShaderChunk.specularmap_pars_fragment="#ifdef USE_SPECULARMAP\n\n\tuniform sampler2D specularMap;\n\n#endif";THREE.ShaderChunk.logdepthbuf_vertex="#ifdef USE_LOGDEPTHBUF\n\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\n#else\n\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.morphtarget_pars_vertex="#ifdef USE_MORPHTARGETS\n\n\t#ifndef USE_MORPHNORMALS\n\n\tuniform float morphTargetInfluences[ 8 ];\n\n\t#else\n\n\tuniform float morphTargetInfluences[ 4 ];\n\n\t#endif\n\n#endif"; THREE.ShaderChunk.specularmap_fragment="float specularStrength;\n\n#ifdef USE_SPECULARMAP\n\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n\n#else\n\n\tspecularStrength = 1.0;\n\n#endif";THREE.ShaderChunk.fog_fragment="#ifdef USE_FOG\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\n\t#else\n\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\n\t#endif\n\n\t#ifdef FOG_EXP2\n\n\t\tfloat fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 );\n\t\tfogFactor = whiteCompliment( fogFactor );\n\n\t#else\n\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n\n\t#endif\n\t\n\tgl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n\n#endif"; THREE.ShaderChunk.bumpmap_pars_fragment="#ifdef USE_BUMPMAP\n\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\n\t\t\t// Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen\n\t\t\t//\thttp://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html\n\n\t\t\t// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)\n\n\tvec2 dHdxy_fwd() {\n\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\n\t\treturn vec2( dBx, dBy );\n\n\t}\n\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\n\t\tvec3 vSigmaX = dFdx( surf_pos );\n\t\tvec3 vSigmaY = dFdy( surf_pos );\n\t\tvec3 vN = surf_norm;\t\t// normalized\n\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\n\t}\n\n#endif"; @@ -398,7 +398,7 @@ THREE.ShaderChunk.defaultnormal_vertex="#ifdef USE_SKINNING\n\n\tvec3 objectNorm THREE.ShaderChunk.skinbase_vertex="#ifdef USE_SKINNING\n\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n\n#endif";THREE.ShaderChunk.map_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n\n#endif"; THREE.ShaderChunk.lightmap_fragment="#ifdef USE_LIGHTMAP\n\n\tgl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );\n\n#endif";THREE.ShaderChunk.shadowmap_pars_vertex="#ifdef USE_SHADOWMAP\n\n\tvarying vec4 vShadowCoord[ MAX_SHADOWS ];\n\tuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n\n#endif";THREE.ShaderChunk.color_fragment="#ifdef USE_COLOR\n\n\tgl_FragColor = gl_FragColor * vec4( vColor, 1.0 );\n\n#endif";THREE.ShaderChunk.morphtarget_vertex="#ifdef USE_MORPHTARGETS\n\n\tvec3 morphed = vec3( 0.0 );\n\tmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\tmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\tmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\tmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\n\t#ifndef USE_MORPHNORMALS\n\n\tmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\tmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\tmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\tmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\n\t#endif\n\n\tmorphed += position;\n\n#endif"; THREE.ShaderChunk.envmap_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvec3 worldNormal = transformDirection( objectNormal, modelMatrix );\n\n\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\n\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\n\t#else\n\n\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t#endif\n\n#endif\n"; -THREE.ShaderChunk.shadowmap_fragment="#ifdef USE_SHADOWMAP\n\n\t#ifdef SHADOWMAP_DEBUG\n\n\t\tvec3 frustumColors[3];\n\t\tfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\n\t\tfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\n\t\tfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n\n\t#endif\n\n\t#ifdef SHADOWMAP_CASCADE\n\n\t\tint inFrustumCount = 0;\n\n\t#endif\n\n\tfloat fDepth;\n\tvec3 shadowColor = vec3( 1.0 );\n\n\tfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n\t\tvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n\t\t\t\t// if ( something && something ) breaks ATI OpenGL shader compiler\n\t\t\t\t// if ( all( something, something ) ) using this instead\n\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\n\t\t\t\t// don't shadow pixels outside of light frustum\n\t\t\t\t// use just first frustum (for cascades)\n\t\t\t\t// don't shadow pixels behind far plane of light frustum\n\n\t\t#ifdef SHADOWMAP_CASCADE\n\n\t\t\tinFrustumCount += int( inFrustum );\n\t\t\tbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n\n\t\t#else\n\n\t\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n\t\t#endif\n\n\t\tbool frustumTest = all( frustumTestVec );\n\n\t\tif ( frustumTest ) {\n\n\t\t\tshadowCoord.z += shadowBias[ i ];\n\n\t\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\n\t\t\t\t\t\t// Percentage-close filtering\n\t\t\t\t\t\t// (9 pixel kernel)\n\t\t\t\t\t\t// http://fabiensanglard.net/shadowmappingPCF/\n\n\t\t\t\tfloat shadow = 0.0;\n\n\t\t/*\n\t\t\t\t\t\t// nested loops breaks shader compiler / validator on some ATI cards when using OpenGL\n\t\t\t\t\t\t// must enroll loop manually\n\n\t\t\t\tfor ( float y = -1.25; y <= 1.25; y += 1.25 )\n\t\t\t\t\tfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n\n\t\t\t\t\t\tvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n\n\t\t\t\t\t\t\t\t// doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup\n\t\t\t\t\t\t\t\t//vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );\n\n\t\t\t\t\t\tfloat fDepth = unpackDepth( rgbaDepth );\n\n\t\t\t\t\t\tif ( fDepth < shadowCoord.z )\n\t\t\t\t\t\t\tshadow += 1.0;\n\n\t\t\t\t}\n\n\t\t\t\tshadow /= 9.0;\n\n\t\t*/\n\n\t\t\t\tconst float shadowDelta = 1.0 / 9.0;\n\n\t\t\t\tfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n\t\t\t\tfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n\t\t\t\tfloat dx0 = -1.25 * xPixelOffset;\n\t\t\t\tfloat dy0 = -1.25 * yPixelOffset;\n\t\t\t\tfloat dx1 = 1.25 * xPixelOffset;\n\t\t\t\tfloat dy1 = 1.25 * yPixelOffset;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n\t\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n\t\t\t\t\t\t// Percentage-close filtering\n\t\t\t\t\t\t// (9 pixel kernel)\n\t\t\t\t\t\t// http://fabiensanglard.net/shadowmappingPCF/\n\n\t\t\t\tfloat shadow = 0.0;\n\n\t\t\t\tfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n\t\t\t\tfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n\t\t\t\tfloat dx0 = -1.0 * xPixelOffset;\n\t\t\t\tfloat dy0 = -1.0 * yPixelOffset;\n\t\t\t\tfloat dx1 = 1.0 * xPixelOffset;\n\t\t\t\tfloat dy1 = 1.0 * yPixelOffset;\n\n\t\t\t\tmat3 shadowKernel;\n\t\t\t\tmat3 depthKernel;\n\n\t\t\t\tdepthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n\t\t\t\tdepthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n\t\t\t\tdepthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n\t\t\t\tdepthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n\t\t\t\tdepthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n\t\t\t\tdepthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n\t\t\t\tdepthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n\t\t\t\tdepthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n\t\t\t\tdepthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n\t\t\t\tvec3 shadowZ = vec3( shadowCoord.z );\n\t\t\t\tshadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\n\t\t\t\tshadowKernel[0] *= vec3(0.25);\n\n\t\t\t\tshadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\n\t\t\t\tshadowKernel[1] *= vec3(0.25);\n\n\t\t\t\tshadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\n\t\t\t\tshadowKernel[2] *= vec3(0.25);\n\n\t\t\t\tvec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\n\n\t\t\t\tshadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\n\t\t\t\tshadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\n\n\t\t\t\tvec4 shadowValues;\n\t\t\t\tshadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\n\t\t\t\tshadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\n\t\t\t\tshadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\n\t\t\t\tshadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\n\n\t\t\t\tshadow = dot( shadowValues, vec4( 1.0 ) );\n\n\t\t\t\tshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n\t\t\t#else\n\n\t\t\t\tvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n\t\t\t\tfloat fDepth = unpackDepth( rgbaDepth );\n\n\t\t\t\tif ( fDepth < shadowCoord.z )\n\n\t\t// spot with multiple shadows is darker\n\n\t\t\t\t\tshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n\n\t\t// spot with multiple shadows has the same color as single shadow spot\n\n\t\t// \t\t\t\t\tshadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );\n\n\t\t\t#endif\n\n\t\t}\n\n\n\t\t#ifdef SHADOWMAP_DEBUG\n\n\t\t\t#ifdef SHADOWMAP_CASCADE\n\n\t\t\t\tif ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n\n\t\t\t#else\n\n\t\t\t\tif ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t}\n\n\t#ifdef GAMMA_OUTPUT\n\n\t\tshadowColor *= shadowColor;\n\n\t#endif\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n\n#endif\n"; +THREE.ShaderChunk.shadowmap_fragment="#ifdef USE_SHADOWMAP\n\n\t#ifdef SHADOWMAP_DEBUG\n\n\t\tvec3 frustumColors[3];\n\t\tfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\n\t\tfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\n\t\tfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n\n\t#endif\n\n\t#ifdef SHADOWMAP_CASCADE\n\n\t\tint inFrustumCount = 0;\n\n\t#endif\n\n\tfloat fDepth;\n\tvec3 shadowColor = vec3( 1.0 );\n\n\tfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n\t\tvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n\t\t\t\t// if ( something && something ) breaks ATI OpenGL shader compiler\n\t\t\t\t// if ( all( something, something ) ) using this instead\n\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\n\t\t\t\t// don't shadow pixels outside of light frustum\n\t\t\t\t// use just first frustum (for cascades)\n\t\t\t\t// don't shadow pixels behind far plane of light frustum\n\n\t\t#ifdef SHADOWMAP_CASCADE\n\n\t\t\tinFrustumCount += int( inFrustum );\n\t\t\tbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n\n\t\t#else\n\n\t\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n\t\t#endif\n\n\t\tbool frustumTest = all( frustumTestVec );\n\n\t\tif ( frustumTest ) {\n\n\t\t\tshadowCoord.z += shadowBias[ i ];\n\n\t\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\n\t\t\t\t\t\t// Percentage-close filtering\n\t\t\t\t\t\t// (9 pixel kernel)\n\t\t\t\t\t\t// http://fabiensanglard.net/shadowmappingPCF/\n\n\t\t\t\tfloat shadow = 0.0;\n\n\t\t/*\n\t\t\t\t\t\t// nested loops breaks shader compiler / validator on some ATI cards when using OpenGL\n\t\t\t\t\t\t// must enroll loop manually\n\n\t\t\t\tfor ( float y = -1.25; y <= 1.25; y += 1.25 )\n\t\t\t\t\tfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n\n\t\t\t\t\t\tvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n\n\t\t\t\t\t\t\t\t// doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup\n\t\t\t\t\t\t\t\t//vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );\n\n\t\t\t\t\t\tfloat fDepth = unpackDepth( rgbaDepth );\n\n\t\t\t\t\t\tif ( fDepth < shadowCoord.z )\n\t\t\t\t\t\t\tshadow += 1.0;\n\n\t\t\t\t}\n\n\t\t\t\tshadow /= 9.0;\n\n\t\t*/\n\n\t\t\t\tconst float shadowDelta = 1.0 / 9.0;\n\n\t\t\t\tfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n\t\t\t\tfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n\t\t\t\tfloat dx0 = -1.25 * xPixelOffset;\n\t\t\t\tfloat dy0 = -1.25 * yPixelOffset;\n\t\t\t\tfloat dx1 = 1.25 * xPixelOffset;\n\t\t\t\tfloat dy1 = 1.25 * yPixelOffset;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n\t\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n\t\t\t\t\t\t// Percentage-close filtering\n\t\t\t\t\t\t// (9 pixel kernel)\n\t\t\t\t\t\t// http://fabiensanglard.net/shadowmappingPCF/\n\n\t\t\t\tfloat shadow = 0.0;\n\n\t\t\t\tfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n\t\t\t\tfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n\t\t\t\tfloat dx0 = -1.0 * xPixelOffset;\n\t\t\t\tfloat dy0 = -1.0 * yPixelOffset;\n\t\t\t\tfloat dx1 = 1.0 * xPixelOffset;\n\t\t\t\tfloat dy1 = 1.0 * yPixelOffset;\n\n\t\t\t\tmat3 shadowKernel;\n\t\t\t\tmat3 depthKernel;\n\n\t\t\t\tdepthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n\t\t\t\tdepthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n\t\t\t\tdepthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n\t\t\t\tdepthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n\t\t\t\tdepthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n\t\t\t\tdepthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n\t\t\t\tdepthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n\t\t\t\tdepthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n\t\t\t\tdepthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n\t\t\t\tvec3 shadowZ = vec3( shadowCoord.z );\n\t\t\t\tshadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\n\t\t\t\tshadowKernel[0] *= vec3(0.25);\n\n\t\t\t\tshadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\n\t\t\t\tshadowKernel[1] *= vec3(0.25);\n\n\t\t\t\tshadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\n\t\t\t\tshadowKernel[2] *= vec3(0.25);\n\n\t\t\t\tvec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\n\n\t\t\t\tshadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\n\t\t\t\tshadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\n\n\t\t\t\tvec4 shadowValues;\n\t\t\t\tshadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\n\t\t\t\tshadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\n\t\t\t\tshadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\n\t\t\t\tshadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\n\n\t\t\t\tshadow = dot( shadowValues, vec4( 1.0 ) );\n\n\t\t\t\tshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n\t\t\t#else\n\n\t\t\t\tvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n\t\t\t\tfloat fDepth = unpackDepth( rgbaDepth );\n\n\t\t\t\tif ( fDepth < shadowCoord.z )\n\n\t\t// spot with multiple shadows is darker\n\n\t\t\t\t\tshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n\n\t\t// spot with multiple shadows has the same color as single shadow spot\n\n\t\t// \t\t\t\t\tshadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );\n\n\t\t\t#endif\n\n\t\t}\n\n\n\t\t#ifdef SHADOWMAP_DEBUG\n\n\t\t\t#ifdef SHADOWMAP_CASCADE\n\n\t\t\t\tif ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n\n\t\t\t#else\n\n\t\t\t\tif ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t}\n\n\t// NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014\n\tshadowColor = inputToLinear( shadowColor );\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n\n#endif\n"; THREE.ShaderChunk.worldpos_vertex="#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\n\t#ifdef USE_SKINNING\n\n\t\tvec4 worldPosition = modelMatrix * skinned;\n\n\t#elif defined( USE_MORPHTARGETS )\n\n\t\tvec4 worldPosition = modelMatrix * vec4( morphed, 1.0 );\n\n\t#else\n\n\t\tvec4 worldPosition = modelMatrix * vec4( position, 1.0 );\n\n\t#endif\n\n#endif\n";THREE.ShaderChunk.shadowmap_pars_fragment="#ifdef USE_SHADOWMAP\n\n\tuniform sampler2D shadowMap[ MAX_SHADOWS ];\n\tuniform vec2 shadowMapSize[ MAX_SHADOWS ];\n\n\tuniform float shadowDarkness[ MAX_SHADOWS ];\n\tuniform float shadowBias[ MAX_SHADOWS ];\n\n\tvarying vec4 vShadowCoord[ MAX_SHADOWS ];\n\n\tfloat unpackDepth( const in vec4 rgba_depth ) {\n\n\t\tconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\n\t\tfloat depth = dot( rgba_depth, bit_shift );\n\t\treturn depth;\n\n\t}\n\n#endif"; THREE.ShaderChunk.skinning_pars_vertex="#ifdef USE_SKINNING\n\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\n\t#ifdef BONE_TEXTURE\n\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureWidth;\n\t\tuniform int boneTextureHeight;\n\n\t\tmat4 getBoneMatrix( const in float i ) {\n\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureWidth ) );\n\t\t\tfloat y = floor( j / float( boneTextureWidth ) );\n\n\t\t\tfloat dx = 1.0 / float( boneTextureWidth );\n\t\t\tfloat dy = 1.0 / float( boneTextureHeight );\n\n\t\t\ty = dy * ( y + 0.5 );\n\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\n\t\t\treturn bone;\n\n\t\t}\n\n\t#else\n\n\t\tuniform mat4 boneGlobalMatrices[ MAX_BONES ];\n\n\t\tmat4 getBoneMatrix( const in float i ) {\n\n\t\t\tmat4 bone = boneGlobalMatrices[ int(i) ];\n\t\t\treturn bone;\n\n\t\t}\n\n\t#endif\n\n#endif\n"; THREE.ShaderChunk.logdepthbuf_pars_fragment="#ifdef USE_LOGDEPTHBUF\n\n\tuniform float logDepthBufFC;\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\t#extension GL_EXT_frag_depth : enable\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.alphamap_fragment="#ifdef USE_ALPHAMAP\n\n\tgl_FragColor.a *= texture2D( alphaMap, vUv ).g;\n\n#endif\n";THREE.ShaderChunk.alphamap_pars_fragment="#ifdef USE_ALPHAMAP\n\n\tuniform sampler2D alphaMap;\n\n#endif\n"; @@ -435,138 +435,137 @@ THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sa THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );\n\t#else\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n\t#endif\n}"].join("\n")}}; THREE.WebGLRenderer=function(a){function b(a){var b=a.geometry;a=a.material;var c=b.vertices.length;if(a.attributes){void 0===b.__webglCustomAttributesList&&(b.__webglCustomAttributesList=[]);for(var d in a.attributes){var e=a.attributes[d];if(!e.__webglInitialized||e.createUniqueBuffers){e.__webglInitialized=!0;var f=1;"v2"===e.type?f=2:"v3"===e.type?f=3:"v4"===e.type?f=4:"c"===e.type&&(f=3);e.size=f;e.array=new Float32Array(c*f);e.buffer=l.createBuffer();e.buffer.belongsToAttribute=d;e.needsUpdate= !0}b.__webglCustomAttributesList.push(e)}}}function c(a,b){var c=b.geometry,e=a.faces3,f=3*e.length,g=1*e.length,h=3*e.length,e=d(b,a);a.__vertexArray=new Float32Array(3*f);a.__normalArray=new Float32Array(3*f);a.__colorArray=new Float32Array(3*f);a.__uvArray=new Float32Array(2*f);1h&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(p={id:nc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:n},q[k]=p,r.push(p)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=r;b.groupsNeedUpdate=!1}f=nb[b.id];g=0;for(d=f.length;gh&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(p={id:mc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:n},q[k]=p,r.push(p)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=r;b.groupsNeedUpdate=!1}f=kb[b.id];g=0;for(d=f.length;gV;V++)ra=Q[V],fb[ib]=ra.x,fb[ib+1]=ra.y,fb[ib+2]=ra.z,ib+=3;else for(V=0;3>V;V++)fb[ib]=M.x,fb[ib+1]=M.y,fb[ib+2]=M.z,ib+=3;l.bindBuffer(l.ARRAY_BUFFER, -v.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,fb,z)}if(pb&&Ya){w=0;for(F=W.length;wV;V++)Fa=O[V],Ua[rb]=Fa.x,Ua[rb+1]=Fa.y,rb+=2;0V;V++)Ca=T[V],qa[Aa]=Ca.x,qa[Aa+1]=Ca.y,Aa+=2;0wa;wa++)tb[wa]=!I.autoScaleCubemaps||Db||Kb?Kb?ma.image[wa].image:ma.image[wa]:M(ma.image[wa],Gc);var Rb=tb[0],Sb=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height),ub=S(ma.format),Cb=S(ma.type);T(l.TEXTURE_CUBE_MAP, -ma,Sb);for(wa=0;6>wa;wa++)if(Db)for(var kb,Vb=tb[wa].mipmaps,Eb=0,ac=Vb.length;Eb=sc&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Nb+=1;return a}function G(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function E(a,b,c,d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function w(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function D(a){a*= -O;a!==tc&&(l.lineWidth(a),tc=a)}function A(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function T(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,S(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,S(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,S(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,S(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE), -b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,N(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,N(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+ -b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height); -console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function K(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, -l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function L(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function N(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? -l.NEAREST:l.LINEAR}function S(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a=== +console.error("THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually."):(l.bufferSubData(n,m.updateRange.offset*m.array.BYTES_PER_ELEMENT,m.array.subarray(m.updateRange.offset,m.updateRange.offset+m.updateRange.count)),m.updateRange.count=0),m.needsUpdate=!1)}else if(a instanceof THREE.Mesh){!0===b.groupsNeedUpdate&&r(a,b);for(var p=kb[b.id],g=0,q=p.length;gW;W++)pa=N[W],Ua[Za]=pa.x,Ua[Za+1]=pa.y,Ua[Za+2]=pa.z,Za+=3;else for(W=0;3>W;W++)Ua[Za]=L.x,Ua[Za+1]=L.y,Ua[Za+2]=L.z,Za+=3;l.bindBuffer(l.ARRAY_BUFFER, +v.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Ua,z)}if(zb&&nb){w=0;for(A=Z.length;wW;W++)ya=S[W],Bb[Wa]=ya.x,Bb[Wa+1]=ya.y,Wa+=2;0W;W++)ta=P[W],rb[ma]=ta.x,rb[ma+1]=ta.y,ma+=2;0ua;ua++)ob[ua]=!I.autoScaleCubemaps||da||xb?xb?la.image[ua].image:la.image[ua]:K(la.image[ua],Gc);var Rb=ob[0],Ob=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height), +pb=N(la.format),Sb=N(la.type);B(l.TEXTURE_CUBE_MAP,la,Ob);for(ua=0;6>ua;ua++)if(da)for(var gb,Eb=ob[ua].mipmaps,yb=0,Yb=Eb.length;yb=sc&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Kb+=1;return a}function F(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function D(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a){a*=J;a!==tc&&(l.lineWidth(a), +tc=a)}function w(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function B(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,N(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,N(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,N(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,N(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&& +b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,T(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,T(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+ +b.sourceFile+" )"));(c=ca.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height); +console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function L(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, +l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function H(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function T(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? +l.NEAREST:l.LINEAR}function N(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a=== THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT; if(a===THREE.FloatType)return l.FLOAT;if(a===THREE.AlphaFormat)return l.ALPHA;if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a=== THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE; -b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; -if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var Q=void 0!==a.canvas?a.canvas:document.createElement("canvas"),U=void 0!==a.context?a.context:null,O=1,ia=void 0!==a.precision?a.precision:"highp", -ga=void 0!==a.alpha?a.alpha:!1,za=void 0!==a.depth?a.depth:!0,H=void 0!==a.stencil?a.stencil:!0,Ua=void 0!==a.antialias?a.antialias:!1,ra=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,Aa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,X=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ua=new THREE.Color(0),bb=0,sa=[],Ja={},Ka=[],Va=[],Ba=[],wb=[],hb=[];this.domElement=Q;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor= -this.autoClear=!0;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var I=this,Za=[],$b=null,$a=null,Fb=-1,qa="",Gb=null,Nb=0,vb=-1,Qb=-1,Rb=-1,Sb=-1,ac=-1,ec=-1,fc=-1,gc=-1,hc=-1,ic=-1,jc=-1,uc= -null,vc=null,wc=null,tc=null,yb=0,lb=0,ab=Q.width,gb=Q.height,xc=0,yc=0,mb=new Uint8Array(16),Pa=new Uint8Array(16),qb=new THREE.Frustum,zb=new THREE.Matrix4;new THREE.Matrix4;var Fa=new THREE.Vector3,na=new THREE.Vector3,Pb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[], -positions:[]}},l;try{var zc={alpha:ga,depth:za,stencil:H,antialias:Ua,premultipliedAlpha:ra,preserveDrawingBuffer:Aa};l=U||Q.getContext("webgl",zc)||Q.getContext("experimental-webgl",zc);if(null===l){if(null!==Q.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}Q.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();Ja={}},!1)}catch(Hc){console.error(Hc)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat= -function(){return{rangeMin:1,rangeMax:1,precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_standard_derivatives");X&&aa.get("EXT_frag_depth");var kc=function(a,b,c,d){!0===ra&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND);l.blendEquation(l.FUNC_ADD); -l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(yb,lb,ab,gb);kc(ua.r,ua.g,ua.b,bb)},Ac=function(){Gb=$b=null;Qb=vb=jc=ic=Rb=-1;qa="";Fb=-1;Pb=!0;for(var a=0;a -b;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}I.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), -c=0,d=b.length;cb;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]), +l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}I.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), +c=0,d=b.length;cd.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+ -f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);K(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),T(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D, -0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):K(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D); -b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=ab,a=gb,d=yb,e=lb);b!==$a&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),$a=b);xc=c;yc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); -else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==$a&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)===l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."); -g&&l.bindFramebuffer(l.FRAMEBUFFER,$a)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +(a.stencilBuffer=!0);a.addEventListener("dispose",Ec);a.__webglTexture=l.createTexture();I.info.memory.textures++;var c=THREE.Math.isPowerOfTwo(a.width)&&THREE.Math.isPowerOfTwo(a.height),d=N(a.format),e=N(a.type);if(b){a.__webglFramebuffer=[];a.__webglRenderbuffer=[];l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture);B(l.TEXTURE_CUBE_MAP,a,c);for(var f=0;6>f;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+ +f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);L(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),B(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D, +0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):L(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D); +b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=ib,a=Pa,d=hb,e=db);b!==Ab&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),Ab=b);xc=c;yc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); +else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==Ab&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)===l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."); +g&&l.bindFramebuffer(l.FRAMEBUFFER,Ab)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; @@ -575,47 +574,47 @@ THREE.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c] break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;default:d=a.getExtension(c)}null===d&&console.log("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}; THREE.WebGLProgram=function(){var a=0;return function(b,c,d,e){var f=b.context,g=d.defines,h=d.__webglShader.uniforms,k=d.attributes,n=d.__webglShader.vertexShader,p=d.__webglShader.fragmentShader,q=d.index0AttributeName;void 0===q&&!0===e.morphTargets&&(q="position");var m="SHADOWMAP_TYPE_BASIC";e.shadowMapType===THREE.PCFShadowMap?m="SHADOWMAP_TYPE_PCF":e.shadowMapType===THREE.PCFSoftShadowMap&&(m="SHADOWMAP_TYPE_PCF_SOFT");var t="ENVMAP_TYPE_CUBE",s="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY"; if(e.envMap){switch(d.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:t="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:t="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:t="ENVMAP_TYPE_SPHERE"}switch(d.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:s="ENVMAP_MODE_REFRACTION"}switch(d.combine){case THREE.MultiplyOperation:r="ENVMAP_BLENDING_MULTIPLY"; -break;case THREE.MixOperation:r="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:r="ENVMAP_BLENDING_ADD"}}var u,v;u=[];for(var y in g)v=g[y],!1!==v&&(v="#define "+y+" "+v,u.push(v));u=u.join("\n");g=f.createProgram();d instanceof THREE.RawShaderMaterial?b=d="":(d=["precision "+e.precision+" float;","precision "+e.precision+" int;",u,e.supportsVertexTextures?"#define VERTEX_TEXTURES":"",b.gammaInput?"#define GAMMA_INPUT":"",b.gammaOutput?"#define GAMMA_OUTPUT":"","#define MAX_DIR_LIGHTS "+e.maxDirLights, -"#define MAX_POINT_LIGHTS "+e.maxPointLights,"#define MAX_SPOT_LIGHTS "+e.maxSpotLights,"#define MAX_HEMI_LIGHTS "+e.maxHemiLights,"#define MAX_SHADOWS "+e.maxShadows,"#define MAX_BONES "+e.maxBones,e.map?"#define USE_MAP":"",e.envMap?"#define USE_ENVMAP":"",e.envMap?"#define "+s:"",e.lightMap?"#define USE_LIGHTMAP":"",e.bumpMap?"#define USE_BUMPMAP":"",e.normalMap?"#define USE_NORMALMAP":"",e.specularMap?"#define USE_SPECULARMAP":"",e.alphaMap?"#define USE_ALPHAMAP":"",e.vertexColors?"#define USE_COLOR": -"",e.skinning?"#define USE_SKINNING":"",e.useVertexTexture?"#define BONE_TEXTURE":"",e.morphTargets?"#define USE_MORPHTARGETS":"",e.morphNormals?"#define USE_MORPHNORMALS":"",e.wrapAround?"#define WRAP_AROUND":"",e.doubleSided?"#define DOUBLE_SIDED":"",e.flipSided?"#define FLIP_SIDED":"",e.shadowMapEnabled?"#define USE_SHADOWMAP":"",e.shadowMapEnabled?"#define "+m:"",e.shadowMapDebug?"#define SHADOWMAP_DEBUG":"",e.shadowMapCascade?"#define SHADOWMAP_CASCADE":"",e.sizeAttenuation?"#define USE_SIZEATTENUATION": -"",e.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"","uniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\nattribute vec2 uv2;\n#ifdef USE_COLOR\n\tattribute vec3 color;\n#endif\n#ifdef USE_MORPHTARGETS\n\tattribute vec3 morphTarget0;\n\tattribute vec3 morphTarget1;\n\tattribute vec3 morphTarget2;\n\tattribute vec3 morphTarget3;\n\t#ifdef USE_MORPHNORMALS\n\t\tattribute vec3 morphNormal0;\n\t\tattribute vec3 morphNormal1;\n\t\tattribute vec3 morphNormal2;\n\t\tattribute vec3 morphNormal3;\n\t#else\n\t\tattribute vec3 morphTarget4;\n\t\tattribute vec3 morphTarget5;\n\t\tattribute vec3 morphTarget6;\n\t\tattribute vec3 morphTarget7;\n\t#endif\n#endif\n#ifdef USE_SKINNING\n\tattribute vec4 skinIndex;\n\tattribute vec4 skinWeight;\n#endif\n"].join("\n"), -b=["precision "+e.precision+" float;","precision "+e.precision+" int;",e.bumpMap||e.normalMap?"#extension GL_OES_standard_derivatives : enable":"",u,"#define MAX_DIR_LIGHTS "+e.maxDirLights,"#define MAX_POINT_LIGHTS "+e.maxPointLights,"#define MAX_SPOT_LIGHTS "+e.maxSpotLights,"#define MAX_HEMI_LIGHTS "+e.maxHemiLights,"#define MAX_SHADOWS "+e.maxShadows,e.alphaTest?"#define ALPHATEST "+e.alphaTest:"",b.gammaInput?"#define GAMMA_INPUT":"",b.gammaOutput?"#define GAMMA_OUTPUT":"",e.useFog&&e.fog?"#define USE_FOG": -"",e.useFog&&e.fogExp?"#define FOG_EXP2":"",e.map?"#define USE_MAP":"",e.envMap?"#define USE_ENVMAP":"",e.envMap?"#define "+t:"",e.envMap?"#define "+s:"",e.envMap?"#define "+r:"",e.lightMap?"#define USE_LIGHTMAP":"",e.bumpMap?"#define USE_BUMPMAP":"",e.normalMap?"#define USE_NORMALMAP":"",e.specularMap?"#define USE_SPECULARMAP":"",e.alphaMap?"#define USE_ALPHAMAP":"",e.vertexColors?"#define USE_COLOR":"",e.metal?"#define METAL":"",e.wrapAround?"#define WRAP_AROUND":"",e.doubleSided?"#define DOUBLE_SIDED": -"",e.flipSided?"#define FLIP_SIDED":"",e.shadowMapEnabled?"#define USE_SHADOWMAP":"",e.shadowMapEnabled?"#define "+m:"",e.shadowMapDebug?"#define SHADOWMAP_DEBUG":"",e.shadowMapCascade?"#define SHADOWMAP_CASCADE":"",e.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"","uniform mat4 viewMatrix;\nuniform vec3 cameraPosition;\n"].join("\n"));n=new THREE.WebGLShader(f,f.VERTEX_SHADER,d+n);p=new THREE.WebGLShader(f,f.FRAGMENT_SHADER,b+p);f.attachShader(g,n);f.attachShader(g,p);void 0!==q&&f.bindAttribLocation(g, -0,q);f.linkProgram(g);!1===f.getProgramParameter(g,f.LINK_STATUS)&&(console.error("THREE.WebGLProgram: Could not initialise shader."),console.error("gl.VALIDATE_STATUS",f.getProgramParameter(g,f.VALIDATE_STATUS)),console.error("gl.getError()",f.getError()));""!==f.getProgramInfoLog(g)&&console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",f.getProgramInfoLog(g));f.deleteShader(n);f.deleteShader(p);q="viewMatrix modelViewMatrix projectionMatrix normalMatrix modelMatrix cameraPosition morphTargetInfluences bindMatrix bindMatrixInverse".split(" "); -e.useVertexTexture?(q.push("boneTexture"),q.push("boneTextureWidth"),q.push("boneTextureHeight")):q.push("boneGlobalMatrices");e.logarithmicDepthBuffer&&q.push("logDepthBufFC");for(var C in h)q.push(C);h=q;C={};q=0;for(b=h.length;qL;L++)A[L]=new THREE.Vector3,w[L]=new THREE.Vector3;A=D.shadowCascadeNearZ[K];D=D.shadowCascadeFarZ[K];w[0].set(-1,-1,A);w[1].set(1,-1,A);w[2].set(-1,1,A);w[3].set(1,1,A);w[4].set(-1,-1,D);w[5].set(1,-1,D);w[6].set(-1,1,D);w[7].set(1,1,D);M.originalCamera=v;w=new THREE.Gyroscope;w.position.copy(z.shadowCascadeOffset);w.add(M);w.add(M.target);v.add(w);z.shadowCascadeArray[E]=M;console.log("Created virtualLight",M)}K= -z;A=E;D=K.shadowCascadeArray[A];D.position.copy(K.position);D.target.position.copy(K.target.position);D.lookAt(D.target);D.shadowCameraVisible=K.shadowCameraVisible;D.shadowDarkness=K.shadowDarkness;D.shadowBias=K.shadowCascadeBias[A];w=K.shadowCascadeNearZ[A];K=K.shadowCascadeFarZ[A];D=D.pointsFrustum;D[0].z=w;D[1].z=w;D[2].z=w;D[3].z=w;D[4].z=K;D[5].z=K;D[6].z=K;D[7].z=K;T[G]=M;G++}else T[G]=z,G++;u=0;for(F=T.length;uK;K++)A=D[K],A.copy(w[K]),A.unproject(E),A.applyMatrix4(G.matrixWorldInverse),A.xt.x&&(t.x=A.x),A.yt.y&&(t.y=A.y),A.zt.z&&(t.z=A.z);G.left=m.x;G.right=t.x;G.top=t.y;G.bottom=m.y;G.updateProjectionMatrix()}G=z.shadowMap;w=z.shadowMatrix;E=z.shadowCamera;E.position.setFromMatrixPosition(z.matrixWorld);s.setFromMatrixPosition(z.target.matrixWorld);E.lookAt(s);E.updateMatrixWorld();E.matrixWorldInverse.getInverse(E.matrixWorld);z.cameraHelper&& -(z.cameraHelper.visible=z.shadowCameraVisible);z.shadowCameraVisible&&z.cameraHelper.update();w.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);w.multiply(E.projectionMatrix);w.multiply(E.matrixWorldInverse);q.multiplyMatrices(E.projectionMatrix,E.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(G);a.clear();r.length=0;e(c,c,E);z=0;for(G=r.length;zT;T++)B[T]=new THREE.Vector3,A[T]=new THREE.Vector3;B=w.shadowCascadeNearZ[H];w=w.shadowCascadeFarZ[H];A[0].set(-1,-1,B);A[1].set(1,-1,B);A[2].set(-1,1,B);A[3].set(1,1,B);A[4].set(-1,-1,w);A[5].set(1,-1,w);A[6].set(-1,1,w);A[7].set(1,1,w);L.originalCamera=v;A=new THREE.Gyroscope;A.position.copy(z.shadowCascadeOffset);A.add(L);A.add(L.target);v.add(A);z.shadowCascadeArray[D]=L;console.log("Created virtualLight",L)}H= +z;B=D;w=H.shadowCascadeArray[B];w.position.copy(H.position);w.target.position.copy(H.target.position);w.lookAt(w.target);w.shadowCameraVisible=H.shadowCameraVisible;w.shadowDarkness=H.shadowDarkness;w.shadowBias=H.shadowCascadeBias[B];A=H.shadowCascadeNearZ[B];H=H.shadowCascadeFarZ[B];w=w.pointsFrustum;w[0].z=A;w[1].z=A;w[2].z=A;w[3].z=A;w[4].z=H;w[5].z=H;w[6].z=H;w[7].z=H;K[F]=L;F++}else K[F]=z,F++;u=0;for(O=K.length;uH;H++)B=w[H],B.copy(A[H]),B.unproject(D),B.applyMatrix4(F.matrixWorldInverse),B.xt.x&&(t.x=B.x),B.yt.y&&(t.y=B.y),B.zt.z&&(t.z=B.z);F.left=m.x;F.right=t.x;F.top=t.y;F.bottom=m.y;F.updateProjectionMatrix()}F=z.shadowMap;A=z.shadowMatrix;D=z.shadowCamera;D.position.setFromMatrixPosition(z.matrixWorld);s.setFromMatrixPosition(z.target.matrixWorld);D.lookAt(s);D.updateMatrixWorld();D.matrixWorldInverse.getInverse(D.matrixWorld);z.cameraHelper&& +(z.cameraHelper.visible=z.shadowCameraVisible);z.shadowCameraVisible&&z.cameraHelper.update();A.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);A.multiply(D.projectionMatrix);A.multiply(D.matrixWorldInverse);q.multiplyMatrices(D.projectionMatrix,D.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(F);a.clear();r.length=0;e(c,c,D);z=0;for(F=r.length;z 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); -x.compileShader(L);x.compileShader(N);x.attachShader(K,L);x.attachShader(K,N);x.linkProgram(K);G=K;v=x.getAttribLocation(G,"position");y=x.getAttribLocation(G,"uv");c=x.getUniformLocation(G,"uvOffset");d=x.getUniformLocation(G,"uvScale");e=x.getUniformLocation(G,"rotation");f=x.getUniformLocation(G,"scale");g=x.getUniformLocation(G,"color");h=x.getUniformLocation(G,"map");k=x.getUniformLocation(G,"opacity");n=x.getUniformLocation(G,"modelViewMatrix");p=x.getUniformLocation(G,"projectionMatrix");q= -x.getUniformLocation(G,"fogType");m=x.getUniformLocation(G,"fogDensity");t=x.getUniformLocation(G,"fogNear");s=x.getUniformLocation(G,"fogFar");r=x.getUniformLocation(G,"fogColor");u=x.getUniformLocation(G,"alphaTest");K=document.createElement("canvas");K.width=8;K.height=8;L=K.getContext("2d");L.fillStyle="white";L.fillRect(0,0,8,8);E=new THREE.Texture(K);E.needsUpdate=!0}x.useProgram(G);x.enableVertexAttribArray(v);x.enableVertexAttribArray(y);x.disable(x.CULL_FACE);x.enable(x.BLEND);x.bindBuffer(x.ARRAY_BUFFER, -F);x.vertexAttribPointer(v,2,x.FLOAT,!1,16,0);x.vertexAttribPointer(y,2,x.FLOAT,!1,16,8);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,z);x.uniformMatrix4fv(p,!1,M.projectionMatrix.elements);x.activeTexture(x.TEXTURE0);x.uniform1i(h,0);L=K=0;(N=T.fog)?(x.uniform3f(r,N.color.r,N.color.g,N.color.b),N instanceof THREE.Fog?(x.uniform1f(t,N.near),x.uniform1f(s,N.far),x.uniform1i(q,1),L=K=1):N instanceof THREE.FogExp2&&(x.uniform1f(m,N.density),x.uniform1i(q,2),L=K=2)):(x.uniform1i(q,0),L=K=0);for(var N=0,S=b.length;N< -S;N++){var Q=b[N];Q._modelViewMatrix.multiplyMatrices(M.matrixWorldInverse,Q.matrixWorld);Q.z=-Q._modelViewMatrix.elements[14]}b.sort(C);for(var U=[],N=0,S=b.length;Ne)return null;var f=[],g=[],h=[],k,n,p;if(0=q--){console.log("Warning, unable to triangulate polygon!");break}k=n;e<=k&&(k=0);n=k+1;e<=n&&(n=0);p=n+1;e<=p&&(p=0);var m;a:{var t=m=void 0,s=void 0,r=void 0,u=void 0,v=void 0,y=void 0,C=void 0,x=void 0, -t=a[g[k]].x,s=a[g[k]].y,r=a[g[n]].x,u=a[g[n]].y,v=a[g[p]].x,y=a[g[p]].y;if(1E-10>(r-t)*(y-s)-(u-s)*(v-t))m=!1;else{var F=void 0,z=void 0,G=void 0,E=void 0,w=void 0,D=void 0,A=void 0,T=void 0,M=void 0,K=void 0,M=T=A=x=C=void 0,F=v-r,z=y-u,G=t-v,E=s-y,w=r-t,D=u-s;for(m=0;me)return null;var f=[],g=[],h=[],k,n,p;if(0=q--){console.log("Warning, unable to triangulate polygon!");break}k=n;e<=k&&(k=0);n=k+1;e<=n&&(n=0);p=n+1;e<=p&&(p=0);var m;a:{var t=m=void 0,s=void 0,r=void 0,u=void 0,v=void 0,y=void 0,E=void 0,x=void 0, +t=a[g[k]].x,s=a[g[k]].y,r=a[g[n]].x,u=a[g[n]].y,v=a[g[p]].x,y=a[g[p]].y;if(1E-10>(r-t)*(y-s)-(u-s)*(v-t))m=!1;else{var O=void 0,z=void 0,F=void 0,D=void 0,A=void 0,w=void 0,B=void 0,K=void 0,L=void 0,H=void 0,L=K=B=x=E=void 0,O=v-r,z=y-u,F=t-v,D=s-y,A=r-t,w=u-s;for(m=0;mE||E>G)return[];k=n*p-k*q;if(0>k||k>G)return[]}else{if(0d?[]:k==d?g?[]:[f]:a<=d?[f,h]: +THREE.Shape.Utils={triangulateShape:function(a,b){function c(a,b,c){return a.x!=b.x?a.xD||D>F)return[];k=n*p-k*q;if(0>k||k>F)return[]}else{if(0d?[]:k==d?g?[]:[f]:a<=d?[f,h]: [f,n]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]);if(!d)return!1; -d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;cK){console.log("Infinite Loop! Holes left:"+ -n.length+", Probably Hole outside Shape!");break}for(q=D;qh;h++)n=k[h].x+":"+k[h].y, +d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;cH){console.log("Infinite Loop! Holes left:"+ +n.length+", Probably Hole outside Shape!");break}for(q=w;qh;h++)n=k[h].x+":"+k[h].y, n=p[n],void 0!==n&&(k[h]=n);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a, b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)};THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()}; THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve;THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b=new THREE.Vector2;b.x=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);return b}; @@ -709,27 +708,27 @@ f;d.nextKey=g}g.time>=this.currentTime?f.interpolate(g,this.currentTime):f.inter THREE.KeyFrameAnimation.prototype.getPrevKeyWith=function(a,b,c){b=this.data.hierarchy[b].keys;for(c=0<=c?c:c+b.length;0<=c;c--)if(b[c].hasTarget(a))return b[c];return b[b.length-1]};THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);a=this.duration/this.frames;var b=Math.floor(this.currentTime/a);b!=this.currentFrame&&(this.mesh.morphTargetInfluences[this.lastFrame]=0,this.mesh.morphTargetInfluences[this.currentFrame]= 1,this.mesh.morphTargetInfluences[b]=0,this.lastFrame=this.currentFrame,this.currentFrame=b);this.mesh.morphTargetInfluences[b]=this.currentTime%a/a;this.mesh.morphTargetInfluences[this.lastFrame]=1-this.mesh.morphTargetInfluences[b]}}}; -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,r){var u,v=h.widthSegments,y=h.heightSegments,C=e/2,x=f/2,F=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",y=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",v=h.depthSegments;var z=v+1,G=y+1,E=e/v,w=f/y,D=new THREE.Vector3;D[u]=0=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)== -Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(H=a.length;0<=--H;){c=H;d=H-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;ed&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;c Date: Sat, 24 Jan 2015 23:32:04 +0100 Subject: [PATCH 052/333] Code clean up. --- editor/js/Menubar.File.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/editor/js/Menubar.File.js b/editor/js/Menubar.File.js index 913096b4d5b614..bfd4d48dbaea10 100644 --- a/editor/js/Menubar.File.js +++ b/editor/js/Menubar.File.js @@ -89,7 +89,7 @@ Menubar.File = function ( editor ) { output = JSON.stringify( output, null, '\t' ); output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' ); - exportString( output, "geometry.json" ); + exportString( output, 'geometry.json' ); } ); options.add( option ); @@ -114,7 +114,7 @@ Menubar.File = function ( editor ) { output = JSON.stringify( output, null, '\t' ); output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' ); - exportString( output, "model.json" ); + exportString( output, 'model.json' ); } ); options.add( option ); @@ -130,7 +130,7 @@ Menubar.File = function ( editor ) { output = JSON.stringify( output, null, '\t' ); output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' ); - exportString( output, "scene.json" ); + exportString( output, 'scene.json' ); } ); options.add( option ); @@ -153,7 +153,7 @@ Menubar.File = function ( editor ) { var exporter = new THREE.OBJExporter(); - exportString( exporter.parse( object ), "model.obj" ); + exportString( exporter.parse( object ), 'model.obj' ); } ); options.add( option ); @@ -167,7 +167,7 @@ Menubar.File = function ( editor ) { var exporter = new THREE.STLExporter(); - exportString( exporter.parse( editor.scene ), "model.stl" ); + exportString( exporter.parse( editor.scene ), 'model.stl' ); } ); options.add( option ); @@ -279,10 +279,10 @@ Menubar.File = function ( editor ) { var blob = new Blob( [ output ], { type: 'text/plain' } ); var objectURL = URL.createObjectURL( blob ); - var link = document.createElement('a'); + var link = document.createElement( 'a' ); link.href = objectURL; - link.download = filename || "data.json"; - link.target = "_blank"; + link.download = filename || 'data.json'; + link.target = '_blank'; link.click(); }; From d4ccf0fcb4c1755e39d1967d2bdc7aa441492438 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 25 Jan 2015 00:46:14 +0100 Subject: [PATCH 053/333] transparency to opacity change. --- examples/models/animated/elderlyWalk.js | 4 +- examples/models/animated/monster/monster.js | 2 +- examples/models/animated/sittingBox.js | 4 +- examples/models/ctm/camaro/camaro.js | 18 +++---- examples/models/skinned/UCS/umich_ucs.js | 4 +- .../models/skinned/human_walk_0_female.js | 2 +- examples/models/skinned/knight.js | 2 +- examples/models/skinned/marine/m4.js | 2 +- examples/models/skinned/marine/marine.js | 2 +- .../models/skinned/marine/marine_anims.js | 2 +- .../models/skinned/marine/marine_ikrig.js | 2 +- examples/models/skinned/simple/simple.js | 2 +- examples/obj/blenderscene/scene.Cube.js | 2 +- examples/obj/blenderscene/scene.Monkey.js | 2 +- examples/obj/blenderscene/scene.Plane.js | 2 +- examples/obj/box/box.js | 2 +- examples/obj/camaro/CamaroNoUv_bin.js | 18 +++---- examples/obj/cubecolors/cube_fvc.js | 2 +- examples/obj/cubecolors/cubecolors.js | 2 +- examples/obj/f50/F50NoUv_bin.js | 50 +++++++++---------- examples/obj/female02/Female02_bin.js | 12 ++--- examples/obj/female02/Female02_slim.js | 12 ++--- examples/obj/gallardo/GallardoNoUv_bin.js | 14 +++--- .../obj/gallardo/parts/gallardo_body_bin.js | 14 +++--- .../obj/gallardo/parts/gallardo_wheel_bin.js | 4 +- examples/obj/leeperrysmith/LeePerrySmith.js | 2 +- examples/obj/lightmap/lightmap.js | 6 +-- examples/obj/male02/Male02_bin.js | 10 ++-- examples/obj/male02/Male02_dds.js | 10 ++-- examples/obj/male02/Male02_slim.js | 10 ++-- examples/obj/veyron/VeyronNoUv_bin.js | 16 +++--- examples/obj/veyron/parts/veyron_body_bin.js | 16 +++--- examples/obj/veyron/parts/veyron_wheel_bin.js | 4 +- examples/obj/walt/WaltHead_bin.js | 2 +- examples/obj/walt/WaltHead_slim.js | 2 +- examples/scenes/test_scene.js | 2 +- src/loaders/Loader.js | 2 +- 37 files changed, 132 insertions(+), 132 deletions(-) diff --git a/examples/models/animated/elderlyWalk.js b/examples/models/animated/elderlyWalk.js index 76ae13da713f4f..209fb042db981e 100644 --- a/examples/models/animated/elderlyWalk.js +++ b/examples/models/animated/elderlyWalk.js @@ -24,7 +24,7 @@ "colorSpecular" : [0.10135135054588318, 0.10135135054588318, 0.10135135054588318], "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "vertexColors" : false }, @@ -37,7 +37,7 @@ "colorSpecular" : [0.10135135054588318, 0.10135135054588318, 0.10135135054588318], "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "vertexColors" : false }], diff --git a/examples/models/animated/monster/monster.js b/examples/models/animated/monster/monster.js index f74681a03de1a9..de77a54a87779d 100644 --- a/examples/models/animated/monster/monster.js +++ b/examples/models/animated/monster/monster.js @@ -26,7 +26,7 @@ "mapDiffuseWrap" : ["repeat", "repeat"], "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "vertexColors" : false }], diff --git a/examples/models/animated/sittingBox.js b/examples/models/animated/sittingBox.js index 87aba32f27e226..25a1ba8d0e2f4f 100644 --- a/examples/models/animated/sittingBox.js +++ b/examples/models/animated/sittingBox.js @@ -31,7 +31,7 @@ "colorSpecular" : [0.10135135054588318, 0.10135135054588318, 0.10135135054588318], "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "vertexColors" : false }, @@ -44,7 +44,7 @@ "colorSpecular" : [0.10135135054588318, 0.10135135054588318, 0.10135135054588318], "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "vertexColors" : false }], diff --git a/examples/models/ctm/camaro/camaro.js b/examples/models/ctm/camaro/camaro.js index 4ac0b6ae749b4b..d812e17fc0c95f 100644 --- a/examples/models/ctm/camaro/camaro.js +++ b/examples/models/ctm/camaro/camaro.js @@ -16,7 +16,7 @@ "mapDiffuse" : "car-ao.png", "opticalDensity" : 1.0, "specularCoef" : 778.431373, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -30,7 +30,7 @@ "mapDiffuse" : "car-ao.png", "opticalDensity" : 1.0, "specularCoef" : 15.686275, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -44,7 +44,7 @@ "mapDiffuse" : "car-ao.png", "opticalDensity" : 1.0, "specularCoef" : 0.0, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -58,7 +58,7 @@ "mapDiffuse" : "car-ao.png", "opticalDensity" : 1.0, "specularCoef" : 15.686275, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -72,7 +72,7 @@ "mapDiffuse" : "car-ao.png", "opticalDensity" : 1.0, "specularCoef" : 778.431373, - "transparency" : 0.34 + "opacity" : 0.34 }, { @@ -86,7 +86,7 @@ "mapDiffuse" : "car-ao.png", "opticalDensity" : 1.0, "specularCoef" : 3.921569, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -100,7 +100,7 @@ "mapDiffuse" : "car-ao.png", "opticalDensity" : 1.0, "specularCoef" : 778.431373, - "transparency" : 1.0 + "opacity" : 1.0 }, @@ -115,7 +115,7 @@ "mapDiffuse" : "plane-ao-256.png", "opticalDensity" : 1.0, "specularCoef" : 96.078431, - "transparency" : 1.0 + "opacity" : 1.0 } ] -} \ No newline at end of file +} diff --git a/examples/models/skinned/UCS/umich_ucs.js b/examples/models/skinned/UCS/umich_ucs.js index 3609df6eff6e7c..30c59297f96102 100644 --- a/examples/models/skinned/UCS/umich_ucs.js +++ b/examples/models/skinned/UCS/umich_ucs.js @@ -20,7 +20,7 @@ "colorDiffuse" : [0.5880, 0.5880, 0.5880], "colorAmbient" : [0.5880, 0.5880, 0.5880], "colorSpecular" : [0.9000, 0.9000, 0.9000], -"transparency" : 1.0, +"opacity" : 1.0, "specularCoef" : 10.0, "mapDiffuse" : "skins/Caucasion_Male.jpg", "vertexColors" : false @@ -1682,4 +1682,4 @@ } ] } -} \ No newline at end of file +} diff --git a/examples/models/skinned/human_walk_0_female.js b/examples/models/skinned/human_walk_0_female.js index be57ddc94432f6..059e94dc44b961 100644 --- a/examples/models/skinned/human_walk_0_female.js +++ b/examples/models/skinned/human_walk_0_female.js @@ -28,7 +28,7 @@ "depthWrite" : true, "shading" : "Phong", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }, diff --git a/examples/models/skinned/knight.js b/examples/models/skinned/knight.js index 64a797c3401005..cd8049b0c13bc9 100644 --- a/examples/models/skinned/knight.js +++ b/examples/models/skinned/knight.js @@ -28,7 +28,7 @@ "depthWrite" : true, "shading" : "Phong", "specularCoef" : 150, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }], diff --git a/examples/models/skinned/marine/m4.js b/examples/models/skinned/marine/m4.js index 76d71283e1cdea..8bce0f09465a16 100644 --- a/examples/models/skinned/marine/m4.js +++ b/examples/models/skinned/marine/m4.js @@ -30,7 +30,7 @@ "mapDiffuseWrap" : ["repeat", "repeat"], "shading" : "Lambert", "specularCoef" : 34, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : true, "vertexColors" : false }], diff --git a/examples/models/skinned/marine/marine.js b/examples/models/skinned/marine/marine.js index de0054cb43752d..c931fe8d1c0530 100644 --- a/examples/models/skinned/marine/marine.js +++ b/examples/models/skinned/marine/marine.js @@ -30,7 +30,7 @@ "mapDiffuseWrap" : ["repeat", "repeat"], "shading" : "Lambert", "specularCoef" : 9, - "transparency" : 0.0, + "opacity" : 0.0, "transparent" : true, "vertexColors" : false }], diff --git a/examples/models/skinned/marine/marine_anims.js b/examples/models/skinned/marine/marine_anims.js index e87b90ef504803..bba0b20a044c63 100644 --- a/examples/models/skinned/marine/marine_anims.js +++ b/examples/models/skinned/marine/marine_anims.js @@ -30,7 +30,7 @@ "mapDiffuseWrap" : ["repeat", "repeat"], "shading" : "Lambert", "specularCoef" : 9, - "transparency" : 0.0, + "opacity" : 0.0, "transparent" : true, "vertexColors" : false }], diff --git a/examples/models/skinned/marine/marine_ikrig.js b/examples/models/skinned/marine/marine_ikrig.js index ceb041d33b12e9..98654f95333416 100644 --- a/examples/models/skinned/marine/marine_ikrig.js +++ b/examples/models/skinned/marine/marine_ikrig.js @@ -30,7 +30,7 @@ "mapDiffuseWrap" : ["repeat", "repeat"], "shading" : "Lambert", "specularCoef" : 9, - "transparency" : 0.0, + "opacity" : 0.0, "transparent" : true, "vertexColors" : false }], diff --git a/examples/models/skinned/simple/simple.js b/examples/models/skinned/simple/simple.js index 3da9b052bc3d00..6cacf7b3337593 100644 --- a/examples/models/skinned/simple/simple.js +++ b/examples/models/skinned/simple/simple.js @@ -29,7 +29,7 @@ "depthWrite" : true, "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }], diff --git a/examples/obj/blenderscene/scene.Cube.js b/examples/obj/blenderscene/scene.Cube.js index ff5823ca48f94d..f8a2a605020dfb 100644 --- a/examples/obj/blenderscene/scene.Cube.js +++ b/examples/obj/blenderscene/scene.Cube.js @@ -28,7 +28,7 @@ "depthWrite" : true, "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }], diff --git a/examples/obj/blenderscene/scene.Monkey.js b/examples/obj/blenderscene/scene.Monkey.js index ea32c1026b4825..2d39edf652bf56 100644 --- a/examples/obj/blenderscene/scene.Monkey.js +++ b/examples/obj/blenderscene/scene.Monkey.js @@ -28,7 +28,7 @@ "depthWrite" : true, "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }], diff --git a/examples/obj/blenderscene/scene.Plane.js b/examples/obj/blenderscene/scene.Plane.js index d5d8eb5c5b9966..3deefea6536c31 100644 --- a/examples/obj/blenderscene/scene.Plane.js +++ b/examples/obj/blenderscene/scene.Plane.js @@ -28,7 +28,7 @@ "depthWrite" : true, "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }], diff --git a/examples/obj/box/box.js b/examples/obj/box/box.js index f6482762ec838f..f4e41852004e5b 100644 --- a/examples/obj/box/box.js +++ b/examples/obj/box/box.js @@ -21,7 +21,7 @@ "colorSpecular" : [0.8, 0.8, 0.8], "illumination" : 2, "specularCoef" : 0.0, - "transparency" : 1.0 + "opacity" : 1.0 }], "buffers": "box.bin" diff --git a/examples/obj/camaro/CamaroNoUv_bin.js b/examples/obj/camaro/CamaroNoUv_bin.js index d63aa2c5d6d6b8..17fd2b99a80aae 100644 --- a/examples/obj/camaro/CamaroNoUv_bin.js +++ b/examples/obj/camaro/CamaroNoUv_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 782.352941, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -35,7 +35,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 782.352941, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -48,7 +48,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 7.843137, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -61,7 +61,7 @@ "illumination" : 1, "opticalDensity" : 1.0, "specularCoef" : 0.0, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -74,7 +74,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 782.352941, - "transparency" : 0.34 + "opacity" : 0.34 }, { @@ -87,7 +87,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -100,7 +100,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -113,7 +113,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -126,7 +126,7 @@ "illumination" : 1, "opticalDensity" : 1.0, "specularCoef" : 0.0, - "transparency" : 1.0 + "opacity" : 1.0 }], "buffers": "CamaroNoUv_bin.bin" diff --git a/examples/obj/cubecolors/cube_fvc.js b/examples/obj/cubecolors/cube_fvc.js index 16d1e2baed0f1f..ef9c382447143e 100644 --- a/examples/obj/cubecolors/cube_fvc.js +++ b/examples/obj/cubecolors/cube_fvc.js @@ -27,7 +27,7 @@ "depthWrite" : true, "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : true }], diff --git a/examples/obj/cubecolors/cubecolors.js b/examples/obj/cubecolors/cubecolors.js index d83db59a3358f0..3953b6a37d876d 100644 --- a/examples/obj/cubecolors/cubecolors.js +++ b/examples/obj/cubecolors/cubecolors.js @@ -27,7 +27,7 @@ "depthWrite" : true, "shading" : "Lambert", "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : true }], diff --git a/examples/obj/f50/F50NoUv_bin.js b/examples/obj/f50/F50NoUv_bin.js index 7602f791b7c4fc..51bf1b79d91acb 100644 --- a/examples/obj/f50/F50NoUv_bin.js +++ b/examples/obj/f50/F50NoUv_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -35,7 +35,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -48,7 +48,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.6 + "opacity" : 0.6 }, { @@ -61,7 +61,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -74,7 +74,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -87,7 +87,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -100,7 +100,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -113,7 +113,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -126,7 +126,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -139,7 +139,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -152,7 +152,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -165,7 +165,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -178,7 +178,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -191,7 +191,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -204,7 +204,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -217,7 +217,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -230,7 +230,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.4 + "opacity" : 0.4 }, { @@ -243,7 +243,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -256,7 +256,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.3 + "opacity" : 0.3 }, { @@ -269,7 +269,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.3 + "opacity" : 0.3 }, { @@ -282,7 +282,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -295,7 +295,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -308,7 +308,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -321,7 +321,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -334,7 +334,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 98.039216, - "transparency" : 0.0 + "opacity" : 0.0 }], "buffers": "F50NoUv_bin.bin" diff --git a/examples/obj/female02/Female02_bin.js b/examples/obj/female02/Female02_bin.js index 40a30b7a3fa686..791bf3ba32125f 100644 --- a/examples/obj/female02/Female02_bin.js +++ b/examples/obj/female02/Female02_bin.js @@ -23,7 +23,7 @@ "mapDiffuse" : "03_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -37,7 +37,7 @@ "mapDiffuse" : "02_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -51,7 +51,7 @@ "mapDiffuse" : "02_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -65,7 +65,7 @@ "mapDiffuse" : "03_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -79,7 +79,7 @@ "mapDiffuse" : "01_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -93,7 +93,7 @@ "mapDiffuse" : "01_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }], "buffers": "Female02_bin.bin" diff --git a/examples/obj/female02/Female02_slim.js b/examples/obj/female02/Female02_slim.js index c12ceb7502075e..9c8bc4b78c791d 100644 --- a/examples/obj/female02/Female02_slim.js +++ b/examples/obj/female02/Female02_slim.js @@ -26,7 +26,7 @@ "mapDiffuse" : "03_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -40,7 +40,7 @@ "mapDiffuse" : "02_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -54,7 +54,7 @@ "mapDiffuse" : "02_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -68,7 +68,7 @@ "mapDiffuse" : "03_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -82,7 +82,7 @@ "mapDiffuse" : "01_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -96,7 +96,7 @@ "mapDiffuse" : "01_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }], "vertices": [1525,10464,868,1404,10444,1171,1576,9895,1152,1356,10926,946,1475,10477,497,1314,10917,626,1180,10484,84,1050,10897,303,759,10476,-194,1316,9895,-81,1645,9910,355,1698,9907,807,1629,9259,1204,1293,9298,1544,1215,9872,1466,1085,10397,1469,602,10311,1664,518,10807,1607,100,10765,1618,457,11337,1603,89,11339,1663,-275,11334,1569,-233,11783,1619,-656,11296,1434,-576,11752,1493,-551,12086,1482,-823,12136,1120,-820,11740,1169,-895,11703,780,-892,11269,1160,-958,11280,822,-853,11666,453,-899,11265,527,-582,11636,134,-633,11266,212,-170,11613,20,-580,12098,-6,-196,12039,-86,-597,12411,-66,-211,12296,-160,-552,13008,-156,-226,12762,-274,-501,13583,-300,-211,13513,-324,-537,13976,-281,-79,13906,-289,-614,14221,-99,-125,14394,30,212,14399,20,457,13885,-231,481,14383,30,489,14536,100,744,14344,76,714,14503,146,494,14682,165,698,14655,209,646,14838,236,774,14816,373,724,15029,255,610,15006,191,466,14833,195,281,14819,198,284,14685,165,259,14550,98,86,14531,187,-200,14426,380,-643,14289,309,-859,14148,-147,-743,13966,-302,-682,13611,-277,-785,13138,-26,-934,12889,285,-878,12551,298,-888,12173,314,-916,12179,705,-903,12454,1040,-769,12354,1257,-515,12299,1484,-230,12053,1626,72,11774,1680,430,11769,1626,839,11352,1524,963,10855,1491,1240,10903,1236,1114,11376,1288,1079,11698,1275,779,11728,1541,750,12016,1545,422,12024,1657,68,12036,1703,-237,12280,1620,-248,12405,1790,84,12396,1779,107,12656,1874,-256,12673,1905,-507,12702,1859,-530,12415,1689,-730,12746,1701,-752,12492,1483,-957,12769,987,-958,12831,669,-950,12492,663,-867,13179,312,-966,13159,669,-945,13111,949,-907,13037,1365,-903,12745,1360,-702,13002,1680,-480,12964,1828,-245,12942,1875,16,12917,1836,139,12906,1815,256,12892,1862,496,12871,1943,445,12613,1954,417,12367,1815,434,12248,1646,745,12240,1552,714,12349,1757,971,12354,1614,957,12595,1852,701,12598,1956,736,12848,1944,988,12838,1848,1258,12822,1588,1194,12550,1563,1330,12536,1212,1387,12839,1162,1219,13019,1628,1363,13176,1315,1507,12980,871,1580,13219,888,1660,12966,523,1668,13299,733,1860,13571,678,1962,13178,496,1739,12806,294,1478,12943,517,1452,12881,864,1406,12552,871,1208,12266,1242,1012,12219,1391,82,12270,1697,1071,11994,1245,1211,11721,939,1258,11994,892,1342,12266,881,1478,12603,481,1477,12875,509,1445,12892,158,1270,13542,-203,1273,13106,-25,1390,13344,-274,1473,13176,-393,1373,12953,-119,1493,12740,-399,1544,12572,-127,1904,12846,-238,1801,12545,91,2081,12707,94,2026,12975,304,2215,13210,152,2104,13428,296,2085,13601,-26,1904,13943,114,1712,13868,-113,1902,13605,-259,2184,13370,-133,2302,12920,-40,2274,13101,-316,2106,13145,-544,1846,13084,-635,1631,12940,-583,1717,13309,-458,2004,13388,-379,1623,13500,-342,1520,13689,-215,1506,13948,-96,1649,14041,176,1290,13952,-115,1417,13733,-186,981,13497,-228,880,12657,-164,1209,12800,-23,1138,12248,101,1357,12306,488,1253,11977,535,1206,11690,612,1236,11379,975,1209,11370,673,1008,11655,257,1063,11961,158,706,11973,1,635,11606,89,995,11340,326,595,11304,154,635,10885,72,254,10417,-229,867,9888,-368,1387,9238,-166,1723,9258,309,1791,9277,779,1698,8697,1251,1339,8739,1619,760,8777,1823,728,9281,1749,681,9791,1708,181,9732,1693,135,10273,1649,-341,10244,1543,-311,10729,1513,-732,10703,1327,-977,10695,1075,-1029,10201,1009,-775,10217,1325,-1104,9648,1002,-826,9654,1349,-906,9126,1335,-1179,9125,979,-982,8562,1275,-1241,8561,914,-1065,7971,1209,-1311,7970,822,-1391,7220,719,-1163,7217,1177,-1252,6479,1188,-1489,6484,693,-1460,6501,166,-1386,7236,262,-1353,7986,355,-1314,8564,452,-1246,9117,558,-1169,9658,644,-1095,10207,730,-1036,10699,811,-969,10727,497,-1034,10235,365,-1094,9689,200,-1150,9140,97,-1212,8583,8,-1231,8007,-68,-1264,7259,-183,-1278,6527,-334,-834,7293,-596,-824,6563,-758,-182,6587,-895,-209,7316,-722,186,6597,-745,221,7332,-612,404,7321,-525,196,8079,-540,399,8068,-492,382,8715,-550,567,8695,-511,347,9272,-540,934,8667,-439,914,9263,-460,317,9850,-416,1416,8632,-172,1772,8656,336,1846,8683,793,1766,8102,1290,1394,8157,1656,788,8203,1882,417,8195,1887,424,8744,1808,191,9218,1723,-352,9686,1575,-399,9138,1596,-482,8575,1568,-574,7975,1572,-651,7228,1580,-713,6508,1621,-343,6551,1848,-256,7279,1746,-176,8019,1715,-61,8602,1693,188,8660,1769,145,8114,1810,68,7378,1888,-24,6654,2038,341,6729,2117,379,7456,1995,780,7463,1986,760,6737,2120,1434,7405,1734,1466,6676,1852,1806,7354,1371,1882,8056,824,1787,8024,381,1926,7307,882,1958,6572,938,1835,6622,1449,1827,7272,401,1437,7250,-111,1416,8001,-132,915,8052,-393,902,7284,-412,904,6542,-512,1458,6506,-177,1858,6531,386,610,6564,-585,543,7294,-471,554,8047,-460,421,6586,-646,-244,9802,-431,-239,9226,-564,-248,8656,-621,179,8689,-587,-225,8066,-639,-818,8040,-479,-802,8615,-412,-765,9178,-338,-723,9743,-197,-707,10290,-17,-672,10761,200,-221,11273,94,-251,10804,19,187,11277,100,194,10845,8,220,11608,42,256,11993,-45,278,12242,-111,770,12219,-63,325,12673,-241,409,13472,-296,988,13905,-176,1437,14124,190,1435,14057,518,1044,14286,105,857,14451,268,824,14627,337,812,14771,601,802,15033,497,889,15186,430,933,15342,371,761,15219,175,849,15446,92,976,15509,328,1005,15745,274,634,15701,-45,637,15415,10,612,15184,89,429,15172,50,438,14973,162,262,14970,156,134,14969,195,130,14783,307,117,14636,262,-22,14479,419,-202,14290,735,-643,14176,647,-981,14211,227,-1121,13979,-195,-898,13876,-317,-685,13609,-275,-529,13476,39,-691,13396,-260,-520,13348,44,-675,13334,345,-880,13322,647,-970,13340,700,-814,13141,578,-1173,13139,555,-1188,13399,610,-1386,13522,376,-1400,13223,322,-1184,12799,519,-1383,12873,274,-1028,12841,90,-848,12755,512,-590,13166,347,-536,13141,33,-709,13155,-235,-596,12786,-23,-624,12754,278,-714,12830,-255,-965,12874,-377,-1237,12928,-305,-1447,12926,-49,-1450,13294,-6,-1434,13615,35,-1312,13928,469,-1148,13756,697,-1017,13616,820,-971,13341,693,-883,13428,1095,-836,13227,1413,-666,13264,1535,-640,13599,1247,-451,13261,1678,-227,13252,1718,-20,13219,1683,187,13217,1641,384,13177,1726,576,13172,1801,802,13136,1809,1038,13093,1713,1136,13409,1431,1228,13657,1152,937,13723,1253,899,13469,1491,694,13483,1499,709,13692,1324,981,14164,847,696,14000,1090,661,14220,930,510,13930,1125,514,14188,965,651,14461,898,508,14449,916,504,14635,948,395,14612,965,372,14686,1102,529,14733,1077,358,14663,1267,575,14745,1232,484,14695,1330,507,14724,1357,575,14759,1282,627,14798,1233,689,14829,1127,694,14848,1168,779,14931,1043,774,14969,1104,817,14998,996,829,15087,1096,844,15057,936,878,15194,902,838,15202,1115,912,15368,914,929,15284,843,953,15375,862,988,15339,791,969,15380,806,1051,15362,746,1047,15316,734,984,15269,780,947,15229,789,923,15261,785,975,15230,737,991,15235,752,1068,15318,705,1115,15415,677,1100,15413,702,1141,15513,666,1066,15486,733,1054,15628,734,1008,15505,797,1013,15608,823,1086,15675,752,1125,15655,677,1144,15686,651,1099,15738,711,1128,15698,640,1150,15624,603,1042,15633,649,1156,15542,596,1164,15623,616,1139,15601,658,1168,15540,610,1156,15487,634,1101,15410,665,1055,15319,691,968,15288,693,881,15185,842,839,15041,881,801,14990,914,752,14904,970,644,14802,1024,626,14660,930,774,14496,818,826,14309,781,902,14383,517,1081,14291,463,1374,13872,845,1503,13493,982,1623,13758,776,1954,13823,426,1693,13960,483,847,14566,555,731,14701,851,806,14962,825,834,15009,649,880,15124,655,942,15268,664,1028,15451,644,1043,15553,604,1043,15770,586,977,16018,275,605,15974,-33,365,15937,-90,395,15664,-102,416,15388,-40,189,15369,-34,244,15146,52,77,15149,105,-36,15356,2,-151,15230,261,-89,15085,330,11,14952,416,49,14732,523,45,14566,472,61,14497,744,-19,14397,692,89,14279,870,164,14461,847,216,14219,934,135,13968,1085,-20,14074,1014,-144,13780,1234,-341,13855,1117,-631,13886,978,-936,13867,846,-1000,14114,576,-1319,14017,124,-1240,13581,-249,-1251,13279,-272,-965,13198,-355,-972,13478,-351,-406,13604,1352,-208,13577,1403,-20,13444,1508,48,13694,1304,320,13933,1111,265,13631,1335,492,13648,1351,465,13394,1560,364,14198,958,299,14449,895,290,14624,927,172,14637,884,83,14668,784,104,14747,970,217,14701,1046,140,14700,1188,218,14668,1303,350,14671,1337,429,14695,1372,510,14770,1383,425,14745,1413,400,14855,1429,323,14841,1431,316,14915,1427,247,14840,1413,258,14912,1415,310,14935,1460,374,14924,1426,361,14940,1462,435,14944,1418,434,14971,1442,388,14969,1491,433,14995,1471,472,14999,1422,467,15023,1430,492,15037,1407,461,15036,1432,451,15047,1427,479,15047,1409,499,15047,1402,509,15045,1403,512,15022,1400,530,15003,1391,485,14970,1405,542,14892,1365,476,14870,1398,573,14809,1337,623,14857,1297,676,14916,1241,738,14974,1200,781,15090,1205,786,15201,1241,855,15345,1112,764,15324,1328,783,15413,1311,795,15484,1292,881,15505,1111,798,15551,1255,877,15662,1077,793,15660,1233,865,15787,1109,927,15663,958,920,15793,987,980,15831,851,943,16055,858,1003,16041,576,1027,15663,717,985,15647,797,983,15604,860,931,15503,910,966,15504,858,1004,15631,854,1038,15674,832,1072,15724,776,1085,15748,699,1141,15484,619,880,15179,783,753,14913,898,1053,15737,771,1024,15698,820,1001,15464,823,995,15404,835,964,15447,799,894,16053,1010,855,15911,1105,757,16190,1190,807,16349,1033,626,16395,1184,454,16315,1369,391,16422,1261,408,16533,1122,692,16451,1067,176,16423,1287,180,16542,1120,-36,16487,1077,-25,16379,1218,-229,16307,1097,-281,16352,968,-364,16229,914,-315,16080,1081,-383,15922,880,-336,15788,984,-351,15663,858,-322,15665,989,-326,15534,831,-301,15541,957,-281,15386,993,-288,15378,786,-244,15250,797,-312,15373,728,-275,15249,737,-331,15328,687,-315,15270,702,-279,15252,679,-287,15319,672,-340,15367,660,-380,15337,586,-391,15260,550,-443,15351,505,-400,15260,523,-446,15323,471,-384,15258,514,-342,15174,562,-326,15177,550,-318,15313,507,-237,15165,571,-203,15151,547,-113,15022,554,-44,14919,560,-43,14875,739,3,14836,821,-8,14826,893,35,14762,1060,79,14742,1177,127,14713,1236,184,14691,1324,109,14762,1290,167,14735,1348,263,14678,1355,345,14680,1379,336,14724,1419,248,14727,1395,177,14840,1368,115,14848,1321,59,14799,1240,18,14779,1099,-54,14846,958,-69,14882,1018,7,14848,1173,68,14878,1297,147,14936,1371,100,14959,1347,57,14993,1341,-18,14955,1253,-39,15001,1263,-120,14997,1114,-55,14892,1119,-144,14987,997,-94,14904,903,-62,14902,826,-102,14945,785,-121,14958,838,-174,15087,795,-163,15079,736,-149,15074,678,-207,15145,670,-229,15166,725,-179,15098,1011,-155,15105,1146,-59,15069,1281,76,15012,1361,93,14996,1360,111,14981,1360,150,14966,1389,197,14920,1394,260,14929,1451,188,14946,1417,223,14952,1474,258,14946,1490,305,14951,1499,240,14989,1490,184,14995,1451,178,14969,1445,151,15004,1400,149,14991,1398,126,14999,1370,109,15004,1363,117,15011,1373,103,15027,1385,142,15057,1439,133,15108,1436,175,15120,1474,168,15183,1466,104,15164,1435,140,15235,1461,65,15219,1423,93,15308,1443,49,15316,1425,25,15211,1401,-53,15302,1358,0,15382,1392,-105,15373,1335,-1,15456,1375,-99,15449,1327,-78,15489,1345,-111,15497,1334,-136,15514,1309,-152,15458,1290,-160,15539,1279,-189,15479,1248,-230,15379,1188,-162,15363,1287,-208,15311,1210,-224,15234,1002,-175,15228,1233,-239,15445,1150,-219,15510,1186,-202,15554,1243,-172,15554,1275,-142,15551,1297,-125,15530,1312,-103,15513,1333,-76,15506,1347,-6,15514,1366,-2,15523,1369,-70,15519,1353,1,15537,1358,-83,15537,1332,-36,15595,1373,-99,15579,1342,-107,15582,1342,-73,15598,1365,-121,15590,1361,-80,15612,1381,-7,15607,1387,-13,15617,1402,49,15603,1397,-14,15620,1417,50,15608,1414,-17,15638,1422,-101,15636,1397,-37,15687,1449,-118,15672,1408,-146,15722,1399,-183,15656,1358,-199,15690,1344,-218,15656,1286,-196,15590,1301,-229,15610,1244,-212,15575,1243,-238,15587,1197,-251,15553,1126,-286,15688,1129,-241,15729,1225,-208,15777,1307,-135,15828,1383,-32,15738,1462,65,15707,1485,31,15685,1477,41,15661,1460,52,15628,1427,97,15636,1447,108,15662,1484,113,15684,1490,140,15635,1471,126,15611,1431,88,15609,1421,77,15585,1405,71,15579,1393,46,15597,1392,58,15586,1374,93,15561,1383,96,15568,1398,113,15595,1412,137,15563,1408,117,15542,1394,104,15543,1382,93,15529,1383,90,15538,1372,89,15544,1376,70,15534,1372,71,15541,1375,87,15557,1367,-11,15492,1372,63,15487,1388,87,15426,1433,72,15372,1431,137,15380,1479,145,15462,1454,92,15505,1392,64,15517,1380,143,15537,1418,172,15473,1477,179,15407,1526,168,15324,1508,143,15334,1478,151,15303,1478,156,15290,1504,153,15252,1497,139,15279,1464,161,15222,1497,184,15197,1478,182,15222,1515,223,15245,1511,192,15224,1555,208,15222,1586,225,15217,1601,201,15247,1613,230,15249,1644,213,15290,1643,259,15251,1652,265,15218,1625,272,15197,1573,308,15225,1610,288,15255,1650,323,15259,1625,297,15298,1652,253,15294,1661,251,15329,1648,211,15322,1636,211,15442,1552,198,15349,1600,180,15318,1553,165,15263,1551,180,15231,1552,192,15286,1607,203,15505,1499,183,15557,1459,155,15583,1430,178,15604,1460,200,15565,1475,245,15519,1518,247,15449,1563,286,15450,1560,291,15514,1508,329,15422,1541,307,15360,1611,293,15331,1644,325,15299,1621,340,15335,1570,359,15344,1528,384,15405,1504,387,15359,1503,385,15327,1502,379,15313,1527,366,15284,1572,357,15249,1570,388,15245,1520,390,15276,1521,414,15263,1489,405,15307,1491,447,15345,1479,457,15411,1470,432,15461,1468,364,15484,1477,332,15489,1493,308,15570,1472,287,15574,1484,242,15574,1488,238,15618,1482,151,15654,1490,140,15743,1510,86,15829,1498,-20,15838,1452,-47,15943,1436,-159,15912,1362,-56,16143,1379,-241,16072,1255,-85,16260,1314,-291,15955,1163,-282,15818,1154,-238,15851,1229,177,16306,1391,183,16195,1445,201,15961,1498,212,15842,1517,219,15764,1528,231,15666,1503,313,15670,1506,302,15759,1527,339,15855,1524,449,15887,1500,478,15791,1514,386,15739,1518,344,15708,1513,331,15655,1490,303,15616,1472,335,15602,1448,361,15586,1430,358,15559,1440,419,15538,1425,451,15527,1427,523,15510,1428,532,15436,1446,492,15361,1470,497,15263,1467,468,15202,1472,396,15206,1489,375,15217,1497,365,15241,1533,347,15240,1570,326,15234,1598,322,15255,1521,312,15205,1551,323,15186,1539,276,15179,1549,232,15177,1530,237,15197,1544,204,15184,1490,229,15129,1515,210,15090,1515,206,15058,1499,153,15035,1432,150,15019,1404,160,15017,1397,192,15019,1426,183,15027,1438,214,15036,1471,258,15072,1527,261,15104,1534,264,15131,1526,283,15135,1525,285,15103,1536,289,15072,1534,262,15048,1492,262,15037,1452,301,15034,1457,295,15040,1501,328,15055,1498,320,15078,1533,380,15053,1488,378,15076,1517,419,15051,1462,447,15065,1462,451,15089,1470,364,15106,1531,310,15109,1539,303,15135,1529,338,15140,1526,357,15200,1505,401,15143,1497,451,15140,1468,505,15068,1426,498,15050,1412,458,15051,1436,414,15042,1449,380,15044,1457,338,15044,1459,492,15047,1401,540,15059,1408,513,15130,1434,516,15195,1451,658,15236,1383,541,15264,1454,607,15369,1425,647,15450,1411,627,15524,1401,596,15558,1414,525,15547,1426,517,15567,1419,439,15572,1410,446,15556,1418,419,15572,1405,415,15562,1415,402,15574,1412,388,15570,1422,409,15593,1415,401,15599,1429,424,15615,1428,414,15620,1439,377,15622,1438,358,15635,1455,354,15687,1509,425,15725,1517,496,15742,1503,604,15799,1475,575,15900,1455,456,15995,1488,436,16193,1429,653,16163,1346,585,15988,1438,670,15867,1397,671,15779,1433,660,15742,1444,585,15744,1480,578,15705,1466,492,15690,1474,425,15666,1465,423,15700,1499,377,15664,1476,397,15641,1452,435,15647,1454,440,15643,1437,494,15672,1468,570,15682,1459,497,15669,1454,496,15659,1438,445,15638,1433,439,15625,1413,529,15653,1430,507,15589,1410,419,15591,1401,417,15578,1409,436,15578,1413,511,15575,1422,590,15574,1415,628,15573,1409,654,15595,1389,617,15587,1406,639,15608,1390,619,15617,1400,603,15599,1410,594,15606,1401,638,15640,1389,598,15651,1413,580,15585,1419,605,15655,1414,565,15663,1430,566,15678,1447,624,15671,1439,634,15692,1440,698,15681,1392,680,15667,1405,656,15655,1409,614,15666,1436,641,15642,1403,673,15649,1388,687,15643,1362,736,15709,1342,708,15750,1380,728,15828,1323,763,15925,1260,699,15948,1324,743,16061,1268,798,15799,1239,759,15689,1298,727,15671,1339,722,15649,1337,678,15625,1364,654,15632,1378,663,15639,1384,684,15544,1375,713,15452,1376,699,15399,1388,646,15316,1406,674,15144,1356,673,15074,1336,566,15046,1392,527,15041,1404,587,14931,1350,663,15024,1322,724,15573,1341,759,15611,1286,222,15028,1441,126,15009,1364,118,15008,1363,136,15012,1374,186,15015,1436,238,15021,1465,219,15035,1435,300,15038,1455,299,15027,1476,300,14997,1500,361,15002,1502,362,15033,1477,383,15052,1451,419,15039,1460,421,15019,1475,352,14956,1500,-179,15579,1318,-165,15564,1302,-154,15571,1326,-133,15594,1362,-146,15612,1361,-87,15615,1392,-136,15563,1324,-153,15556,1301,-130,15561,1311,-110,15542,1326,-92,15528,1339,-67,15161,1309,82,15086,1390,63,15148,1405,-76,15242,1333,-140,15313,1303,-286,15208,661,-266,15140,653,-225,15109,670,-261,15107,625,-242,15105,613,-327,15175,595,-342,15219,605,-345,15411,463,-429,15323,460,-449,15378,433,-369,15488,506,-385,15624,441,-217,15387,206,-281,15614,143,-309,15886,145,-399,15898,434,-389,15691,712,-374,15520,575,-463,15535,478,-462,15459,439,-478,15455,449,-464,15373,444,-457,15437,495,-396,15480,587,-371,15466,682,-349,15468,725,-346,15511,662,-373,15490,714,-399,15552,675,-400,15917,722,-425,15586,620,-443,15592,543,-441,15569,622,-457,15579,553,-478,15520,486,-458,15493,516,-440,15519,597,-410,15526,685,117,15924,-83,146,15651,-94,401,14439,931,-267,10359,-250,1458,12792,131,1446,10505,1238,1412,10472,1265,1435,10483,1281,1413,10489,1225,1466,10516,1176,1430,10502,1168,1429,10499,1162,1468,10518,1170,1420,10506,1155,1467,10528,1167,1419,10494,1140,1471,10529,1155,1478,10566,1106,1429,10543,1084,1456,10543,1043,1498,10561,1059,1478,10541,1005,1516,10559,1022,1535,10518,870,1462,10471,1000,1506,10444,879,1588,10480,753,1543,10404,806,1632,10465,635,1538,10302,690,1678,10455,561,1620,10310,543,1675,10175,578,1724,10229,478,1668,10119,637,1759,10099,615,1707,10099,742,1774,10070,758,1692,10116,823,1794,10046,903,1683,10182,876,1716,10176,942,1767,10094,1027,1828,10037,1032,1748,10066,1082,1807,10018,1085,1948,10100,1105,1903,10051,1217,1928,10182,1136,1958,10210,1059,1900,10273,1015,1962,10223,963,2001,10241,829,1938,10333,837,1944,10393,725,1840,10447,862,1848,10478,750,1923,10448,615,2023,10349,589,1881,10500,515,1844,10513,590,1746,10485,451,1913,10546,479,1768,10542,410,1940,10577,394,1808,10573,339,1872,10718,151,2021,10730,217,2038,11018,-129,1810,10646,67,1911,10933,-227,1864,10823,-310,1831,10556,3,1896,10458,-44,1934,10701,-375,2044,10603,-422,2008,10377,-62,2258,10574,-378,2141,10387,-7,2229,10478,97,2369,10677,-266,2493,10889,-668,2356,10857,-150,2527,11098,-522,2582,10994,-907,2634,11241,-751,2767,11400,-1099,2490,11416,-671,2677,11463,-994,2708,11545,-1081,2777,11514,-1199,2757,11695,-1262,2743,11671,-1091,2606,12156,-816,2501,12221,-1051,2321,12219,-1191,2609,11699,-1426,2444,11632,-1497,2673,11478,-1413,2679,11246,-1271,2495,11211,-1377,2420,10887,-1040,2357,10770,-799,2104,10843,-848,1991,10979,-799,1928,11140,-711,2010,11247,-604,2192,11320,-494,2098,11421,-788,2294,11488,-687,2415,11670,-927,2227,11625,-1027,2322,11699,-1130,2494,11714,-1059,2646,11574,-927,2502,11994,-657,2374,12407,-366,2448,12602,-560,2279,12669,-810,2064,12623,-954,2154,12133,-1210,2031,11975,-1084,2296,11575,-1405,2325,11443,-1404,2503,11432,-1467,2288,11284,-1353,2163,10991,-1052,2046,11134,-999,1992,11306,-907,2120,11505,-1137,2218,11349,-1273,2259,11452,-1307,2190,11589,-1250,2260,11447,-1075,2458,11483,-948,2298,11842,-626,2066,11788,-757,1872,12166,-425,2151,12248,-290,1981,12771,103,1705,12693,9,1590,12755,-139,1784,12233,-592,1991,11853,-913,2236,11520,-1204,1805,12344,-769,1579,12845,-291,1683,13016,-431,1912,12518,-924,1814,13132,-509,2054,13182,-434,2229,13116,-189,2161,12920,8,2385,11272,-460,2221,11001,-89,2163,10625,184,2096,10484,362,2068,10423,462,2024,10388,507,2059,10270,560,2012,10306,712,2050,10136,813,2034,10114,930,1980,10147,997,2029,10086,1017,2038,10008,944,2007,10046,1086,1955,9958,1223,1889,10007,1220,1811,9970,1131,1854,9970,991,1831,9912,1096,1907,9928,968,1887,9869,1094,2018,9971,1037,1976,9892,1177,2052,9930,1012,2031,9863,1069,1983,9903,1084,1911,9888,1010,1934,9873,927,1931,9844,970,1994,9840,904,1978,9804,959,2071,9872,970,2052,9816,1031,2065,9952,964,2072,9985,885,2080,10023,791,2061,10203,667,2086,10178,508,2088,10252,440,2132,10267,363,2147,10343,272,2068,10268,181,2053,10185,259,2040,10163,357,2034,10107,447,2062,9949,604,2103,10067,647,2070,9911,744,2070,9885,884,1951,9825,829,1839,9910,848,1810,9931,718,1929,9833,701,1914,9893,567,1795,9974,579,1780,10130,410,1908,10061,390,1906,10163,297,1821,10232,302,1833,10263,241,1780,10356,291,1776,10312,340,1700,10402,384,1674,10341,439,1721,10460,508,1714,10451,347,1760,10518,263,1814,10434,205,1865,10344,153,1935,10179,224,1955,10263,139,1800,10530,657,1748,10549,740,1678,10556,814,1586,10553,895,1645,10547,926,1719,10543,880,1774,10540,839,1817,10525,770,1808,10483,874,1775,10513,886,1720,10458,960,1683,10484,970,1595,10505,1068,1556,10561,1042,1541,10565,1081,1532,10570,1127,1529,10520,1181,1514,10528,1190,1507,10518,1191,1501,10520,1195,1482,10505,1251,1465,10485,1285,1433,10479,1289,1415,10470,1274,1413,10462,1280,1409,10464,1270,1410,10480,1222,1404,10463,1265,1405,10479,1223,1401,10464,1217,1407,10436,1201,1422,10430,1148,1445,10454,1061,1443,10386,1181,1484,10414,1055,1534,10412,1067,1493,10384,1193,1532,10408,1215,1573,10437,1089,1578,10488,1111,1565,10463,1082,1575,10512,1093,1572,10445,1082,1531,10419,1064,1528,10436,1059,1480,10441,1044,1486,10423,1038,1448,10479,1036,1532,10394,925,1580,10386,961,1651,10419,985,1685,10366,977,1666,10284,959,1669,10312,941,1682,10249,1043,1732,10176,1062,1721,10129,1113,1641,10019,1271,1667,9960,1240,1723,9915,1243,1802,9937,1383,1876,10120,1253,1848,10235,1140,1858,10343,1070,1866,10348,970,1788,10411,1018,1732,10420,971,1661,10327,1068,1642,10295,1131,1674,10241,1107,1745,10183,1117,1607,10147,1260,1664,10109,1264,1821,10240,1212,1721,10148,1370,1782,10308,1236,1821,10341,1146,1748,10387,1130,1811,10170,1247,1717,10043,1412,1698,10021,1460,1654,9994,1348,1678,9949,1317,1716,9907,1319,1788,9909,1430,1757,9884,1457,1753,9968,1464,1701,9918,1496,1672,9988,1485,1612,9838,1531,1543,9868,1526,1623,9971,1371,1795,10020,1391,1655,9927,1335,1698,9879,1347,1622,9771,1500,1607,9750,1513,1569,9799,1549,1522,9853,1541,1505,9834,1535,1512,9859,1428,1487,9849,1421,1542,9821,1393,1551,9834,1368,1580,9776,1405,1561,9758,1396,1582,9739,1509,1527,9769,1536,1446,9791,1510,1436,9804,1418,1464,9762,1385,1527,9812,1384,1505,9719,1394,1521,9699,1485,1498,9749,1527,1486,9738,1529,1443,9770,1521,1379,9734,1486,1374,9744,1421,1397,9706,1392,1436,9669,1401,1445,9654,1465,1503,9696,1501,1475,9733,1518,1438,9757,1510,1384,9724,1499,1338,9685,1472,1342,9679,1486,1343,9673,1484,1340,9675,1474,1348,9697,1439,1360,9667,1424,1354,9648,1474,1376,9630,1461,1390,9646,1425,1384,9628,1456,1440,9656,1481,1487,9697,1494,1439,9661,1481,1481,9695,1498,1469,9728,1517,1436,9663,1491,1416,9687,1511,1393,9716,1505,1436,9750,1514,1389,9722,1498,1351,9674,1491,1340,9663,1480,1347,9665,1488,1351,9643,1481,1347,9642,1474,1366,9630,1471,1372,9634,1479,1358,9647,1489,1383,9635,1480,1378,9631,1472,1365,9629,1464,1336,9664,1474,1384,9628,1472,1366,9652,1492,1602,9791,1379,1525,9884,1404,1719,10350,1227,1575,10206,1277,1597,10133,1300,1638,10106,1310,1708,10128,1405,1610,10063,1314,1675,10103,1411,1670,10184,1423,1616,10133,1447,1588,10197,1421,1491,10092,1487,1460,10076,1379,1530,10149,1323,1616,10228,1417,1634,10243,1382,1709,10227,1355,1575,10174,1318,1563,10102,1300,1489,10028,1358,1537,9993,1370,1569,10008,1477,1553,10070,1487,1518,10035,1516,1470,10076,1506,1444,10049,1409,1471,10009,1386,1512,9976,1401,1553,9986,1495,1482,9945,1394,1441,9982,1381,1409,10024,1404,1396,9941,1407,1437,9905,1420,1524,9967,1491,1463,9915,1501,1442,9966,1527,1478,9999,1520,1392,9992,1510,1448,10050,1501,1368,9979,1429,1326,9930,1460,1346,9891,1440,1387,9863,1452,1403,9866,1508,1450,9916,1518,1433,9957,1533,1394,9978,1526,1337,9937,1517,1310,9891,1492,1321,9862,1485,1352,9846,1487,1353,9839,1518,1400,9872,1522,1435,9914,1515,1423,9949,1528,1418,9945,1529,1390,9964,1521,1389,9959,1526,1349,9930,1528,1345,9932,1529,1307,9889,1524,1310,9882,1528,1325,9860,1533,1347,9842,1523,1338,9841,1528,1340,9844,1533,1349,9846,1532,1354,9852,1537,1345,9851,1538,1331,9864,1545,1325,9859,1541,1320,9878,1541,1313,9873,1537,1322,9886,1541,1315,9883,1536,1355,9927,1535,1314,9889,1537,1309,9873,1531,1320,9855,1536,1378,9907,1543,1338,9870,1545,1397,9881,1530,1399,9877,1522,1431,9913,1520,1355,9844,1531,1664,10322,929,1618,10329,917,1558,10350,843,1582,10245,773,1645,10189,838,1548,10462,1196,1523,10466,1245,1504,10489,1256,1492,10500,1255,1489,10499,1252,1467,10478,1291,1458,10473,1297,1457,10480,1290,1432,10472,1296,1432,10465,1299,1412,10455,1281,1409,10454,1270,1435,10466,1292,1461,10467,1299,1470,10469,1293,1480,10468,1292,1451,10426,1277,1403,10449,1263,1417,10422,1252,1490,10441,1280,1473,10480,1291,2008,9815,1122,1950,9829,1149,1884,9820,1074,1897,9776,1042,1943,9746,1029,2011,9753,1104,1991,9781,1157,1946,9819,1167,1903,9810,1098,1918,9779,1064,1910,9775,1060,1955,9747,1060,2011,9741,1119,1947,9733,1058,1864,9715,1095,1908,9683,1088,1996,9731,1126,1943,9668,1166,1962,9749,1172,1936,9803,1170,1885,9734,1207,1849,9752,1131,1888,9803,1102,1868,9703,1122,1904,9669,1119,1938,9650,1180,1887,9655,1115,1856,9693,1120,1849,9730,1157,1875,9721,1225,1829,9717,1154,1821,9661,1121,1853,9627,1116,1920,9640,1180,1868,9603,1172,1853,9635,1208,1879,9656,1212,1812,9664,1211,1845,9625,1212,1813,9648,1216,1765,9626,1197,1761,9639,1164,1799,9685,1153,1782,9617,1134,1861,9705,1222,1912,9683,1214,1937,9717,1192,1811,9586,1131,1817,9569,1161,1858,9599,1186,1837,9622,1206,1809,9639,1208,1771,9617,1204,1738,9591,1186,1740,9603,1163,1741,9584,1186,1750,9581,1146,1754,9563,1181,1771,9552,1166,1774,9567,1140,1776,9550,1161,1773,9551,1173,1778,9549,1172,1814,9573,1175,1813,9574,1183,1841,9598,1187,1833,9619,1205,1799,9589,1203,1779,9611,1206,1808,9634,1210,1775,9616,1202,1744,9586,1195,1745,9582,1193,1743,9574,1189,1739,9576,1185,1749,9559,1181,1753,9559,1186,1765,9550,1174,1770,9553,1180,1759,9561,1190,1777,9554,1179,1764,9565,1192,1751,9582,1197,1749,9575,1194,1763,9550,1169,1845,9600,1183,1815,9569,1174,1910,9811,1305,1908,9890,1315,1834,9909,1341,1748,9874,1260,1766,9815,1233,1821,9777,1224,1920,9808,1314,1891,9863,1351,1837,9912,1354,1790,9886,1261,1808,9846,1231,1849,9811,1233,1867,9818,1198,1909,9808,1307,1861,9837,1355,1831,9903,1344,1743,9813,1371,1719,9831,1262,1791,9909,1234,1825,9869,1194,1743,9788,1230,1787,9750,1229,1816,9726,1337,1810,9788,1370,1772,9748,1393,1727,9796,1391,1707,9803,1297,1734,9768,1267,1765,9728,1258,1804,9705,1355,1748,9703,1257,1714,9753,1264,1678,9789,1302,1666,9713,1264,1706,9667,1266,1780,9692,1352,1717,9641,1344,1694,9684,1390,1732,9715,1393,1643,9728,1380,1683,9674,1392,1642,9707,1390,1581,9681,1359,1576,9696,1301,1635,9751,1300,1708,9777,1387,1606,9662,1266,1643,9619,1269,1652,9598,1325,1702,9637,1361,1673,9670,1382,1637,9696,1378,1588,9670,1370,1545,9637,1344,1554,9652,1312,1548,9628,1345,1571,9622,1293,1566,9597,1342,1591,9578,1325,1601,9596,1290,1598,9576,1319,1648,9600,1341,1687,9639,1355,1646,9604,1342,1681,9636,1360,1668,9666,1381,1636,9689,1381,1592,9668,1369,1551,9631,1357,1552,9625,1355,1549,9616,1351,1546,9618,1345,1560,9592,1342,1564,9593,1349,1582,9577,1335,1587,9581,1343,1570,9595,1356,1597,9581,1343,1593,9578,1335,1581,9577,1328,1598,9575,1334,1644,9606,1352,1622,9630,1376,1597,9662,1375,1560,9625,1361,1557,9617,1358,1578,9600,1359,275,4985,1312,601,4694,1387,620,4975,1510,298,4732,1213,232,4649,857,256,4112,1101,170,4080,810,240,3487,1043,168,3486,756,288,2526,963,207,2520,752,259,1636,953,207,1628,724,145,1231,680,218,1220,974,51,1002,660,198,1008,1011,185,810,1045,38,764,611,78,548,971,114,586,517,114,401,884,559,575,431,753,386,760,79,-3,1442,974,-24,1162,1000,-24,1614,277,-7,1915,774,-18,2160,772,150,2168,994,157,1623,982,179,1169,830,530,825,701,748,482,439,756,101,733,981,567,454,989,171,197,997,206,416,1252,358,532,1247,355,446,1599,443,580,1593,477,533,2483,349,749,2477,462,624,3464,210,949,3475,370,1054,3480,778,1001,3996,353,1115,4055,841,1104,4603,890,984,4382,426,639,4375,295,650,3941,198,287,4027,368,345,4418,422,390,4759,572,641,4697,404,338,4949,629,656,4917,507,299,5142,659,673,5115,528,701,5468,513,932,5106,684,1023,5456,662,720,5740,460,1119,5716,611,824,6512,232,1282,6483,394,886,7339,76,1379,7327,253,922,8172,12,1451,8158,194,958,8955,-9,1426,8951,175,1607,8201,806,1576,8990,753,1408,8259,1365,1368,9041,1316,865,8306,1568,881,9073,1501,341,8314,1321,395,9074,1263,215,8273,748,179,7439,799,345,7380,210,328,6532,354,383,8213,149,453,8985,122,278,9034,683,277,5759,576,277,5494,631,145,5458,974,160,5190,963,194,4961,922,264,3496,375,304,2502,449,322,1607,469,299,1258,361,103,764,166,176,616,193,397,611,150,366,337,215,456,323,448,217,328,494,219,340,244,246,-9,280,361,-12,257,432,-13,448,247,-9,484,251,5199,1350,638,5187,1547,960,5160,1378,962,4947,1339,979,4665,1238,577,4096,1254,545,3464,1181,494,2521,1123,453,1633,1119,435,1218,1162,447,1027,1211,500,795,1280,184,650,1163,176,363,1491,73,200,1452,281,174,1922,562,155,2234,561,-13,2226,555,233,2198,306,240,1925,581,430,1669,535,618,1439,959,340,1214,849,590,1038,733,796,948,678,992,949,631,1200,966,707,1228,666,727,1598,740,878,2483,770,935,3450,1068,997,4088,1129,1083,4911,957,973,4684,525,945,4906,652,1076,5139,999,1148,5402,1014,1231,5758,1004,1418,6539,941,1531,7369,856,1337,7426,1402,830,7471,1611,303,7479,1358,182,6602,889,139,5814,959,236,5517,1394,245,5386,1384,653,5402,1576,661,5514,1580,679,5838,1600,247,5839,1412,292,6638,1384,773,6631,1620,1246,6588,1424,1089,5796,1447,1020,5475,1427,987,5344,1414,789,2498,977,635,1614,964,966,224,1636,764,229,2133,-2309,8016,1087,-2275,7967,1093,-2272,8014,1105,-2305,7963,1080,-2326,7969,1056,-2304,7952,1079,-2321,7960,1060,-2318,7951,1054,-2301,7943,1075,-2297,7938,1069,-2275,7950,1085,-2280,7959,1089,-2269,7960,1089,-2261,7956,1083,-2269,7947,1081,-2296,7946,1068,-2316,7948,1048,-2320,7957,1041,-2325,7961,1032,-2324,7961,1050,-2338,8015,1058,-2303,8088,1081,-2267,8080,1103,-2262,8013,1101,-2264,7962,1094,-2251,7959,1085,-2258,8010,1105,-2261,8085,1101,-2303,8096,1081,-2336,8087,1048,-2335,8081,1054,-2337,8014,1048,-2330,7964,1046,-2342,8012,1045,-2348,8093,1049,-2341,8011,1028,-2328,8021,998,-2304,7968,1007,-2318,8077,977,-2274,8036,955,-2319,8179,974,-2264,8183,946,-2211,8185,963,-2221,8037,972,-2187,8034,1015,-2178,8181,1006,-2223,8222,983,-2278,8220,975,-2328,8227,998,-2269,8239,965,-2217,8236,983,-2177,8343,934,-2183,8246,1023,-2140,8364,981,-2174,8392,879,-2086,8439,941,-2080,8508,992,-1994,8585,922,-2115,8690,949,-2165,8571,1010,-2306,8659,930,-2293,8752,846,-2357,8576,894,-2357,8673,820,-2369,8534,869,-2389,8575,819,-2410,8460,837,-2386,8585,755,-2461,8430,780,-2433,8460,687,-2488,8375,693,-2422,8395,623,-2450,8265,651,-2443,8260,559,-2454,8128,595,-2398,8114,539,-2390,7908,604,-2251,8171,590,-2258,7973,644,-2255,8195,659,-2237,8234,567,-2249,8252,648,-2153,8333,603,-2187,8244,512,-2274,8146,574,-2385,8103,541,-2376,8243,503,-2383,8076,467,-2351,7926,586,-2357,7940,510,-2297,7900,477,-2321,8073,414,-2360,8246,427,-2286,8239,379,-2249,8352,380,-2250,8241,331,-2262,8104,361,-2218,8094,317,-2251,8027,391,-2204,7997,363,-2124,8045,389,-2130,8135,351,-2129,8061,441,-2139,8158,406,-2097,8259,326,-2109,8248,393,-2017,8321,364,-2043,8317,499,-1966,8425,533,-1936,8421,386,-2072,8471,305,-2010,8601,329,-1890,8557,426,-2018,8695,328,-1883,8664,423,-1988,8835,329,-1873,8830,415,-1832,8920,352,-1804,8958,474,-1764,9094,440,-1791,9054,328,-1713,9238,259,-1677,9269,391,-1450,9713,141,-1445,9758,299,-1201,10144,19,-1203,10207,191,-1111,10376,-44,-1116,10442,134,-1043,10796,40,-1002,10748,-122,-1025,10964,18,-976,10950,-144,-922,11108,-144,-939,11106,-375,-805,11611,-18,-805,11645,-252,-935,11690,-381,-791,12218,-316,-704,12181,-155,-751,12948,-186,-1037,12289,-373,-1159,11730,-396,-1325,11195,-426,-1098,11154,-462,-1175,10955,-477,-1025,10918,-377,-1084,10704,-365,-1247,10350,-284,-1370,10126,-186,-1605,9727,-14,-1837,9258,188,-1892,9069,264,-1931,8939,279,-2110,8866,361,-2149,8745,351,-2136,8642,351,-2183,8495,350,-2212,8397,339,-2141,8344,293,-2193,8243,285,-2234,8314,330,-2257,8524,444,-2313,8418,434,-2345,8332,425,-2355,8366,495,-2428,8343,544,-2380,8428,547,-2319,8552,537,-2267,8691,527,-2308,8707,626,-2363,8576,634,-2347,8710,743,-2276,8839,746,-2106,8785,864,-2081,8871,804,-2062,8957,772,-2173,8964,682,-2124,9093,658,-2155,9049,469,-2179,8922,505,-2079,8980,302,-2027,9112,281,-1991,9313,213,-1780,9795,1,-1579,10205,-176,-1470,10424,-300,-1285,10734,-437,-1511,10857,-301,-1677,10578,-155,-1759,10327,-40,-1901,9893,149,-2050,9380,372,-2096,9177,428,-2061,9220,606,-1997,9084,744,-1935,8927,744,-1960,8830,776,-1959,8736,848,-1947,8665,765,-1952,8739,667,-1893,8888,614,-1877,9034,712,-1836,9000,584,-1825,9163,652,-1795,9132,545,-1697,9313,509,-1754,9359,598,-1480,9813,439,-1592,9871,487,-1763,9933,476,-1872,9399,623,-2014,9420,546,-1899,9951,347,-1937,9208,678,-1764,10408,177,-1635,10414,332,-1427,10353,388,-1271,10287,353,-1195,10533,297,-1141,10815,197,-1114,10955,134,-981,11131,36,-891,11615,177,-736,12146,96,-710,12924,0,-736,12883,238,-846,12891,377,-838,12158,279,-1016,12176,371,-1034,12897,439,-1296,12954,300,-1303,12259,253,-1362,12985,59,-1412,12299,-6,-1303,11698,189,-1423,11762,-27,-1461,11228,-40,-1312,11182,101,-1309,11031,141,-1470,11059,50,-1487,11065,-170,-1515,10941,147,-1561,10913,-91,-1695,10652,72,-1583,10669,249,-1375,10605,322,-1316,10897,223,-1088,11125,153,-1051,11631,267,-1423,11020,-360,-1449,11240,-243,-1388,11785,-273,-1327,12336,-275,-978,12978,-300,-1270,13022,-210,-1854,8862,518,-1865,8705,554,-1905,8555,565,-2000,8581,656,-1979,8555,736,-2031,8489,869,-2104,8411,794,-2202,8382,855,-2254,8353,897,-2323,8277,986,-2344,8241,1061,-2363,8185,1065,-2346,8104,1032,-2309,8102,1089,-2307,8115,1086,-2241,8102,1107,-2258,8091,1113,-2241,8009,1099,-2214,8018,1077,-2195,8074,1063,-2232,7966,1057,-2189,8176,1064,-2194,8222,1032,-2202,8230,1084,-2191,8287,1076,-2144,8411,1037,-2215,8451,1063,-2294,8568,990,-2335,8515,943,-2359,8448,873,-2395,8309,850,-2508,8318,804,-2514,8301,720,-2522,8195,738,-2471,8183,677,-2471,7988,731,-2359,8031,765,-2347,8208,720,-2365,8042,830,-2358,8238,797,-2313,8262,717,-2333,8292,795,-2236,8347,730,-2301,8376,825,-2174,8389,757,-2233,8375,840,-2112,8403,722,-2305,8209,712,-2456,8155,669,-2443,7942,724,-2445,7957,643,-2393,7861,611,-2287,7924,659,-2261,7995,710,-2309,8006,760,-2449,7897,737,-2440,7869,669,-2379,7826,631,-2269,7893,669,-2275,7925,724,-2297,7947,708,-2338,7949,750,-2431,7860,749,-2407,7810,698,-2341,7715,750,-2331,7723,821,-2319,7696,838,-2307,7663,778,-2265,7662,722,-2241,7651,742,-2257,7642,805,-2221,7628,825,-2218,7660,884,-2290,7681,848,-2161,7735,885,-2212,7771,857,-2241,7779,836,-2252,7819,828,-2316,7923,773,-2205,7815,782,-2205,7789,722,-2281,7692,713,-2198,7752,742,-2204,7783,791,-2179,7780,804,-2164,7741,755,-2116,7707,790,-2123,7735,841,-2065,7683,880,-2062,7658,833,-2047,7628,902,-2102,7683,918,-2140,7629,919,-2210,7638,880,-2210,7618,832,-2196,7621,838,-2193,7636,878,-2144,7614,912,-2083,7601,934,-2090,7587,930,-2144,7614,907,-2190,7629,878,-2190,7618,841,-2146,7606,902,-2085,7585,927,-2094,7582,922,-2140,7587,872,-2118,7588,843,-2073,7569,878,-2086,7569,901,-2077,7567,905,-2068,7568,887,-2067,7569,909,-2084,7578,921,-2075,7581,926,-2060,7573,911,-2070,7586,929,-2078,7593,930,-2074,7635,926,-2066,7577,907,-2051,7574,889,-2055,7579,880,-2058,7570,889,-2063,7572,880,-2111,7594,839,-2161,7611,817,-2161,7617,811,-2108,7592,836,-2063,7571,874,-2053,7582,871,-2047,7618,868,-2098,7603,829,-2172,7614,797,-2169,7630,781,-2073,8456,630,-2167,8241,444,-2223,8141,527,-2203,7969,575,-2251,7982,619,-2353,7901,596,-2341,7876,532,-2329,7887,605,-2247,7962,623,-2262,7957,604,-2212,7970,570,-2226,7958,567,-2221,7937,520,-2197,7937,517,-2295,7873,479,-2276,7860,496,-2128,7871,570,-2136,7894,621,-2174,7894,665,-2230,7796,666,-2301,7839,559,-2240,7779,601,-2197,7956,512,-2218,8120,462,-2272,8125,419,-2248,8024,453,-2233,7980,413,-2198,7977,368,-2149,8032,387,-2128,8043,382,-2181,7971,382,-2074,8007,410,-2077,8034,455,-2139,8077,422,-2154,8057,427,-2170,8072,475,-2182,8165,449,-2183,8055,464,-2241,8006,464,-2217,7997,471,-2160,8069,470,-2106,8033,498,-2139,7955,506,-2192,7958,436,-2110,7929,421,-2151,7937,457,-2119,7916,473,-2102,7913,424,-2090,7981,415,-2090,7920,428,-2090,7996,405,-2048,8004,415,-2036,7946,436,-1991,8003,434,-2002,8030,464,-2059,8032,449,-2106,8025,440,-2098,8012,452,-2115,8007,495,-2130,7943,517,-2114,7950,514,-2111,8026,486,-2068,8032,493,-2057,7975,516,-2083,7927,479,-2056,7942,480,-2043,7939,484,-2044,7964,513,-2036,7948,483,-2035,7970,507,-2031,7949,483,-2030,7967,506,-1997,7984,514,-1996,7986,518,-2000,7998,520,-2009,8028,504,-1954,8026,478,-1955,8010,454,-1940,7988,468,-1941,7992,492,-1951,8004,511,-1967,8028,502,-1956,8008,515,-1955,7996,516,-1952,7996,512,-1945,7997,508,-1955,7989,511,-1995,7977,512,-1987,7959,491,-1948,7978,495,-1942,7981,495,-1949,7990,508,-1938,7987,494,-1935,7993,493,-1944,8002,508,-1935,7990,474,-1936,7985,476,-1941,7979,478,-1946,7976,474,-1982,7959,463,-2018,7949,459,-2022,7951,455,-2028,7941,449,-1980,7963,454,-1982,7964,457,-1942,7979,467,-1941,7981,472,-1942,7988,461,-1981,7971,445,-2182,7772,564,-2201,7746,625,-2169,7753,571,-2140,7848,577,-2161,7864,620,-2186,7860,664,-2219,7777,678,-2195,7781,683,-2185,7878,672,-2165,7887,615,-2136,7866,568,-2149,7760,582,-2086,7863,592,-2108,7893,638,-2131,7883,691,-2123,7803,712,-2155,7748,645,-2109,7763,661,-2096,7762,667,-2106,7788,709,-2086,7773,669,-2068,7771,625,-2062,7783,635,-2008,7797,646,-2012,7798,649,-1963,7813,673,-1963,7816,679,-2013,7791,656,-1969,7808,680,-1958,7819,687,-1961,7826,676,-1956,7826,685,-1968,7825,709,-1987,7874,693,-1978,7858,659,-2015,7868,625,-2007,7810,635,-1962,7827,667,-2076,7782,607,-2036,7897,668,-2056,7887,718,-2051,7830,734,-2046,7814,730,-2092,7797,704,-2080,7775,671,-2086,7792,704,-2043,7804,722,-2046,7813,725,-1993,7827,739,-1995,7842,740,-2008,7872,725,-1988,7837,736,-1988,7827,735,-1992,7818,732,-2027,7785,692,-1978,7807,708,-1971,7811,711,-1964,7812,687,-1964,7818,712,-1961,7826,712,-1978,7836,734,-1978,7829,733,-1983,7820,730,-2058,7780,641,-2057,8464,700,-2328,8391,841,-2316,8396,915,-2324,8442,990,-2333,8294,1053,-2306,8248,1094,-2316,8174,1100,-2262,8186,1135,-2260,8244,1118,-2256,8298,1105,-2299,8299,1085,-2282,8453,1042,-2402,8236,854,-2526,8211,809,-2518,8011,844,-2512,8043,772,-2516,7960,787,-2477,7951,732,-2376,7985,788,-2375,7997,835,-2407,8055,881,-2526,7976,851,-2502,7948,862,-2486,7898,811,-2456,7924,750,-2463,7813,836,-2421,7785,798,-2326,7834,827,-2344,7943,795,-2327,7848,883,-2348,7962,852,-2410,8002,869,-2387,7965,899,-2367,7855,926,-2463,7806,899,-2452,7759,851,-2414,7753,802,-2329,7796,841,-2329,7813,890,-2366,7814,928,-2460,7775,910,-2433,7754,920,-2335,7792,949,-2299,7791,907,-2294,7772,855,-2391,7734,821,-2276,7713,877,-2280,7731,927,-2314,7731,966,-2387,7692,945,-2421,7719,872,-2395,7681,890,-2348,7673,854,-2391,7668,894,-2358,7658,864,-2307,7616,886,-2260,7648,901,-2260,7660,949,-2294,7664,981,-2343,7634,970,-2389,7673,937,-2380,7663,900,-2376,7666,935,-2351,7625,961,-2310,7587,977,-2321,7581,971,-2350,7626,957,-2317,7578,967,-2354,7621,950,-2376,7659,933,-2376,7658,902,-2353,7610,921,-2331,7609,895,-2307,7571,921,-2321,7571,942,-2315,7565,945,-2305,7566,928,-2307,7562,949,-2296,7564,931,-2300,7562,952,-2289,7565,931,-2303,7569,949,-2289,7571,924,-2268,7601,957,-2309,7581,971,-2289,7612,978,-2266,7600,924,-2285,7575,917,-2320,7610,889,-2298,7570,917,-2298,7569,923,-2322,7612,893,-2351,7654,876,-2353,7648,879,-2311,7571,965,-2324,7579,962,-2318,7573,960,-2305,7572,969,-2267,7953,1030,-2204,8771,452,-2205,8670,445,-2258,8790,533,-2280,8831,621,106,4686,538,81,4872,738,-229,4589,593,267,4756,210,262,5011,406,294,4739,-281,180,4980,-34,37,4754,-499,86,4401,-764,398,4407,-479,373,4257,-49,227,4167,197,-124,4100,239,-555,4638,351,-503,4158,14,-589,4692,-24,-541,4253,-281,-376,3602,-283,-24,3555,-74,-135,2770,-714,-168,2845,-924,63,2052,-1010,114,2720,-497,217,1998,-814,231,1562,-914,71,1658,-1139,33,1476,-1234,198,1347,-971,-14,1313,-1350,137,1092,-1045,-137,1107,-1429,75,860,-1037,-275,792,-1469,-11,600,-970,-373,478,-1195,-288,680,-1593,-396,433,-1249,-278,508,-1700,-395,288,-1358,539,300,-1296,208,86,-863,211,250,-782,538,463,-1173,622,976,-1506,629,1038,-1343,696,1342,-1678,740,1420,-1482,777,1692,-1838,708,1593,-1317,672,1857,-1710,465,1757,-1964,503,1608,-2005,708,1565,-1923,668,1319,-2058,532,1348,-2113,545,1043,-2290,651,1021,-2247,614,1160,-1872,284,1429,-1844,392,1207,-1962,432,936,-2159,604,900,-2090,125,1550,-1731,-67,1184,-1625,30,1100,-1745,68,1687,-1553,69,1838,-1390,32,2134,-1237,36,2964,-1161,-421,3754,-555,-301,4397,-701,-213,3916,-885,146,3961,-943,276,3008,-1199,453,3910,-689,439,3739,-339,291,3624,-108,356,2785,-580,427,2063,-912,467,1648,-1019,482,1412,-1071,495,1214,-1151,478,1015,-1156,424,587,-1073,190,312,-757,-113,233,-562,-302,283,-661,-322,199,-663,-331,49,-741,-138,-1,-640,-132,149,-564,608,1803,-1237,535,1996,-1524,536,2150,-1101,492,2241,-1362,379,2248,-1422,474,2977,-1043,489,2864,-745,242,2233,-1430,312,2002,-1592,423,1999,-1558,432,1892,-1798,-333,4718,-449,-371,4951,-236,-602,4944,166,-564,4849,563,-302,4797,816,79,5053,858,-343,4984,925,-377,5197,1008,-588,5030,678,-618,5144,302,-632,5195,753,-389,5315,1029,-671,5322,779,-706,5385,385,-400,5268,61,-390,5099,-52,-17,5001,-273,198,5127,106,-75,5159,-97,-112,5331,-2,212,5289,222,-118,5431,-16,253,5433,220,263,5419,639,286,5706,611,265,5702,202,254,6498,632,268,6498,73,270,7339,652,281,7358,38,239,8173,698,250,8192,73,-197,7345,-249,-170,6504,-186,-125,5708,-37,-469,5407,31,-783,5669,335,-753,5648,801,-413,5663,1069,-917,6441,833,-943,6455,319,-655,6465,-167,-549,5673,-11,-720,7322,-223,-1039,7292,310,-1010,7276,892,-521,6449,1160,53,5677,1014,69,5348,978,66,5222,941,269,5175,534,7,6474,1075,-8,7312,1153,-46,8146,1211,18,8927,1157,201,8948,592,89,8959,13,-225,8180,-215,-784,8156,-196,-1109,8125,346,-1081,8109,941,-585,7284,1242,-619,8118,1295,-953,8894,1096,-1096,8904,511,-882,8926,-46,-396,8946,-176,-490,8905,1337,95,16666,115,292,16444,-111,-84,16579,106,325,16462,-109,279,16756,268,59,16747,422,0,16706,337,-65,16685,331,-126,16635,383,-185,16541,151,-208,16308,-54,27,16373,-135,129,16115,-257,433,16161,-204,496,16173,-213,579,16583,65,791,16247,-37,614,16614,170,665,16671,406,967,16337,393,944,16271,780,672,16640,750,356,16768,706,336,16796,468,56,16758,544,-67,16689,520,-38,16694,450,-34,16578,451,-94,16601,521,-169,16590,489,-261,16492,231,-302,16465,415,-325,16291,83,-384,16237,285,-333,16041,-21,-418,15970,190,-407,15671,129,-289,15719,-47,-347,15291,117,-206,15330,-10,-52,15350,-115,-116,15747,-151,128,15773,-240,145,15397,-191,166,15778,-230,219,15407,-176,262,15410,-215,201,15781,-265,497,15812,-206,551,15441,-150,621,15448,-145,582,15820,-217,877,15849,-22,924,15478,-17,1002,15846,108,886,16294,94,1110,15838,298,1134,15857,387,1097,15839,620,1033,15859,644,1036,15422,601,1058,15435,558,1180,15461,376,1170,15470,334,1153,15462,266,1044,15472,107,952,15095,22,1065,15087,108,1176,15060,220,1213,15035,331,1249,15040,413,1135,15022,565,1033,15006,576,1103,14617,408,1212,14618,399,1132,14335,247,1257,14359,258,1276,14163,129,1435,14183,138,1411,14377,204,1319,14653,313,1270,14676,242,1234,14700,153,1147,14707,69,1375,14409,27,1257,14415,-64,1460,14205,-132,1333,14177,-244,1060,14406,-164,1206,14154,-310,1006,14395,-135,1118,14115,-319,967,14706,-5,1000,14707,-7,924,15094,40,653,15066,-107,704,14718,-116,981,14398,-144,748,14435,-246,1089,14139,-335,833,14059,-520,729,14049,-451,663,14413,-228,641,14700,-123,586,15062,-79,551,15057,-123,569,14698,-145,662,14411,-194,592,14413,-282,336,14686,-165,349,14390,-291,635,14024,-528,695,14060,-440,368,14059,-526,297,14393,-250,285,14680,-129,244,15027,-117,292,15030,-157,169,15017,-139,210,14677,-167,217,14391,-299,297,14066,-496,178,14093,-558,42,14342,-213,-24,14083,-465,32,14643,-105,-22,14988,-58,-1,14640,-110,-8,14373,-229,-30,14080,-406,-148,14095,-472,-131,14371,-164,-245,14110,-388,-295,14354,-99,-365,14105,-308,-340,14074,-175,-316,14352,-47,-277,14581,77,-360,14565,150,-438,14332,6,-431,14093,-212,-524,14092,-151,-306,14306,127,-401,14088,-89,-264,14071,-118,-122,14270,123,-120,14552,285,-254,14555,257,-266,14878,410,-163,14883,454,-274,15288,475,-322,15294,431,-417,15279,265,-389,14902,270,-340,15290,151,-286,14925,193,-298,14927,137,-255,14601,25,-127,14620,-47,-151,14957,36,-456,15666,252,-429,15668,467,-409,15705,532,-441,15873,514,-421,15852,558,-436,16160,606,-393,16220,331,-460,15941,265,-361,16414,606,-431,16118,854,-461,15833,661,-423,15841,644,-343,15529,703,-434,15537,705,-373,15257,727,-308,15263,709,-310,14899,738,-262,14903,712,-239,14574,734,-177,14579,715,-229,14397,748,-145,14408,732,-200,14301,964,-256,14541,914,-254,14536,966,-316,14885,883,-392,15259,864,-333,14881,934,-283,14861,1075,-204,14518,1095,-234,14288,993,-173,14233,1121,-136,14187,1186,-170,14497,1199,-66,14173,1228,-117,14497,1225,-237,14848,1180,-368,15219,1058,-409,15259,899,-442,15560,871,-431,15530,1040,-310,15198,1204,-200,14848,1208,-96,14850,1331,-20,14496,1344,-42,14151,1269,56,14146,1378,-170,15191,1333,-210,15502,1339,-359,15507,1213,-424,15768,1043,-363,15704,1220,-219,15666,1353,-207,15808,1362,-351,15895,1222,-402,16007,1052,-462,15810,853,-380,16335,867,-365,16233,1076,-294,16100,1245,-158,15972,1377,-110,16103,1397,-208,16252,1286,-251,16390,1116,-171,16410,1103,-179,16517,901,-151,16607,923,-146,16505,1138,-138,16307,1331,-165,16264,1296,25,16174,1466,30,16100,1486,259,16187,1542,20,16366,1387,25,16579,1210,30,16692,965,54,16755,661,-99,16675,610,-127,16578,603,-195,16578,596,-251,16504,897,353,16762,726,329,16706,1018,287,16568,1258,273,16390,1442,557,16283,1422,519,16103,1514,247,16068,1551,468,16007,1536,640,15884,1467,698,15930,1433,741,15726,1403,784,15746,1371,785,15553,1350,814,15568,1334,798,15349,1321,766,16071,1282,697,15951,1411,856,15770,1288,847,15760,1312,812,15747,1318,892,15595,1236,892,15586,1241,934,15395,989,917,15620,1216,1006,15800,1148,1038,15411,1165,956,15406,1271,849,15396,1283,955,15011,1267,843,14995,1277,967,14737,1275,851,14707,1289,995,14322,1267,885,14258,1323,1053,14765,1189,1114,14387,1196,996,14340,1301,992,14444,1064,974,14753,1047,1049,15023,1177,973,15015,1056,1014,14756,1014,967,14396,1033,1020,14441,1015,1008,14810,858,1025,15036,879,984,15031,844,952,14804,827,1018,14530,817,958,14527,786,1022,15400,861,1042,15403,895,985,15672,842,1034,15712,877,1042,15407,1026,1012,15793,1028,1015,15864,856,898,16231,1085,950,16253,799,627,16557,1073,669,16621,774,973,15866,814,581,16413,1304,993,15796,1071,1034,15407,1071,1014,15021,1018,344,14049,-442,1432,14169,-64,1345,14386,120,1358,14379,141,1472,14178,-9,1573,14185,82,101,16110,-229,-182,16066,-133,-386,15568,451,-428,15842,690,-418,15852,528,-342,15453,720,-436,16160,606,827,15546,14,983,15277,433,822,15218,201,988,15644,297,808,15826,-28,990,15837,266,798,16128,-26,346,16129,-171,424,15787,-161,469,15479,-104,480,15165,109,858,14905,313,1026,14983,471,1086,14695,342,851,14671,231,1135,14465,218,909,14450,126,1244,14303,91,981,14277,-37,1108,14155,-254,1362,14183,-69,948,14237,-29,1052,14130,-226,867,14432,157,527,14891,219,544,14642,177,854,14421,139,580,14432,94,907,14262,-50,644,14230,-121,971,14099,-284,738,14076,-412,662,14078,-344,599,14208,-138,562,14409,74,291,14223,-148,343,14093,-435,634,14053,-416,258,14069,-388,249,14188,-135,238,14392,42,205,14632,149,174,14873,202,106,15143,91,47,15465,-109,-38,15738,-159,-115,16035,-119,-340,15951,129,-299,15705,135,-264,15516,170,-237,15151,251,-197,14856,311,-164,14639,214,7,14620,169,211,14389,64,190,14222,-128,217,14069,-350,154,14073,-395,-68,14074,-357,-13,14276,-62,-10,14381,81,-42,14398,82,-32,14249,-53,-90,14289,-87,-248,14271,-39,-321,14133,-261,-184,14120,-349,-87,14092,-330,-140,14398,141,981,16086,263,1076,14644,342,1106,14507,263,977,14412,280,1174,14356,142,1028,14261,143,1139,14173,-13,1295,14255,13,942,14589,369,721,14385,237,1040,14245,164,773,14213,87,874,14104,-119,1121,14183,1,699,14569,338,463,14569,287,481,14363,184,750,14206,74,512,14201,23,822,14106,-139,565,14066,-219,189,14561,282,207,14353,178,233,14191,20,485,14187,20,216,14078,-214,500,14070,-229,-50,14548,284,-38,14363,180,-82,14205,32,203,14182,13,-133,14105,-173,167,14072,-217,-146,14604,219,-167,14440,129,-202,14325,-33,-123,14231,13,-305,14229,-199,-152,14140,-172,-144,14863,337,-46,14867,466,-163,15107,332,-140,15066,472,-278,15516,205,-295,15355,445,196,15012,421,154,15146,382,448,15005,422,387,15163,401,631,15075,471,618,15194,429,899,15179,546,973,15485,574,966,15218,405,1027,14918,449,900,14838,511,676,14798,477,438,14777,430,180,14776,405,994,15646,335,1048,15841,589,1000,15853,849,983,15649,858,944,16271,780,1064,15649,590], diff --git a/examples/obj/gallardo/GallardoNoUv_bin.js b/examples/obj/gallardo/GallardoNoUv_bin.js index 818dccabd3ae6b..7755e32d22ded2 100644 --- a/examples/obj/gallardo/GallardoNoUv_bin.js +++ b/examples/obj/gallardo/GallardoNoUv_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 29.411765, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -35,7 +35,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 29.411765, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -48,7 +48,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 7.843137, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -61,7 +61,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 25.490196, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -74,7 +74,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 29.411765, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -87,7 +87,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 29.411765, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -100,7 +100,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 29.411765, - "transparency" : 0.0 + "opacity" : 0.0 }], "buffers": "GallardoNoUv_bin.bin" diff --git a/examples/obj/gallardo/parts/gallardo_body_bin.js b/examples/obj/gallardo/parts/gallardo_body_bin.js index 04deeffae5816b..515dc7c1bc5e53 100644 --- a/examples/obj/gallardo/parts/gallardo_body_bin.js +++ b/examples/obj/gallardo/parts/gallardo_body_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 21.568627, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -35,7 +35,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 27.45098, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -48,7 +48,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 27.45098, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -61,7 +61,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 27.45098, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -74,7 +74,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 3.921569, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -87,7 +87,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 27.45098, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -100,7 +100,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 27.45098, - "transparency" : 0.0 + "opacity" : 0.0 }], "buffers": "gallardo_body_bin.bin" diff --git a/examples/obj/gallardo/parts/gallardo_wheel_bin.js b/examples/obj/gallardo/parts/gallardo_wheel_bin.js index 12998ff5c0ceff..f70f26f4bb275f 100644 --- a/examples/obj/gallardo/parts/gallardo_wheel_bin.js +++ b/examples/obj/gallardo/parts/gallardo_wheel_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 27.45098, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -35,7 +35,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 27.45098, - "transparency" : 0.0 + "opacity" : 0.0 }], "buffers": "gallardo_wheel_bin.bin" diff --git a/examples/obj/leeperrysmith/LeePerrySmith.js b/examples/obj/leeperrysmith/LeePerrySmith.js index 34cacd2e9796ed..9a023472c07184 100644 --- a/examples/obj/leeperrysmith/LeePerrySmith.js +++ b/examples/obj/leeperrysmith/LeePerrySmith.js @@ -25,7 +25,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 96.078431, - "transparency" : 1.0 + "opacity" : 1.0 }], "vertices": [0.023176,0.126403,-0.101062,0.021848,0.091849,-0.099773,0.172455,-0.149425,-0.111905,0.139894,-0.136233,-0.115169,0.102390,-0.126029,-0.116829,0.067526,-0.122075,-0.119424,0.042264,-0.121297,-0.121546,0.010158,-0.120563,-0.123041,0.026909,-0.121459,-0.122500,0.172272,-0.185303,-0.125973,0.192128,-0.186209,-0.113378,0.145571,-0.181063,-0.131637,0.112588,-0.176913,-0.134636,0.081648,-0.207133,-0.099600,0.074817,-0.173955,-0.135147,0.046271,-0.173123,-0.134073,0.010627,-0.173625,-0.132441,0.027435,-0.173444,-0.132638,0.044773,0.175774,-0.062341,0.024817,0.181350,-0.071721,0.054713,0.153872,-0.073377,0.060036,0.135850,-0.075095,0.043232,0.155975,-0.082424,0.044299,0.129767,-0.091033,0.023913,0.157521,-0.091274,0.062595,0.105491,-0.072434,0.040694,0.066881,-0.082644,0.044559,0.096979,-0.089655,0.018512,0.064264,-0.091845,0.030220,0.038157,-0.069943,0.035665,0.048390,-0.076119,0.011349,0.038427,-0.077101,0.014488,0.047634,-0.084033,0.006171,0.016694,-0.069153,0.008810,0.031334,-0.071367,0.004539,-0.012019,-0.073166,0.005029,-0.039024,-0.083427,0.017981,-0.041605,-0.082549,0.024598,-0.021923,-0.070245,0.057801,-0.086257,-0.099602,0.082061,-0.081049,-0.078651,0.031106,-0.073801,-0.098946,0.042309,-0.051528,-0.072788,0.008636,-0.070928,-0.101203,0.208332,-0.144762,-0.072272,0.179209,-0.125539,-0.078098,0.138221,-0.106657,-0.080674,0.212489,-0.176470,-0.069400,0.176445,-0.206956,-0.088011,0.198340,-0.164372,-0.100843,0.198269,-0.196156,-0.080781,0.151145,-0.209691,-0.091975,0.119229,-0.208938,-0.094483,0.055139,-0.205446,-0.097345,0.033738,-0.203494,-0.087789,0.013374,-0.202320,-0.085199,0.059989,0.164534,-0.055750,0.045423,0.191627,-0.029821,0.023677,0.196586,-0.046065,0.072047,0.144071,-0.051279,0.077402,0.109084,-0.041756,0.070930,0.075700,-0.042884,0.059675,0.073760,-0.067570,0.064537,0.054354,-0.037987,0.041480,0.025174,-0.049471,0.046471,0.039055,-0.053819,0.053010,0.051819,-0.059043,0.026652,0.026936,-0.067000,0.040279,0.003294,-0.045288,0.040300,-0.021609,-0.051435,0.049671,-0.044944,-0.053808,0.049231,-0.027629,-0.037069,0.047506,-0.011688,-0.035420,0.023672,0.009751,-0.065196,0.103965,-0.087631,-0.048159,0.064989,-0.063214,-0.055781,0.074175,-0.072443,-0.040557,0.057151,-0.050235,-0.037770,0.216846,-0.137152,-0.039981,0.226105,-0.152649,-0.039549,0.185920,-0.117661,-0.040807,0.145124,-0.101127,-0.049875,0.222035,-0.159358,-0.054488,0.063986,0.175529,-0.026118,0.034099,0.201420,-0.012789,0.020299,0.205731,-0.018778,0.076598,0.153616,-0.019422,0.079827,0.125271,-0.010973,0.088090,0.066378,-0.011398,0.087473,0.067707,-0.005629,0.085055,0.066404,-0.010749,0.082935,0.066423,-0.008327,0.084288,0.076341,-0.011381,0.082832,0.084207,-0.008477,0.084778,0.079704,-0.000022,0.088692,0.086363,-0.003427,0.086841,0.090016,0.000613,0.085354,0.092043,0.000044,0.082823,0.092092,-0.000390,0.084267,0.093719,-0.001518,0.088842,0.091349,-0.000724,0.089115,0.094073,-0.002105,0.085915,0.096440,-0.002494,0.086938,0.091249,-0.007663,0.090085,0.066467,-0.009652,0.091209,0.075474,-0.007672,0.089631,0.066701,-0.005609,0.090591,0.066594,-0.007464,0.090317,0.087226,-0.004842,0.090989,0.082168,-0.007225,0.090464,0.089169,-0.006505,0.090963,0.083658,-0.009171,0.090945,0.076249,-0.010034,0.088328,0.076779,-0.012058,0.087297,0.085319,-0.010913,0.090194,0.075093,-0.005646,0.089654,0.081477,-0.005664,0.088031,0.075847,-0.006981,0.083915,0.088381,-0.004004,0.084488,0.080609,-0.003358,0.087372,0.078108,-0.008286,0.085242,0.082305,-0.006488,0.086352,0.075338,-0.007221,0.086655,0.083794,-0.008292,0.087685,0.082530,-0.006730,0.087077,0.087965,-0.004634,0.085890,0.089456,-0.005929,0.086785,0.064226,-0.002194,0.086773,0.065196,-0.004434,0.086046,0.073338,-0.005014,0.086368,0.072486,-0.002583,0.076418,0.104172,-0.001948,0.081464,0.090641,-0.004379,0.079669,0.082215,-0.003655,0.081715,0.067146,-0.005777,0.080219,0.075306,-0.004340,0.078756,0.074883,-0.004688,0.077877,0.080540,-0.001452,0.075697,0.090021,-0.016394,0.072972,0.072103,-0.020641,0.079455,0.068249,-0.005856,0.077010,0.078322,-0.002481,0.076257,0.071968,-0.006503,0.074921,0.085872,-0.001734,0.080906,0.095358,0.000859,0.081481,0.075672,-0.006923,0.087750,0.056459,-0.003344,0.087678,0.055649,-0.004461,0.086459,0.055043,-0.005934,0.086119,0.057494,-0.002203,0.087054,0.057224,-0.002745,0.068973,0.055717,-0.017373,0.070356,0.046521,-0.000606,0.078942,0.049279,0.000867,0.082163,0.058222,-0.004993,0.079618,0.051160,-0.001322,0.079912,0.058747,-0.005930,0.078813,0.053359,-0.002991,0.075288,0.050156,-0.000996,0.074508,0.056620,-0.005606,0.059052,0.038709,-0.033045,0.064351,0.037588,-0.010469,0.061032,0.021013,-0.011209,0.084144,0.055454,-0.006167,0.082538,0.056760,-0.005254,0.053970,0.023607,-0.029981,0.056859,-0.045061,-0.010865,0.057272,-0.018943,-0.011935,0.058704,0.003333,-0.011399,0.051730,0.005999,-0.027311,0.052484,-0.013514,-0.025079,0.054283,-0.035960,-0.023993,0.061165,-0.062320,-0.021829,0.058923,-0.072281,-0.008034,0.064271,-0.096336,-0.005141,0.078623,-0.093010,-0.020721,0.216514,-0.147081,-0.011596,0.171340,-0.111631,-0.030896,0.172922,-0.115915,-0.020595,0.188797,-0.129297,-0.010712,0.148026,-0.105628,-0.030668,0.151476,-0.113996,-0.017651,0.157262,-0.126540,-0.004869,0.119439,-0.116175,-0.014065,0.113075,-0.102033,-0.027986,0.089229,-0.118515,-0.006900,0.217905,-0.177481,-0.021209,0.201506,-0.193492,-0.019545,0.225444,-0.161085,-0.027452,0.180410,-0.203577,-0.018685,0.156597,-0.207309,-0.014352,0.125664,-0.207369,-0.009385,0.082411,-0.205951,-0.017895,0.070849,0.164298,0.017994,0.061407,0.180859,0.006428,0.034360,0.201518,0.010861,0.048414,0.192329,0.005734,0.054563,0.183549,0.029715,0.045178,0.189812,0.034759,0.017506,0.207797,0.013759,0.075243,0.135002,0.020552,0.086085,0.072711,0.001591,0.086754,0.064073,0.001528,0.086534,0.097480,0.005366,0.083555,0.099249,0.004932,0.082949,0.087858,0.000660,0.086324,0.094236,0.006447,0.084388,0.092479,0.006797,0.082299,0.093851,0.003823,0.069194,0.075536,0.031760,0.070887,0.095031,0.028150,0.073328,0.106790,0.016142,0.074314,0.094762,0.013963,0.074006,0.093823,0.011493,0.074497,0.091145,0.009490,0.074403,0.093174,0.008442,0.073161,0.081151,0.022087,0.072004,0.082584,0.023152,0.071565,0.086693,0.023632,0.074872,0.094643,0.004813,0.074121,0.090171,0.006144,0.078126,0.087579,0.000557,0.074180,0.087154,0.005628,0.075202,0.088402,0.006575,0.076139,0.084860,0.002891,0.074645,0.083451,0.002043,0.068832,0.060104,0.026492,0.069454,0.068988,0.027446,0.069880,0.061514,0.024903,0.071076,0.061907,0.018961,0.062951,0.066308,0.016092,0.066478,0.059627,0.017676,0.067991,0.063913,0.017642,0.070255,0.063234,0.018371,0.071829,0.061260,0.019920,0.071494,0.068704,0.019341,0.072118,0.065961,0.019374,0.071272,0.066472,0.018386,0.071535,0.069878,0.017841,0.071558,0.069096,0.020365,0.072570,0.073334,0.020693,0.070729,0.071208,0.024209,0.071267,0.067580,0.021677,0.072175,0.065789,0.020425,0.071821,0.065586,0.021308,0.071355,0.062683,0.022579,0.071947,0.061480,0.021235,0.062519,0.064269,0.016289,0.061652,0.061568,0.016302,0.069003,0.059387,0.011388,0.060323,0.066479,0.015913,0.059550,0.064985,0.015923,0.059008,0.064957,0.014686,0.059914,0.066955,0.014958,0.062826,0.067392,0.015411,0.066008,0.062283,0.013515,0.062532,0.066541,0.013857,0.060168,0.066610,0.013784,0.058820,0.062326,0.015746,0.058629,0.060125,0.015169,0.058675,0.059268,0.013848,0.058490,0.061869,0.014360,0.061729,0.060006,0.012344,0.062000,0.063839,0.012998,0.059461,0.064560,0.013361,0.059255,0.060945,0.012623,0.069466,0.068724,0.016586,0.069941,0.068879,0.017482,0.068992,0.068626,0.016814,0.069351,0.068803,0.017456,0.067198,0.066799,0.015437,0.069119,0.065793,0.013966,0.080325,0.090379,0.007958,0.074052,0.087357,0.014510,0.075774,0.087590,0.012491,0.073570,0.085427,0.013164,0.075469,0.082869,0.010898,0.074216,0.084033,0.011751,0.076949,0.084341,0.009831,0.078630,0.080730,0.009335,0.081098,0.084869,0.007333,0.083337,0.079698,0.004596,0.080773,0.073983,0.005932,0.075781,0.078945,0.011540,0.075998,0.080981,0.012134,0.074764,0.082665,0.012011,0.073495,0.082376,0.014452,0.073487,0.083659,0.013402,0.072884,0.085021,0.014367,0.072463,0.083996,0.015667,0.072945,0.080856,0.014204,0.071837,0.082564,0.016213,0.072292,0.070664,0.008130,0.070403,0.074944,0.010988,0.076737,0.073916,0.004759,0.073819,0.073193,0.004910,0.071050,0.077573,0.009867,0.073215,0.078829,0.010091,0.079008,0.065329,0.002334,0.083066,0.064923,0.004148,0.076196,0.064944,0.002301,0.073246,0.063334,0.005754,0.072449,0.066559,0.010449,0.072539,0.068648,0.013810,0.073747,0.072346,0.016226,0.073011,0.075228,0.015250,0.075554,0.088341,0.015973,0.080652,0.091587,0.012306,0.074789,0.083900,0.017044,0.076280,0.087178,0.016246,0.072650,0.081888,0.017527,0.078455,0.088807,0.016674,0.082306,0.093338,0.012726,0.082274,0.096719,0.012700,0.076878,0.097061,0.012986,0.079950,0.098375,0.012535,0.076283,0.084045,0.017636,0.073967,0.078034,0.016378,0.074869,0.080543,0.017213,0.075005,0.080265,0.019537,0.074582,0.075885,0.018128,0.071426,0.079573,0.017170,0.070365,0.077576,0.016550,0.070436,0.080267,0.016590,0.069776,0.079214,0.016018,0.069384,0.077304,0.014123,0.071611,0.079953,0.013473,0.070979,0.081242,0.015734,0.070307,0.080480,0.015774,0.070403,0.078934,0.013462,0.071558,0.069837,0.011312,0.070217,0.072933,0.012190,0.069692,0.074712,0.014419,0.071870,0.071984,0.013611,0.070013,0.067399,0.017825,0.067960,0.066749,0.017631,0.067921,0.068151,0.017274,0.073517,0.091773,0.019467,0.070971,0.081503,0.016888,0.072604,0.084311,0.017321,0.071094,0.082174,0.016688,0.072872,0.086135,0.015768,0.072292,0.084691,0.016642,0.074108,0.088424,0.015402,0.076123,0.090427,0.013178,0.074534,0.088786,0.015671,0.076164,0.085778,0.019698,0.078337,0.091643,0.017806,0.076861,0.093720,0.017930,0.077410,0.091226,0.004902,0.076151,0.093721,0.009178,0.079314,0.091844,0.012077,0.080643,0.093344,0.007799,0.078361,0.092592,0.011086,0.079243,0.097188,0.006966,0.083189,0.084463,0.003205,0.082749,0.094011,0.006997,0.082308,0.095100,0.004279,0.085449,0.056743,-0.000840,0.073468,0.034492,0.015134,0.076433,0.037022,0.015864,0.066183,0.037179,0.023895,0.063726,0.038056,0.020730,0.070579,0.035490,0.014312,0.066133,0.036290,0.017922,0.069002,0.034382,0.019959,0.073931,0.035059,0.019076,0.083196,0.045809,0.003171,0.078320,0.038596,0.009810,0.076149,0.038538,0.008475,0.075286,0.041647,0.007781,0.081995,0.044922,0.001548,0.080079,0.046485,0.000900,0.070861,0.039585,0.013174,0.067289,0.039563,0.015827,0.065438,0.039737,0.014178,0.070751,0.044024,0.006719,0.067993,0.041639,0.007853,0.071186,0.042225,0.011931,0.069228,0.042326,0.013402,0.067851,0.042275,0.013610,0.068753,0.042716,0.011190,0.071086,0.043666,0.009001,0.074740,0.044417,0.007158,0.075966,0.046712,0.002945,0.073340,0.045073,0.005029,0.073011,0.046429,0.002890,0.062014,0.029918,0.029715,0.060046,0.020319,0.004975,0.063139,0.036294,0.007116,0.061523,0.034901,0.019117,0.059750,0.022439,0.019200,0.063683,0.039994,0.026977,0.066966,0.054585,0.031247,0.071261,0.057589,0.020931,0.069597,0.054478,0.021091,0.070080,0.056230,0.022500,0.069145,0.053910,0.023492,0.073843,0.055634,0.014803,0.068517,0.052239,0.021413,0.069764,0.052683,0.019109,0.071272,0.054313,0.016965,0.069012,0.052490,0.017665,0.070956,0.056784,0.020033,0.070165,0.057152,0.019019,0.069269,0.058590,0.018480,0.067844,0.054809,0.020190,0.067566,0.052448,0.019251,0.067976,0.053810,0.025230,0.067376,0.054498,0.027620,0.059343,0.058749,0.012415,0.065441,0.058362,0.013850,0.068394,0.052718,0.015813,0.068207,0.055254,0.013917,0.066864,0.053243,0.017672,0.067284,0.055433,0.018983,0.066262,0.054717,0.016539,0.065091,0.056396,0.017541,0.060766,0.059031,0.015790,0.063803,0.056534,0.016137,0.064649,0.056440,0.015265,0.061170,0.057602,0.012874,0.060540,0.057667,0.014484,0.065552,0.044075,0.026187,0.068910,0.050065,0.023830,0.068174,0.048355,0.025111,0.069151,0.049142,0.022381,0.072155,0.050537,0.019341,0.071096,0.035291,0.022656,0.074154,0.037087,0.021217,0.069827,0.037124,0.024672,0.072388,0.039488,0.023891,0.072020,0.044199,0.021361,0.067270,0.040710,0.026134,0.069212,0.039212,0.025799,0.070417,0.040783,0.025329,0.069619,0.044573,0.024828,0.081162,0.059144,0.006886,0.077082,0.056852,0.010320,0.080618,0.050742,0.007214,0.084901,0.056478,0.001367,0.084427,0.057630,0.005323,0.077552,0.058736,0.004764,0.074892,0.059324,0.003626,0.070168,0.053675,0.014501,0.070711,0.054153,0.015478,0.071266,0.054632,0.011900,0.072814,0.055403,0.012167,0.075219,0.055945,0.008518,0.072727,0.057342,0.007380,0.075339,0.049627,0.017137,0.075481,0.043538,0.016309,0.078172,0.050100,0.012280,0.081131,0.053015,0.008608,0.079812,0.055862,0.010961,0.077111,0.053148,0.014380,0.083215,0.047778,0.004236,0.078822,0.045865,0.010337,0.079132,0.041598,0.010756,0.083317,0.051678,0.003147,0.082853,0.049874,0.004210,0.057664,-0.025169,0.002042,0.058622,0.001493,0.004014,0.040391,-0.039929,0.026006,0.051250,-0.031787,0.016111,0.054645,0.002680,0.021076,0.057350,-0.095940,0.003035,0.038719,-0.067751,0.023431,0.048499,-0.087210,0.012410,0.055391,-0.079254,0.003129,0.049052,-0.061049,0.013194,0.055959,-0.053471,0.001645,0.036435,-0.097545,0.020787,0.025944,-0.072247,0.030263,0.025130,-0.094536,0.027211,0.013175,-0.096194,0.029761,0.157688,-0.146442,0.008445,0.130193,-0.141525,0.014393,0.125648,-0.125652,0.000909,0.103742,-0.141562,0.025711,0.097230,-0.126333,0.011424,0.066272,-0.117444,0.001772,0.071139,-0.126499,0.019414,0.052926,-0.107731,0.009048,0.048189,-0.121131,0.019949,0.027821,-0.113048,0.024557,0.016210,-0.116560,0.026946,0.208693,-0.167151,0.006813,0.180154,-0.196084,0.017502,0.174304,-0.174993,0.024207,0.194198,-0.184853,0.016553,0.185371,-0.154560,0.009265,0.162326,-0.195000,0.026987,0.150560,-0.166867,0.025708,0.132241,-0.158365,0.025631,0.047942,-0.202486,0.004163,0.021075,-0.200480,0.006360,0.056248,0.176466,0.042084,0.055530,0.164647,0.057220,0.030859,0.187772,0.061989,0.043374,0.171886,0.069423,0.032482,0.196228,0.039699,0.043490,0.182635,0.054545,0.015585,0.192144,0.067330,0.016632,0.201431,0.043361,0.069425,0.113010,0.037123,0.063244,0.131254,0.058656,0.058359,0.100372,0.071170,0.063624,0.097101,0.057783,0.068492,0.085302,0.043463,0.062668,0.070777,0.060302,0.058594,0.081291,0.072855,0.065848,0.053037,0.041986,0.061724,0.031178,0.052231,0.057297,0.015091,0.035844,0.059713,0.053783,0.068304,0.053894,0.012268,0.067998,0.029747,-0.030711,0.049418,0.039156,-0.017620,0.060685,0.049271,0.000291,0.047646,0.044825,-0.012142,0.034195,0.017041,-0.037669,0.064773,0.014038,-0.058907,0.044236,0.013549,-0.077003,0.037403,0.027913,-0.049331,0.033991,0.010878,-0.042399,0.060366,0.014044,-0.045694,0.052701,0.074631,-0.141740,0.033540,0.043278,-0.134198,0.035919,0.021862,-0.136181,0.037291,0.113342,-0.164023,0.037606,0.130926,-0.189282,0.039167,0.088770,-0.192340,0.047339,0.082025,-0.165184,0.047651,0.049180,-0.162472,0.049696,0.051632,-0.188657,0.053746,0.021856,-0.185917,0.052469,0.022804,-0.159458,0.050255,0.030783,0.177158,0.078163,0.014637,0.165462,0.099130,0.015214,0.180769,0.084295,0.054119,0.122431,0.076965,0.041865,0.158841,0.084613,0.029699,0.162831,0.093468,0.046832,0.137197,0.087858,0.036021,0.142298,0.097836,0.042482,0.120959,0.096302,0.053072,0.150914,0.073174,0.053686,0.097869,0.079870,0.052806,0.086564,0.078715,0.055972,0.069802,0.078675,0.050155,0.111317,0.086204,0.047801,0.076351,0.086534,0.028765,0.074991,0.096985,0.042539,0.075082,0.090754,0.035870,0.074559,0.094563,0.035235,0.066736,0.097519,0.033063,0.055889,0.101752,0.051229,0.079415,0.082112,0.043403,0.063956,0.093096,0.050861,0.064595,0.086243,0.005459,0.086185,0.100157,0.003045,0.092111,0.100918,0.004696,0.098332,0.102601,0.027680,0.069358,0.099014,0.021056,0.071614,0.099344,0.022340,0.076175,0.097803,0.015057,0.073968,0.100461,0.016324,0.078433,0.097892,0.010307,0.081417,0.098869,0.053356,0.043665,0.081227,0.035005,0.034474,0.103504,0.033661,0.008961,0.102526,0.042441,0.042291,0.095974,0.038580,0.018624,0.100637,0.045670,0.016512,0.090995,0.016370,0.022782,0.103857,0.017874,0.018426,0.102910,0.018602,0.019650,0.102179,0.018114,0.021425,0.102599,0.033994,-0.006201,0.095309,0.034534,-0.013875,0.086486,0.031253,-0.021871,0.078338,0.043253,-0.010576,0.072172,0.038525,0.003611,0.095923,0.042389,-0.003561,0.085051,0.022516,-0.032370,0.071904,0.014686,-0.034642,0.079563,0.020939,-0.027815,0.084922,0.024544,-0.020673,0.093366,0.010108,-0.031361,0.090606,0.032016,0.124087,0.105505,0.020776,0.124592,0.112490,0.024374,0.142961,0.105128,0.007637,0.124725,0.115477,0.010700,0.143556,0.108958,0.004135,0.110257,0.115925,0.015120,0.109682,0.113677,0.003004,0.061223,0.115470,0.005396,0.059481,0.117460,0.004338,0.061464,0.116718,0.004002,0.061502,0.115886,0.003456,0.061736,0.117825,0.003230,0.060062,0.119738,0.000602,0.059937,0.121259,0.002192,0.061992,0.117888,0.002699,0.060535,0.115346,0.008435,0.102981,0.108299,0.000210,0.098327,0.109465,0.001627,0.103331,0.112669,-0.000002,0.077725,0.120348,0.025626,0.062415,0.102802,0.006108,0.064795,0.118509,0.011102,0.058179,0.116271,0.009944,0.061139,0.113538,0.013757,0.069610,0.103936,0.012510,0.064648,0.106530,0.017121,0.060734,0.105906,0.019384,0.066424,0.102995,0.011297,0.059918,0.107970,0.008638,0.064244,0.111234,0.005171,0.068552,0.116344,0.004269,0.073134,0.114142,0.008283,0.068549,0.109251,0.008440,0.073601,0.106663,0.009184,0.078080,0.103005,0.002358,0.069173,0.125381,0.001109,0.072845,0.122927,0.003523,0.064955,0.128171,0.007672,0.061280,0.121424,0.003785,0.060133,0.131966,-0.000094,0.084208,0.117024,0.003672,0.078699,0.111050,0.003605,0.083496,0.106149,0.000528,0.090902,0.110693,0.001037,0.061596,0.117376,0.000776,0.061026,0.116912,0.001644,0.060944,0.115748,0.028623,0.047259,0.105896,0.028684,0.013238,0.105818,0.029568,0.030880,0.107023,0.028393,0.020411,0.107555,0.033314,0.019580,0.104942,0.007229,0.054736,0.116839,0.006053,0.056238,0.119324,0.003342,0.057022,0.122586,0.000184,0.056765,0.125023,0.000579,0.054813,0.116851,0.003368,0.054037,0.115514,0.005939,0.053954,0.115628,0.005109,0.057848,0.114763,0.006324,0.058477,0.115520,0.002937,0.057916,0.115132,0.022374,0.055503,0.106129,0.014625,0.055448,0.106988,0.011558,0.050997,0.109336,0.008261,0.013202,0.118042,0.014759,0.017772,0.104600,0.005626,0.019832,0.118482,0.003263,0.023240,0.117150,0.002603,0.023317,0.113424,0.009598,0.017633,0.107067,0.003228,0.017922,0.108812,0.001354,0.055378,0.133088,0.004101,0.055422,0.130323,-0.000602,0.051592,0.124436,0.010146,0.006124,0.114708,0.017387,0.008915,0.111692,0.014395,0.015371,0.113968,0.012032,0.019875,0.114061,0.015480,0.022395,0.109604,0.013607,0.022402,0.111342,0.013098,0.022527,0.108812,0.008948,0.022996,0.111576,0.009718,0.022519,0.113641,0.015297,0.020554,0.110949,0.017484,0.017674,0.110212,0.021652,0.012936,0.108637,0.023702,0.016891,0.107845,0.016862,0.021141,0.109993,0.019184,0.019368,0.109349,0.013672,0.023419,0.106035,0.012722,0.022805,0.110093,0.010178,0.023670,0.108448,0.009560,0.023215,0.112440,0.008980,0.024154,0.115996,0.012631,0.022943,0.112970,0.012685,0.025696,0.115981,0.016392,0.022353,0.108907,0.016224,0.022212,0.109204,0.014867,0.022287,0.110701,0.015123,0.022306,0.107646,0.015583,0.023370,0.112717,0.016940,0.022382,0.110918,0.017508,0.021794,0.109912,0.019031,0.023297,0.111688,0.019867,0.021277,0.110066,0.023927,0.020871,0.109223,0.022170,0.025466,0.111353,0.016866,0.026215,0.113751,0.012917,0.029661,0.116662,0.007730,0.028695,0.119303,0.006831,0.033270,0.119841,0.002231,0.030802,0.122498,0.001415,0.035490,0.122524,0.001994,0.048849,0.120209,0.001658,0.047344,0.119745,0.001618,0.045518,0.119759,0.005241,0.045439,0.116409,0.006140,0.042500,0.117124,0.006704,0.038169,0.118736,0.009835,0.045305,0.112427,0.012001,0.040916,0.113588,0.013176,0.035080,0.115956,0.018587,0.030802,0.113476,0.004617,0.025939,0.118896,-0.000323,0.026114,0.120761,0.006495,0.023679,0.110125,0.005833,0.023437,0.114398,0.000684,0.023655,0.116096,0.001620,0.023722,0.111155,0.004160,0.053662,0.124423,0.006577,0.053391,0.125689,0.007647,0.056938,0.125892,0.011054,0.054168,0.119743,0.006020,0.052783,0.121145,0.008601,0.051429,0.122167,0.000546,0.051228,0.122091,0.002056,0.050799,0.120049,0.001436,0.052672,0.118519,0.000403,0.053446,0.121455,0.002458,0.053754,0.129296,0.000888,0.054161,0.127189,0.001757,0.043095,0.120358,0.001688,0.039625,0.121431,0.003664,0.052072,0.117194,0.004285,0.050287,0.119113,0.006089,0.052223,0.119246,0.005600,0.052038,0.117832,0.006278,0.049302,0.119745,0.007993,0.049880,0.120410,0.009172,0.047638,0.113538,0.005228,0.047860,0.118938,0.005277,0.046877,0.117350,0.011300,0.050455,0.111731,0.009254,0.048228,0.116089,0.011983,0.055962,0.110459,0.012317,0.055251,0.113329,0.011470,0.051259,0.115812,0.011873,0.052138,0.111698,0.018579,0.049881,0.107413,0.014577,0.046388,0.109331,0.015431,0.021911,0.106701,0.016659,0.021963,0.105816,0.016555,0.021997,0.106254,0.019430,0.038023,0.111057,0.023783,0.041656,0.108007,0.025501,0.028391,0.109656,-0.001260,0.055926,0.123418,-0.000996,0.055405,0.119582,-0.000875,0.059296,0.120137,-0.000539,0.058778,0.117885,0.000838,0.058372,0.116105,-0.000659,0.052551,0.131457,-0.000483,0.053445,0.125061,-0.002225,0.050608,0.126343,-0.001769,0.051411,0.129049,-0.001707,0.030817,0.124033,-0.002418,0.035414,0.122855,-0.001713,0.045229,0.121990,-0.002205,0.049500,0.124114,-0.001470,0.046739,0.122125,-0.001155,0.048502,0.122413,-0.000121,0.052832,0.128707,-0.000979,0.052615,0.126956,-0.001902,0.042880,0.122025,-0.002276,0.039454,0.122240,0.029913,0.000644,0.102013,0.014584,-0.008379,0.113753,0.012083,-0.000747,0.113284,0.020542,0.001919,0.109143,0.023210,-0.005271,0.106417,0.025946,0.006867,0.105969,0.025422,-0.013293,0.101792,0.014478,-0.025602,0.100775,0.016126,-0.018199,0.110625,0.043748,0.085070,0.086984,0.039720,0.099225,0.084275,0.034134,0.104277,0.087917,0.024633,0.104531,0.090482,0.041394,0.087732,0.081615,0.022058,0.081993,0.090272,0.028828,0.080022,0.089928,0.035224,0.080942,0.087777,0.040317,0.085194,0.082814,0.038498,0.082966,0.085103,0.041605,0.094019,0.082153,0.041831,0.090147,0.081544,0.024887,0.101228,0.093445,0.033627,0.101618,0.090664,0.039085,0.098177,0.086906,0.033768,0.093284,0.094112,0.025918,0.092893,0.096412,0.026264,0.086109,0.100056,0.033208,0.085568,0.097796,0.040529,0.086802,0.092108,0.041411,0.087106,0.089674,0.041951,0.087867,0.091545,0.040441,0.089393,0.088514,0.037481,0.084943,0.087441,0.037525,0.086325,0.091163,0.039820,0.088625,0.089281,0.038981,0.087568,0.090872,0.038995,0.087888,0.089067,0.039340,0.086895,0.085225,0.040148,0.089508,0.086896,0.040715,0.089106,0.083603,0.041490,0.091433,0.083231,0.040934,0.090882,0.085902,0.041211,0.094540,0.084297,0.040331,0.091831,0.087245,0.039493,0.088364,0.090670,0.037629,0.086338,0.094123,0.038298,0.092301,0.090392,0.038537,0.085912,0.096143,0.039099,0.088864,0.096091,0.026615,0.085622,0.103034,0.033643,0.085306,0.100587,0.034377,0.089941,0.100488,0.026785,0.090450,0.103644,0.034383,0.083190,0.089816,0.028293,0.082101,0.092418,0.022033,0.084054,0.093426,0.022362,0.084992,0.096566,0.034853,0.084360,0.093281,0.029128,0.082790,0.095693,0.029704,0.085405,0.097930,0.039566,0.082523,0.091149,0.036049,0.081516,0.094857,0.041939,0.083390,0.088447,0.039255,0.083848,0.092863,0.036187,0.083170,0.096147,0.036152,0.084663,0.096530,0.038888,0.085196,0.093563,0.041679,0.085426,0.089580,0.040790,0.084447,0.090618,0.040081,0.085465,0.091638,0.040726,0.085814,0.090682,0.040225,0.087106,0.090527,0.039432,0.086786,0.091578,0.030155,0.081217,0.098031,0.023514,0.083800,0.100488,0.030190,0.082959,0.099168,0.029953,0.085641,0.099024,0.023022,0.085545,0.100574,0.030017,0.084547,0.099309,0.022715,0.086744,0.100107,0.022832,0.086715,0.098784,0.037956,0.086937,0.092835,0.035413,0.085856,0.095327,0.035914,0.085731,0.096183,0.038417,0.086434,0.093390,0.017110,0.099393,0.090101,0.013831,0.090368,0.089523,0.014740,0.087314,0.089464,0.013081,0.088757,0.097307,0.012185,0.089572,0.097692,0.018707,0.087944,0.098710,0.018391,0.092315,0.096600,0.014912,0.091132,0.096045,0.014889,0.089206,0.097159,0.018285,0.087457,0.101191,0.018540,0.085432,0.099728,0.017738,0.086686,0.099405,0.013241,0.090370,0.095690,0.013075,0.089852,0.096651,0.013475,0.089491,0.096125,0.016695,0.087919,0.098182,0.016826,0.088590,0.096810,0.013558,0.092321,0.089848,0.013984,0.094363,0.089973,0.014417,0.091107,0.092444,0.014607,0.092478,0.093990,0.015092,0.091477,0.094116,0.014432,0.093869,0.093238,0.014243,0.093548,0.094745,0.016488,0.096219,0.094228,0.014482,0.092307,0.095021,0.015123,0.091311,0.095229,0.015643,0.090309,0.094097,0.015390,0.090055,0.095051,0.014088,0.091951,0.095402,0.014166,0.092587,0.095530,0.014392,0.090090,0.095420,0.014169,0.090971,0.095387,0.013507,0.090757,0.095340,0.015269,0.089061,0.092878,0.013855,0.089830,0.095200,0.015084,0.089232,0.094738,0.013625,0.089690,0.095488,0.016941,0.085086,0.089880,0.014114,0.092573,0.092551,0.017447,0.087058,0.093021,0.016640,0.088493,0.095544,0.010820,0.090359,0.097769,0.018194,0.091089,0.101719,0.018356,0.084059,0.099321,0.011655,0.088790,0.097363,0.023626,0.082001,0.099507,0.014182,0.086143,0.098239,0.015125,0.086553,0.098448,0.044967,0.092226,0.088476,0.042609,0.096077,0.093740,0.036717,0.098792,0.100544,0.035241,0.095193,0.100848,0.040339,0.092906,0.095021,0.043110,0.090147,0.090251,0.045002,0.087862,0.086851,0.014129,0.088826,0.098876,0.014532,0.102372,0.104160,0.027964,0.108234,0.108791,0.041835,0.106590,0.101248,0.047768,0.101438,0.091361,0.049552,0.094571,0.084482,0.048904,0.088290,0.082162,0.047229,0.083619,0.083904,0.044625,0.081120,0.086618,0.040827,0.079814,0.090004,0.035765,0.078898,0.093522,0.029540,0.078789,0.096472,0.023150,0.079683,0.098177,0.017579,0.081985,0.098238,0.012873,0.084562,0.097831,0.009455,0.087984,0.097333,0.008259,0.091535,0.096620,0.009821,0.096529,0.098116,0.026427,0.096160,0.104018,0.026939,0.100990,0.104189,0.017791,0.095523,0.101518,0.016777,0.099377,0.101623,0.013708,0.092715,0.099257,0.035124,0.038581,0.049776,0.039080,0.024864,0.047290,0.032147,0.035572,0.078221,0.034891,0.024530,0.074542,0.034834,0.008881,0.073887,0.026758,0.023137,0.093144,0.027843,0.012333,0.092902,0.026861,0.001791,0.093043,0.024412,0.029528,0.095196,0.026530,0.039926,0.082343,0.020637,0.031777,0.097458,0.028334,0.044621,0.051426,0.017053,0.047051,0.053177,0.022385,0.046258,0.052385,0.015292,0.040220,0.085713,0.020658,0.040188,0.084663,0.015937,0.032097,0.098867,0.010889,0.032038,0.099907,0.004647,0.032137,0.100669,0.008367,0.040946,0.086345,0.010003,0.047902,0.053585,0.011230,-0.010441,0.048394,0.020216,-0.010900,0.048730,0.018340,-0.012710,0.076135,0.009050,-0.013252,0.076639,0.014718,-0.005842,0.094332,0.006045,-0.006123,0.095843,0.022555,-0.004006,0.093450,0.026033,-0.011105,0.075186,0.027673,-0.010821,0.047062,0.034500,-0.005192,0.046128,0.031597,-0.004745,0.074193,0.039052,0.007377,0.046373,0.008729,0.046687,0.031052,0.021476,0.045633,0.032895,0.015102,0.046036,0.031085,0.034781,0.026121,0.028417,0.034564,0.037799,0.032261,0.025192,0.043013,0.030562,0.025532,-0.002526,0.028581,0.034328,-0.000441,0.029471,0.020338,-0.005064,0.031720,0.011003,-0.003252,0.028884,0.034668,0.008949,0.027577,0.002560,0.026967,0.106224,0.007947,0.026868,0.105504,0.012324,0.026588,0.104068,0.016156,0.026178,0.102114,0.004248,0.009035,0.103982,0.011464,0.009138,0.101968,0.017802,0.009608,0.100604,0.021296,0.012232,0.099873,0.021871,0.016389,0.099512,0.020989,0.020971,0.099568,0.019117,0.024548,0.100450,0.017503,0.088818,0.071664,0.019809,0.080889,0.071708,0.026032,0.077788,0.069579,0.024182,0.075164,0.072710,0.028625,0.076300,0.069802,0.029771,0.072641,0.072962,0.033728,0.073362,0.072142,0.038051,0.079330,0.071234,0.036365,0.075739,0.071325,0.032801,0.081397,0.068375,0.023608,0.087564,0.068552,0.030866,0.085881,0.068343,0.038629,0.083806,0.071724,0.038851,0.089097,0.072842,0.037192,0.094680,0.074031,0.033511,0.089777,0.069636,0.032461,0.099886,0.075006,0.032927,0.093409,0.070637,0.030989,0.096861,0.071831,0.026825,0.092134,0.069317,0.027190,0.096989,0.071423,0.025390,0.100692,0.074539,0.019809,0.096172,0.072785,0.030279,0.077525,0.068992,0.031975,0.078968,0.068525,0.026945,0.081539,0.068182,0.014113,0.089684,0.077391,0.016711,0.080272,0.077495,0.023008,0.073380,0.078570,0.030489,0.070609,0.078804,0.035941,0.071577,0.077675,0.016717,0.099001,0.078387,0.024477,0.104300,0.079916,0.039104,0.074393,0.076449,0.040867,0.078512,0.076008,0.041670,0.083561,0.076245,0.041396,0.089619,0.076980,0.033487,0.102739,0.079835,0.039335,0.096199,0.078236,0.030090,0.074788,0.085909,0.022529,0.076879,0.085645,0.036150,0.075965,0.084401,0.039437,0.078386,0.082090,0.041162,0.081465,0.080395,0.042051,0.086027,0.079952,0.041786,0.091287,0.079982,0.039860,0.097485,0.081528,0.034008,0.103717,0.084187,0.024385,0.105369,0.085607,0.016224,0.099897,0.084778,0.015896,0.082857,0.085447,0.013675,0.090953,0.085523,0.074642,0.088653,0.020862,0.067532,0.153085,0.041307,0.075445,0.094433,0.017201,0.073032,0.095287,0.015281,-0.003616,0.126512,-0.104661,-0.004071,0.091240,-0.103573,-0.026044,-0.070979,-0.099865,-0.008917,-0.070654,-0.101133,-0.047310,-0.073917,-0.096352,-0.072196,-0.086303,-0.097012,-0.027006,-0.120371,-0.122653,-0.008612,-0.120849,-0.123049,-0.042991,-0.121063,-0.122267,-0.057581,-0.120705,-0.121558,-0.081371,-0.121090,-0.119626,-0.113948,-0.124444,-0.116116,-0.149207,-0.134132,-0.113030,-0.179944,-0.146701,-0.108592,-0.025781,-0.173219,-0.132975,-0.007804,-0.173687,-0.132646,-0.041901,-0.172764,-0.134116,-0.060242,-0.172229,-0.136489,-0.092566,-0.206204,-0.099545,-0.067223,-0.204664,-0.097921,-0.087866,-0.172759,-0.137290,-0.123883,-0.175320,-0.134999,-0.155087,-0.178891,-0.129565,-0.179910,-0.182676,-0.122595,-0.198794,-0.182649,-0.109368,-0.002531,0.183647,-0.075206,-0.031957,0.179976,-0.071227,-0.003210,0.159565,-0.094261,-0.050628,0.153385,-0.080359,-0.031245,0.157439,-0.089020,-0.030010,0.127219,-0.100110,-0.049465,0.128285,-0.088310,-0.062878,0.149809,-0.071088,-0.066882,0.132087,-0.071430,-0.027332,0.063747,-0.090297,-0.028092,0.092443,-0.099689,-0.005381,0.063313,-0.094283,-0.047265,0.066992,-0.080230,-0.048708,0.096557,-0.087809,-0.068529,0.102783,-0.067099,-0.024485,0.038535,-0.074177,-0.025904,0.047848,-0.081101,-0.023495,0.029003,-0.070706,-0.023219,0.013661,-0.070671,-0.008673,0.017762,-0.070118,-0.007571,0.032008,-0.071196,-0.007133,0.038695,-0.077388,-0.006436,0.047347,-0.084980,-0.040415,0.038893,-0.064781,-0.038721,0.026749,-0.062171,-0.043744,0.049691,-0.070845,-0.023259,-0.012953,-0.074079,-0.023922,-0.038947,-0.082148,-0.035209,-0.042362,-0.078584,-0.009891,-0.038177,-0.083710,-0.010025,-0.010543,-0.074134,-0.038461,0.007881,-0.061824,-0.039544,-0.023011,-0.065904,-0.057149,-0.051317,-0.069504,-0.093413,-0.080365,-0.075927,-0.146318,-0.104975,-0.078019,-0.185137,-0.122528,-0.075002,-0.212204,-0.141393,-0.068463,-0.026490,-0.201987,-0.085331,-0.006679,-0.202141,-0.085364,-0.046354,-0.202892,-0.088142,-0.128182,-0.207321,-0.092552,-0.158530,-0.207390,-0.088649,-0.182617,-0.204189,-0.084012,-0.204171,-0.161093,-0.096855,-0.203287,-0.192929,-0.076524,-0.002687,0.198543,-0.051182,-0.054104,0.172712,-0.063032,-0.030867,0.195463,-0.047395,-0.069585,0.160834,-0.054693,-0.079309,0.141073,-0.046499,-0.083486,0.107608,-0.036058,-0.077666,0.075458,-0.038350,-0.065672,0.073021,-0.061220,-0.052013,0.024814,-0.045889,-0.055532,0.039465,-0.049298,-0.060406,0.053174,-0.054447,-0.071655,0.055253,-0.034776,-0.051575,0.002745,-0.042602,-0.060627,-0.045066,-0.050184,-0.052185,-0.021778,-0.048545,-0.057945,-0.012147,-0.032715,-0.058902,-0.027942,-0.033745,-0.082321,-0.071512,-0.036917,-0.075832,-0.062376,-0.052435,-0.065658,-0.050118,-0.033741,-0.111693,-0.086954,-0.045120,-0.151178,-0.099633,-0.047376,-0.189379,-0.115159,-0.037752,-0.218004,-0.135172,-0.036138,-0.226509,-0.149204,-0.035642,-0.216272,-0.172876,-0.065403,-0.223702,-0.155804,-0.050482,-0.027085,0.204509,-0.021013,-0.002893,0.207852,-0.022636,-0.041910,0.199639,-0.014871,-0.053985,0.189407,-0.030679,-0.072484,0.173913,-0.023825,-0.087285,0.126966,-0.007737,-0.083674,0.154620,-0.013798,-0.089826,0.082364,-0.003847,-0.086880,0.074425,-0.004479,-0.088246,0.075142,-0.005366,-0.084205,0.091323,-0.014037,-0.082033,0.073692,-0.017128,-0.086809,0.068500,-0.005622,-0.083821,0.072335,-0.005307,-0.090445,0.090400,-0.004176,-0.089553,0.067645,-0.006036,-0.096513,0.066420,-0.010071,-0.096056,0.068006,-0.006235,-0.090765,0.075696,-0.006752,-0.091712,0.067171,-0.006869,-0.093387,0.066800,-0.008895,-0.093359,0.076392,-0.010024,-0.092243,0.084596,-0.007903,-0.097311,0.086574,-0.003403,-0.095897,0.092308,-0.007819,-0.098468,0.066446,-0.008582,-0.097338,0.066975,-0.005156,-0.100271,0.075683,-0.008634,-0.098657,0.066671,-0.006422,-0.100258,0.082916,-0.007926,-0.099181,0.087666,-0.004846,-0.099259,0.090061,-0.006867,-0.097452,0.076820,-0.012756,-0.100018,0.076229,-0.010822,-0.100022,0.084560,-0.009925,-0.096967,0.085940,-0.011456,-0.098868,0.075468,-0.007091,-0.098741,0.082147,-0.006427,-0.097418,0.076488,-0.008676,-0.093605,0.087914,-0.003736,-0.093678,0.081630,-0.004779,-0.094999,0.083328,-0.007041,-0.097539,0.078840,-0.009499,-0.096322,0.076165,-0.008399,-0.096232,0.087767,-0.004270,-0.097474,0.083041,-0.007402,-0.096983,0.084127,-0.008287,-0.095458,0.088868,-0.005310,-0.095054,0.074156,-0.006343,-0.095477,0.065481,-0.004610,-0.094572,0.072821,-0.003808,-0.078563,0.057814,-0.013707,-0.078885,0.048090,0.000756,-0.088527,0.051568,-0.001515,-0.084201,0.051102,-0.000129,-0.086925,0.053596,-0.002927,-0.086811,0.059685,-0.005697,-0.082859,0.057272,-0.004676,-0.067564,0.039196,-0.030452,-0.075118,0.041516,-0.008011,-0.064159,0.022826,-0.027877,-0.069902,0.020392,-0.010566,-0.096539,0.056955,-0.002368,-0.096603,0.056008,-0.004235,-0.095140,0.055559,-0.005858,-0.090088,0.059053,-0.005460,-0.091468,0.057766,-0.004550,-0.092288,0.056534,-0.005256,-0.065867,-0.043716,-0.007952,-0.062281,0.005092,-0.025204,-0.068482,0.002351,-0.010082,-0.067031,-0.019096,-0.009699,-0.065362,-0.024464,0.004177,-0.063129,-0.014196,-0.022617,-0.063855,-0.035749,-0.020811,-0.061874,-0.092021,0.006801,-0.061098,-0.075582,0.005618,-0.062946,-0.051123,0.004296,-0.068655,-0.093035,-0.001031,-0.065496,-0.069406,-0.004982,-0.068119,-0.061148,-0.018108,-0.084066,-0.091222,-0.016753,-0.069565,-0.113124,0.006790,-0.093338,-0.114245,-0.001859,-0.118632,-0.100739,-0.025112,-0.123842,-0.113495,-0.010703,-0.129308,-0.124174,0.002880,-0.152589,-0.104560,-0.028581,-0.159929,-0.125620,-0.003302,-0.154989,-0.113200,-0.015989,-0.175692,-0.114705,-0.018544,-0.174908,-0.110710,-0.028643,-0.190877,-0.127458,-0.007735,-0.217460,-0.145279,-0.008703,-0.089158,-0.204770,-0.015152,-0.130798,-0.205230,-0.006803,-0.160474,-0.204840,-0.012084,-0.183399,-0.200910,-0.016072,-0.203645,-0.190316,-0.016504,-0.219281,-0.173907,-0.017943,-0.225629,-0.157642,-0.023957,-0.026203,0.207364,0.012255,-0.004459,0.210432,0.014176,-0.042542,0.201092,0.010376,-0.056033,0.192190,0.007473,-0.077940,0.165016,0.019792,-0.068036,0.180801,0.009384,-0.062837,0.183265,0.030367,-0.083302,0.135738,0.020690,-0.084752,0.104659,-0.000990,-0.079440,0.075551,0.031503,-0.083371,0.093840,0.012555,-0.083504,0.090396,0.008276,-0.082878,0.093003,0.010509,-0.083055,0.092635,0.007648,-0.083315,0.094163,0.004497,-0.082862,0.089506,0.005160,-0.088016,0.086685,-0.000007,-0.084781,0.087253,0.005451,-0.083811,0.086280,0.004478,-0.085671,0.084390,0.001663,-0.086840,0.080678,-0.002508,-0.085579,0.078384,-0.002822,-0.083993,0.083239,0.001114,-0.083358,0.085975,-0.001885,-0.079211,0.069107,0.026171,-0.079088,0.062038,0.023467,-0.081012,0.061971,0.017984,-0.072806,0.066647,0.016593,-0.077041,0.063906,0.018110,-0.079577,0.063042,0.017762,-0.082258,0.065830,0.017754,-0.081105,0.068422,0.018304,-0.080505,0.066549,0.016998,-0.079554,0.070149,0.017370,-0.080452,0.073811,0.019661,-0.081193,0.068634,0.019720,-0.079739,0.071157,0.023058,-0.080928,0.067126,0.021492,-0.081149,0.062640,0.021481,-0.082163,0.065392,0.020765,-0.082790,0.065542,0.019339,-0.072553,0.064313,0.017433,-0.071749,0.061393,0.016901,-0.069454,0.064789,0.016469,-0.070280,0.066541,0.016026,-0.068836,0.064711,0.014634,-0.069831,0.067040,0.015010,-0.072569,0.067696,0.015482,-0.076376,0.062575,0.013294,-0.070120,0.066285,0.014085,-0.072454,0.066563,0.014066,-0.068712,0.062036,0.015959,-0.068511,0.061515,0.013752,-0.069649,0.064093,0.012881,-0.072167,0.063358,0.012743,-0.078307,0.068602,0.015942,-0.078658,0.068840,0.016752,-0.078058,0.068431,0.016688,-0.077803,0.068372,0.016163,-0.076713,0.067043,0.014909,-0.079381,0.066977,0.013259,-0.089734,0.088839,0.006697,-0.084037,0.086468,0.011178,-0.085603,0.085897,0.009416,-0.083733,0.084380,0.010380,-0.085340,0.081608,0.009607,-0.084318,0.082849,0.009811,-0.086799,0.083093,0.008503,-0.087887,0.079891,0.007874,-0.084812,0.077380,0.010379,-0.084497,0.081245,0.010543,-0.084946,0.079836,0.010779,-0.082591,0.084044,0.011366,-0.083148,0.082082,0.011223,-0.082820,0.080607,0.012645,-0.081932,0.082781,0.012748,-0.082070,0.078809,0.013090,-0.081495,0.081068,0.013833,-0.081172,0.070250,0.007057,-0.080066,0.073929,0.009812,-0.084623,0.072545,0.003709,-0.087932,0.073518,0.004249,-0.080283,0.076156,0.008508,-0.082410,0.078135,0.008115,-0.089704,0.065053,0.002117,-0.086144,0.064394,0.001855,-0.082625,0.064837,0.005898,-0.081903,0.068417,0.010242,-0.081920,0.070191,0.013229,-0.082275,0.075623,0.014252,-0.082320,0.073091,0.015393,-0.085183,0.088346,0.013348,-0.086319,0.087040,0.013652,-0.085234,0.083674,0.015112,-0.083159,0.081325,0.015334,-0.087594,0.089431,0.014566,-0.085474,0.096158,0.011524,-0.085602,0.084249,0.016149,-0.083206,0.080458,0.018468,-0.084474,0.080480,0.016056,-0.083386,0.077821,0.015385,-0.082891,0.076202,0.017379,-0.081679,0.078888,0.015112,-0.080698,0.077249,0.014574,-0.080581,0.079358,0.014746,-0.079663,0.076602,0.012775,-0.080020,0.078337,0.014263,-0.080210,0.079282,0.014421,-0.080551,0.079801,0.014256,-0.080568,0.078667,0.012489,-0.079775,0.077904,0.012607,-0.079831,0.075082,0.012854,-0.080192,0.072847,0.010624,-0.080968,0.070713,0.010130,-0.081063,0.073026,0.012523,-0.076846,0.066834,0.017351,-0.078610,0.067443,0.017137,-0.076754,0.068150,0.016718,-0.084020,0.094283,0.014866,-0.081181,0.080495,0.014952,-0.081161,0.081017,0.014637,-0.082756,0.083683,0.014854,-0.082782,0.085464,0.012564,-0.082150,0.083892,0.013837,-0.085944,0.089436,0.010690,-0.084157,0.087833,0.012357,-0.084186,0.088447,0.012675,-0.087031,0.091890,0.015354,-0.084696,0.086014,0.017873,-0.085604,0.093549,0.015546,-0.085057,0.092808,0.008191,-0.086782,0.089960,0.004134,-0.088441,0.091756,0.010693,-0.087646,0.092493,0.010163,-0.087528,0.096120,0.006228,-0.082671,0.091234,0.017276,-0.083136,0.088616,0.018826,-0.081690,0.081103,0.020581,-0.081234,0.082822,0.021965,-0.082214,0.094847,0.014952,-0.080787,0.087372,0.023883,-0.082667,0.107146,0.017088,-0.080576,0.095625,0.027380,-0.095233,0.072901,0.000588,-0.090488,0.083432,0.005765,-0.092470,0.079338,0.003591,-0.090505,0.074183,0.004847,-0.093223,0.065410,0.003982,-0.095625,0.064357,0.000647,-0.089751,0.091034,0.010678,-0.090990,0.092833,0.011309,-0.094692,0.096698,0.005064,-0.090613,0.095709,0.011368,-0.088499,0.097411,0.011385,-0.089693,0.092763,0.007420,-0.088925,0.094346,0.000563,-0.091641,0.098614,0.004880,-0.092099,0.083664,0.001705,-0.093100,0.079893,-0.001439,-0.092223,0.086946,-0.000279,-0.094714,0.093691,0.005590,-0.093147,0.091832,0.005794,-0.095403,0.089633,0.000230,-0.094536,0.090945,-0.000116,-0.091382,0.092923,0.006158,-0.092697,0.090234,-0.000205,-0.091629,0.091524,0.003237,-0.091600,0.093185,0.003941,-0.093647,0.092171,-0.001205,-0.097375,0.091131,-0.000700,-0.097548,0.094429,-0.002019,-0.093995,0.096527,-0.002144,-0.095265,0.064304,-0.002809,-0.001150,0.037169,0.023136,-0.001407,0.006325,0.022515,-0.038870,0.006503,0.027157,-0.085747,0.035196,0.013388,-0.089128,0.038695,0.013990,-0.077756,0.037803,0.022312,-0.074985,0.039345,0.020891,-0.083067,0.034838,0.013169,-0.078550,0.035004,0.018324,-0.086061,0.036319,0.017088,-0.081332,0.034771,0.018663,-0.090221,0.039373,0.008211,-0.086070,0.040521,0.006677,-0.087777,0.038682,0.007156,-0.089686,0.046947,0.000585,-0.082591,0.036966,0.012151,-0.078953,0.036596,0.015974,-0.076012,0.038736,0.016046,-0.077006,0.042728,0.008375,-0.078930,0.044063,0.006204,-0.082096,0.039805,0.011043,-0.078046,0.041667,0.011277,-0.077793,0.039790,0.014278,-0.080014,0.039389,0.013399,-0.080353,0.042433,0.008386,-0.084789,0.043291,0.006423,-0.089018,0.049410,0.000596,-0.080727,0.045695,0.002041,-0.082264,0.044235,0.004076,-0.085046,0.047187,0.002956,-0.073094,0.029768,0.029564,-0.072144,0.034321,0.018987,-0.072900,0.035763,0.008334,-0.068317,0.018623,0.005381,-0.068394,0.020762,0.019684,-0.075046,0.040436,0.025861,-0.077769,0.055052,0.030950,-0.078635,0.060840,0.025089,-0.081432,0.058150,0.020324,-0.079176,0.054235,0.020234,-0.080648,0.056846,0.021819,-0.078874,0.054496,0.023199,-0.083730,0.055532,0.014037,-0.079080,0.051753,0.020710,-0.081210,0.055048,0.016110,-0.079689,0.052284,0.018000,-0.078912,0.052588,0.017002,-0.080831,0.057267,0.019131,-0.079593,0.057720,0.017972,-0.078551,0.058925,0.018031,-0.076291,0.060365,0.018105,-0.077437,0.051951,0.018588,-0.077911,0.054270,0.019161,-0.081895,0.061377,0.018922,-0.082091,0.061531,0.020062,-0.077844,0.054339,0.025122,-0.077533,0.054729,0.026945,-0.069209,0.058593,0.011622,-0.075586,0.059011,0.013815,-0.079897,0.060511,0.011589,-0.078151,0.052647,0.015028,-0.078097,0.056054,0.013773,-0.076318,0.052847,0.017172,-0.076870,0.055465,0.018584,-0.075762,0.055087,0.016619,-0.074746,0.057182,0.017752,-0.070845,0.059109,0.015398,-0.071141,0.057804,0.012226,-0.074415,0.056941,0.015161,-0.073654,0.057121,0.015790,-0.070513,0.057801,0.013772,-0.068488,0.059192,0.012963,-0.068523,0.059959,0.014725,-0.071741,0.059902,0.011713,-0.069391,0.060619,0.011653,-0.076371,0.044541,0.024848,-0.078169,0.048598,0.024367,-0.078460,0.050297,0.023354,-0.079650,0.049321,0.021790,-0.081670,0.050969,0.018506,-0.082423,0.036681,0.020482,-0.084845,0.039800,0.018301,-0.080518,0.038738,0.022225,-0.082196,0.041706,0.020787,-0.081779,0.045306,0.019290,-0.080226,0.042360,0.022661,-0.079224,0.040833,0.023323,-0.077724,0.041599,0.024014,-0.079453,0.045267,0.022723,-0.086973,0.055950,0.009485,-0.087830,0.058542,0.004587,-0.085895,0.059169,0.003721,-0.080523,0.054901,0.014942,-0.079969,0.053860,0.013988,-0.085333,0.055513,0.007976,-0.082614,0.055453,0.011899,-0.080994,0.054375,0.011410,-0.083496,0.057467,0.007097,-0.085513,0.051438,0.016597,-0.086748,0.044997,0.014898,-0.089434,0.054899,0.009800,-0.088241,0.050509,0.011457,-0.086753,0.053797,0.013477,-0.089929,0.046191,0.009195,-0.091449,0.042364,0.009384,-0.093462,0.046427,0.002361,-0.091871,0.045486,0.000730,-0.090894,0.058645,0.006599,-0.093985,0.056947,0.000120,-0.090528,0.050733,0.006720,-0.094052,0.057155,0.005418,-0.093965,0.056483,0.002204,-0.090747,0.052712,0.008117,-0.093258,0.048421,0.003705,-0.092569,0.050353,0.004033,-0.092483,0.052097,0.003330,-0.094305,0.057813,-0.001314,-0.095363,0.057729,-0.001607,-0.015401,-0.003508,0.028242,-0.025948,-0.003928,0.031280,-0.001801,-0.003069,0.027619,-0.048193,-0.038040,0.028131,-0.034569,-0.046911,0.036970,-0.059035,-0.030279,0.017964,-0.051968,-0.015628,0.036626,-0.030747,-0.002600,0.029072,-0.039540,-0.002244,0.030562,-0.067090,-0.000237,0.005175,-0.062010,-0.000366,0.022963,-0.019065,-0.075872,0.036206,-0.020625,-0.056825,0.044938,-0.017329,-0.096257,0.029005,-0.002821,-0.078619,0.040117,-0.003469,-0.062753,0.050445,-0.001888,-0.097406,0.030515,-0.032845,-0.071418,0.031464,-0.046247,-0.066078,0.024881,-0.053552,-0.084265,0.014295,-0.056572,-0.058577,0.015492,-0.040844,-0.096220,0.021496,-0.029721,-0.094399,0.027304,-0.022063,-0.136654,0.035534,-0.017782,-0.117247,0.025426,0.000984,-0.140664,0.031200,0.000053,-0.121378,0.023185,-0.030729,-0.112800,0.023533,-0.050879,-0.118120,0.021430,-0.045074,-0.133852,0.034158,-0.056735,-0.104012,0.012615,-0.073171,-0.124083,0.021915,-0.077700,-0.139366,0.035253,-0.107338,-0.139306,0.027695,-0.100186,-0.125266,0.013294,-0.133457,-0.139729,0.015835,-0.159776,-0.144924,0.009516,-0.027035,-0.200145,0.006267,-0.003036,-0.199924,0.003967,-0.053920,-0.201782,0.005087,-0.134982,-0.156587,0.025631,-0.164733,-0.192063,0.027330,-0.152646,-0.165155,0.025185,-0.181836,-0.193332,0.018708,-0.195234,-0.182156,0.018323,-0.175585,-0.172993,0.024508,-0.186471,-0.152735,0.011165,-0.209066,-0.164683,0.008958,-0.026271,0.191967,0.066498,-0.026329,0.201577,0.043754,-0.004740,0.204063,0.045074,-0.041762,0.187340,0.060857,-0.042201,0.195949,0.040176,-0.054003,0.189309,0.034954,-0.053744,0.182056,0.053309,-0.065380,0.176136,0.041431,-0.066563,0.164725,0.056112,-0.075502,0.129945,0.056911,-0.077261,0.153267,0.040035,-0.030462,0.090407,0.067202,-0.041603,0.097022,0.068981,-0.041901,0.093648,0.068043,-0.040300,0.085511,0.066756,-0.038482,0.089568,0.066810,-0.039206,0.083199,0.066884,-0.033688,0.084938,0.066702,-0.034547,0.095133,0.067813,-0.069626,0.102059,0.074695,-0.074647,0.097089,0.062089,-0.078991,0.085142,0.045124,-0.069015,0.083427,0.075395,-0.074047,0.071201,0.065321,-0.080335,0.112553,0.036370,-0.027840,0.045253,0.032544,-0.030473,0.047463,0.051948,-0.023053,0.047941,0.052614,-0.019273,0.045571,0.030638,-0.014833,0.048416,0.052806,-0.011847,0.046367,0.030461,-0.001380,0.046955,0.030581,-0.002224,0.048749,0.053256,-0.047164,0.039201,0.045956,-0.043142,0.036594,0.028490,-0.032387,0.042291,0.029554,-0.038815,0.045936,0.050266,-0.040554,0.023718,0.025275,-0.049026,0.023554,0.041388,-0.076907,0.053563,0.044249,-0.072361,0.031252,0.054786,-0.064305,0.009529,0.069589,-0.066816,0.013165,0.036565,-0.071705,0.054472,0.070300,-0.027804,-0.034973,0.072339,-0.021813,-0.045067,0.054789,-0.018973,-0.042675,0.062092,-0.024815,-0.038972,0.064697,-0.027832,-0.008835,0.047087,-0.017626,-0.009628,0.046939,-0.004124,-0.041518,0.073704,-0.004074,-0.044589,0.063583,-0.004043,-0.042751,0.068437,-0.002868,-0.010045,0.047204,-0.038718,-0.032082,0.051158,-0.045522,-0.021951,0.059984,-0.047280,-0.016832,0.073485,-0.057315,-0.003752,0.047054,-0.047398,0.004356,0.042686,-0.043789,-0.007903,0.045077,-0.036464,-0.010279,0.046526,-0.003895,-0.049291,0.057831,-0.024625,-0.158627,0.049429,-0.001813,-0.184622,0.048678,-0.000093,-0.159796,0.043746,-0.026127,-0.184718,0.050447,-0.052388,-0.160792,0.050002,-0.055775,-0.187303,0.053289,-0.085681,-0.163168,0.048528,-0.093195,-0.189768,0.048013,-0.116621,-0.161947,0.037952,-0.134564,-0.185956,0.039158,-0.026623,0.180379,0.084059,-0.005834,0.167102,0.101320,-0.005119,0.194426,0.069561,-0.005510,0.182408,0.086942,-0.054776,0.171838,0.068793,-0.042412,0.176746,0.077745,-0.026734,0.165597,0.099337,-0.054204,0.159275,0.084797,-0.042082,0.163073,0.093784,-0.060646,0.135494,0.088155,-0.050721,0.141290,0.098897,-0.055943,0.121795,0.097357,-0.067003,0.121636,0.078133,-0.065894,0.150989,0.072107,-0.014653,0.092699,0.101535,-0.015612,0.088031,0.100842,-0.016763,0.098276,0.102889,-0.030465,0.078179,0.098113,-0.028980,0.074217,0.100579,-0.018756,0.084421,0.099593,-0.024090,0.081101,0.098518,-0.022873,0.077804,0.101956,-0.028212,0.095185,0.101234,-0.028038,0.099315,0.101655,-0.026812,0.102636,0.103524,-0.021761,0.087047,0.097814,-0.026222,0.083978,0.097941,-0.019353,0.089523,0.097503,-0.018680,0.092113,0.097164,-0.020943,0.096287,0.098645,-0.031859,0.080978,0.098156,-0.023395,0.088269,0.097933,-0.027673,0.085588,0.098615,-0.021374,0.090007,0.097492,-0.021087,0.091043,0.097836,-0.023786,0.092620,0.098749,-0.024793,0.087007,0.089414,-0.026232,0.088554,0.092648,-0.025265,0.093400,0.093515,-0.025579,0.092382,0.093944,-0.023583,0.095453,0.089530,-0.024932,0.094779,0.092392,-0.024859,0.094252,0.093756,-0.024693,0.093522,0.092190,-0.023138,0.093552,0.089611,-0.026593,0.100551,0.089451,-0.024680,0.092166,0.092370,-0.022948,0.091885,0.089467,-0.023059,0.089114,0.089327,-0.029666,0.083612,0.089467,-0.022723,0.089985,0.097086,-0.028083,0.090724,0.100977,-0.028141,0.088195,0.099721,-0.022322,0.090488,0.097614,-0.024113,0.090056,0.097874,-0.026420,0.097343,0.092550,-0.027331,0.093387,0.095019,-0.028046,0.089445,0.097313,-0.024875,0.093103,0.094590,-0.025059,0.092031,0.094926,-0.025397,0.091210,0.094212,-0.024803,0.090398,0.092812,-0.024712,0.091118,0.094877,-0.024302,0.092681,0.094990,-0.024491,0.093401,0.094978,-0.024028,0.091793,0.095023,-0.023993,0.091173,0.095123,-0.023587,0.091756,0.095525,-0.024778,0.092118,0.095293,-0.024776,0.090526,0.096402,-0.030452,0.085373,0.092747,-0.031533,0.086316,0.096303,-0.032909,0.082862,0.099074,-0.024529,0.088609,0.097949,-0.028198,0.086793,0.098979,-0.033240,0.084712,0.099815,-0.027472,0.088184,0.098665,-0.032711,0.086514,0.099964,-0.023414,0.091548,0.095745,-0.023162,0.090748,0.095951,-0.023005,0.090888,0.096412,-0.023466,0.091162,0.095385,-0.023596,0.091128,0.095377,-0.024295,0.090485,0.094667,-0.026022,0.089797,0.095104,-0.031917,0.088236,0.098105,-0.032140,0.088038,0.099151,-0.026488,0.089578,0.097361,-0.026297,0.090022,0.096254,-0.030089,0.078410,0.071324,-0.025622,0.083592,0.070635,-0.027336,0.098460,0.071626,-0.023907,0.091143,0.070708,-0.028602,0.079390,0.085189,-0.028699,0.076508,0.077464,-0.022173,0.082735,0.076927,-0.022325,0.085149,0.085426,-0.020471,0.091753,0.076946,-0.021201,0.092711,0.085670,-0.024626,0.101022,0.077634,-0.024957,0.101579,0.084513,-0.034369,0.107614,0.084828,-0.033861,0.106714,0.078622,-0.059311,0.078470,0.085955,-0.037920,0.075946,0.097458,-0.046142,0.075239,0.094953,-0.053726,0.075980,0.090548,-0.036668,0.070836,0.099868,-0.046294,0.067889,0.098260,-0.056449,0.065500,0.093286,-0.053817,0.088665,0.092313,-0.051994,0.091745,0.095769,-0.047361,0.094714,0.100871,-0.038148,0.096131,0.104252,-0.055688,0.092555,0.091297,-0.060753,0.104135,0.094664,-0.054716,0.097117,0.095662,-0.039643,0.102326,0.103713,-0.054021,0.109088,0.102587,-0.049191,0.100938,0.101550,-0.045967,0.079232,0.093776,-0.051499,0.080390,0.090324,-0.058974,0.086810,0.084880,-0.055922,0.082915,0.086939,-0.039094,0.079203,0.096915,-0.050418,0.102786,0.084624,-0.044336,0.106033,0.087462,-0.034739,0.105640,0.089617,-0.051156,0.091345,0.081374,-0.036820,0.081097,0.088520,-0.043773,0.082132,0.086122,-0.049840,0.088191,0.082124,-0.047694,0.084841,0.083870,-0.052102,0.098040,0.082787,-0.051889,0.093974,0.081637,-0.033780,0.101193,0.091330,-0.042623,0.101941,0.089327,-0.049287,0.100885,0.086830,-0.043468,0.094471,0.092501,-0.034125,0.094404,0.094490,-0.035640,0.087540,0.098078,-0.044809,0.086898,0.095613,-0.051230,0.086237,0.092399,-0.052613,0.086554,0.092367,-0.055198,0.088204,0.089146,-0.051543,0.086609,0.090692,-0.050514,0.088443,0.089607,-0.047590,0.085473,0.086893,-0.048933,0.085788,0.091765,-0.050266,0.087900,0.090351,-0.050120,0.087142,0.091950,-0.050092,0.087397,0.089673,-0.049517,0.088182,0.085108,-0.050515,0.089210,0.087743,-0.050535,0.091215,0.083857,-0.050623,0.091015,0.087109,-0.051066,0.093758,0.083865,-0.051064,0.097147,0.085101,-0.048746,0.087128,0.093341,-0.050190,0.087973,0.091228,-0.050488,0.092507,0.088301,-0.049102,0.094562,0.090293,-0.051042,0.087238,0.095821,-0.049850,0.085470,0.095136,-0.046090,0.084687,0.098591,-0.037256,0.084974,0.101306,-0.038382,0.088992,0.103595,-0.047027,0.088273,0.100278,-0.043679,0.083547,0.088695,-0.036966,0.082811,0.091220,-0.045525,0.084959,0.093607,-0.038794,0.084005,0.095878,-0.039132,0.086946,0.098150,-0.046557,0.081435,0.094977,-0.050652,0.082502,0.091942,-0.052880,0.084223,0.089543,-0.054504,0.086177,0.088300,-0.050071,0.083772,0.093372,-0.046622,0.083394,0.096172,-0.046181,0.085103,0.096947,-0.049729,0.084887,0.094288,-0.051959,0.085735,0.090689,-0.051446,0.084744,0.091633,-0.050681,0.086577,0.091453,-0.051181,0.085756,0.091670,-0.050838,0.085306,0.092631,-0.050323,0.086388,0.092699,-0.039897,0.081416,0.097931,-0.040128,0.083662,0.099042,-0.039308,0.086927,0.099231,-0.039797,0.085458,0.099656,-0.045833,0.086437,0.097059,-0.045701,0.086769,0.096049,-0.049131,0.086755,0.093831,-0.049261,0.086069,0.094388,-0.035515,0.099816,0.069801,-0.039780,0.100077,0.070121,-0.048148,0.093848,0.071291,-0.046226,0.084357,0.069501,-0.047268,0.088752,0.070128,-0.046805,0.098928,0.072441,-0.041911,0.103189,0.073293,-0.034090,0.103253,0.072985,-0.044082,0.080661,0.069510,-0.040944,0.077922,0.070323,-0.036345,0.076631,0.071263,-0.037180,0.081462,0.067357,-0.035208,0.080020,0.068193,-0.032351,0.081171,0.068060,-0.051872,0.091018,0.079283,-0.050797,0.089154,0.074898,-0.050372,0.102098,0.081195,-0.052173,0.096548,0.079727,-0.051111,0.094983,0.075902,-0.049425,0.100855,0.077103,-0.049468,0.084104,0.074334,-0.050352,0.086160,0.079239,-0.047191,0.079752,0.074524,-0.048098,0.082366,0.080533,-0.043459,0.076383,0.075626,-0.044014,0.079199,0.082389,-0.037089,0.077587,0.084357,-0.037159,0.074612,0.077023,-0.044514,0.106844,0.083434,-0.043565,0.106061,0.078376,-0.062916,0.113161,0.088723,-0.065756,0.101403,0.083468,-0.062607,0.082627,0.082146,-0.064520,0.090055,0.080866,-0.064015,0.066852,0.086019,-0.067968,0.072425,0.079358,-0.062463,0.098499,0.088589,-0.061156,0.091842,0.085157,-0.024513,0.017056,0.103171,-0.025667,0.018740,0.102187,-0.026060,0.020712,0.102302,-0.030321,0.015660,0.097356,-0.028873,0.041813,0.083435,-0.021752,0.041584,0.085125,-0.031238,0.031273,0.095586,-0.028914,0.023814,0.098850,-0.030408,0.020475,0.097718,-0.014157,0.041810,0.086133,-0.028613,0.011119,0.098187,-0.003074,0.041712,0.086758,-0.045220,0.057293,0.102873,-0.047330,0.033899,0.103874,-0.056532,0.042481,0.094066,-0.047181,0.014487,0.102165,-0.054604,0.011883,0.092249,-0.042979,0.037149,0.074416,-0.036594,0.041733,0.079745,-0.037909,0.023433,0.089894,-0.035868,0.029741,0.092511,-0.038289,0.011914,0.089547,-0.036007,0.001319,0.090844,-0.045301,0.024817,0.070512,-0.045029,0.006642,0.069863,-0.066196,0.044019,0.080955,-0.019679,-0.036147,0.081153,-0.022323,-0.031120,0.087728,-0.022927,-0.025558,0.098269,-0.013287,-0.032157,0.092279,-0.029139,-0.004295,0.093171,-0.024339,-0.014152,0.075905,-0.015191,-0.014610,0.076576,-0.004243,-0.038300,0.083967,-0.002082,-0.032806,0.093488,-0.003440,-0.013472,0.076518,-0.031995,-0.014923,0.103011,-0.032752,-0.027704,0.080896,-0.031575,-0.021896,0.092726,-0.037034,0.003860,0.105454,-0.043939,-0.011587,0.089632,-0.040533,-0.003842,0.100405,-0.041499,-0.007436,0.071639,-0.033862,-0.012846,0.074072,-0.022638,0.125175,0.115216,-0.025869,0.143896,0.110401,-0.007052,0.144995,0.110579,-0.007211,0.124599,0.114323,-0.046114,0.125063,0.105786,-0.035578,0.125313,0.112213,-0.040104,0.142958,0.106859,-0.008659,0.062406,0.118524,-0.008388,0.061545,0.117884,-0.010678,0.062395,0.116873,-0.012301,0.063022,0.118637,-0.011861,0.062906,0.117745,-0.011295,0.063011,0.119612,-0.009851,0.063024,0.119366,-0.010512,0.061548,0.116538,-0.009292,0.061755,0.116779,-0.018538,0.110637,0.115208,-0.029485,0.110808,0.112532,-0.021663,0.103587,0.107679,-0.014434,0.103535,0.111769,-0.012467,0.098342,0.109779,-0.011511,0.078513,0.121076,-0.016534,0.066850,0.122341,-0.019244,0.062856,0.117848,-0.026138,0.062762,0.107804,-0.021845,0.067433,0.109533,-0.022252,0.073074,0.106062,-0.027682,0.069055,0.104618,-0.021804,0.062243,0.112204,-0.018572,0.066792,0.115058,-0.015734,0.070678,0.119433,-0.018398,0.071418,0.112311,-0.014944,0.075194,0.116252,-0.017940,0.076778,0.108700,-0.017970,0.081444,0.104343,-0.011953,0.073637,0.124411,-0.012701,0.070004,0.127575,-0.013212,0.065853,0.130542,-0.017453,0.062561,0.125935,-0.014277,0.085539,0.107205,-0.014498,0.080761,0.112549,-0.011625,0.084844,0.117181,-0.012068,0.091428,0.110843,-0.006581,0.110730,0.115889,-0.006111,0.098533,0.112922,-0.006000,0.103952,0.113891,-0.006027,0.092781,0.115273,-0.006307,0.086562,0.119751,-0.005954,0.079966,0.123833,-0.004580,0.067597,0.132601,-0.005448,0.074997,0.127009,-0.005031,0.071380,0.129566,-0.035289,0.064270,0.104418,-0.041054,0.109419,0.109027,-0.016299,0.055893,0.119306,-0.016004,0.056966,0.121476,-0.013347,0.057379,0.124114,-0.008868,0.056451,0.126350,-0.007633,0.055644,0.124033,-0.008746,0.055700,0.120652,-0.009930,0.054697,0.118305,-0.014812,0.054714,0.117654,-0.012542,0.053995,0.117039,-0.007514,0.059570,0.121020,-0.007791,0.058987,0.118823,-0.013213,0.059003,0.116673,-0.014416,0.060836,0.119436,-0.014598,0.059964,0.117798,-0.009306,0.060584,0.122596,-0.012400,0.061032,0.121317,-0.011189,0.058504,0.116486,-0.009108,0.058679,0.117282,-0.032301,0.056899,0.107741,-0.020417,0.059415,0.121484,-0.023984,0.056894,0.109639,-0.024214,0.052278,0.114272,-0.012022,0.012718,0.119851,-0.021323,0.016215,0.105238,-0.011557,0.019572,0.119962,-0.010797,0.023257,0.117496,-0.015952,0.016798,0.107822,-0.010103,0.023319,0.113708,-0.009898,0.017716,0.109213,-0.012914,0.060509,0.133723,-0.008951,0.051467,0.132121,-0.010829,0.054891,0.134479,-0.013452,0.054773,0.132269,-0.008825,0.053056,0.125254,-0.009252,0.051088,0.125068,-0.007685,0.049485,0.127081,-0.007947,0.050018,0.129444,-0.019711,0.007037,0.114582,-0.019398,0.014031,0.116937,-0.018160,0.019746,0.115907,-0.023189,0.021261,0.109858,-0.015860,0.022616,0.111778,-0.020061,0.021471,0.109167,-0.020818,0.021556,0.111729,-0.016836,0.022552,0.114478,-0.022392,0.019563,0.112296,-0.024243,0.016354,0.112586,-0.026282,0.010537,0.111723,-0.024537,0.020032,0.110828,-0.026563,0.018126,0.110698,-0.025210,0.022169,0.103261,-0.022539,0.022939,0.105412,-0.021201,0.022066,0.109778,-0.017850,0.022667,0.112491,-0.018800,0.023517,0.108146,-0.022334,0.024533,0.115585,-0.021043,0.022229,0.113025,-0.017826,0.023897,0.116188,-0.024392,0.020936,0.108992,-0.023398,0.021230,0.110376,-0.024546,0.020982,0.109204,-0.023883,0.021559,0.107378,-0.024528,0.022236,0.112865,-0.025501,0.020386,0.110335,-0.025440,0.021094,0.111389,-0.027847,0.020020,0.111012,-0.028075,0.022047,0.112562,-0.026892,0.024773,0.114105,-0.023719,0.028451,0.116464,-0.019300,0.032210,0.119426,-0.018710,0.027554,0.119251,-0.014550,0.030207,0.121890,-0.010412,0.030840,0.123560,-0.014613,0.034946,0.121495,-0.010199,0.035599,0.122619,-0.012389,0.049226,0.120574,-0.012109,0.047671,0.120033,-0.009129,0.045534,0.121760,-0.012264,0.045776,0.119912,-0.015447,0.046026,0.117263,-0.019086,0.037493,0.118478,-0.017320,0.042490,0.117321,-0.019729,0.046317,0.114287,-0.029217,0.029706,0.114034,-0.024336,0.034305,0.115884,-0.022715,0.040950,0.114157,-0.014208,0.025467,0.118851,-0.010177,0.026150,0.120575,-0.010223,0.023637,0.116108,-0.014322,0.023151,0.114536,-0.014851,0.023779,0.110049,-0.010190,0.023773,0.111257,-0.007923,0.049192,0.125001,-0.008848,0.047098,0.122241,-0.009033,0.048667,0.123045,-0.013375,0.054145,0.126509,-0.015295,0.053336,0.128686,-0.016892,0.057103,0.129895,-0.020185,0.055255,0.125141,-0.015633,0.053479,0.124104,-0.017459,0.052532,0.125854,-0.011515,0.052725,0.119611,-0.012383,0.051052,0.120637,-0.010565,0.051077,0.122789,-0.010479,0.053586,0.122129,-0.009369,0.051304,0.127339,-0.009848,0.051122,0.129019,-0.011907,0.052439,0.130161,-0.009862,0.053692,0.127625,-0.010234,0.039479,0.121916,-0.009821,0.042950,0.121565,-0.013319,0.042974,0.120005,-0.014410,0.039157,0.120697,-0.013559,0.052107,0.118154,-0.014579,0.050931,0.119139,-0.016652,0.050864,0.120237,-0.015845,0.052583,0.118899,-0.016764,0.053152,0.121353,-0.017848,0.051316,0.122999,-0.015240,0.049465,0.119108,-0.020026,0.047512,0.117674,-0.015217,0.048154,0.117929,-0.023603,0.051408,0.117165,-0.019429,0.048868,0.120277,-0.021916,0.052842,0.121404,-0.022710,0.056979,0.119118,-0.023339,0.057982,0.115402,-0.023817,0.053679,0.117457,-0.023879,0.047101,0.110394,-0.028247,0.050734,0.108342,-0.022708,0.020755,0.106991,-0.024869,0.021249,0.106172,-0.024349,0.020885,0.106118,-0.029947,0.037872,0.111758,-0.021049,0.026064,0.103324,-0.024998,0.031689,0.097773,-0.016149,0.026732,0.105299,-0.018810,0.031876,0.099729,-0.025577,0.025409,0.100736,-0.010499,0.027055,0.106273,-0.012057,0.032057,0.100937,-0.010308,0.008889,0.104748,-0.023786,0.008868,0.100248,-0.017088,0.008703,0.102959,-0.005413,0.045188,0.121847,-0.002360,0.012328,0.118759,-0.003685,0.017967,0.109386,-0.003572,0.019445,0.121159,-0.004120,0.023239,0.114403,-0.004176,0.023123,0.118402,-0.004457,0.062040,0.136611,-0.004745,0.054694,0.136294,-0.004756,0.050748,0.132589,-0.004552,0.049729,0.129413,-0.004557,0.049123,0.126833,-0.006030,0.030213,0.124423,-0.006227,0.035035,0.122187,-0.005370,0.025711,0.120972,-0.004935,0.023529,0.116722,-0.004424,0.023674,0.111773,-0.004828,0.048315,0.124741,-0.005045,0.047464,0.123467,-0.005195,0.046586,0.122640,-0.005807,0.042457,0.121209,-0.006157,0.038802,0.121170,-0.003956,0.026963,0.106467,-0.003702,0.032208,0.101257,-0.003293,0.008585,0.105195,-0.040367,0.048152,0.107331,-0.029495,0.014711,0.109409,-0.033168,0.009897,0.108029,-0.031840,0.018953,0.110200,-0.031900,0.023961,0.112111,-0.034615,0.042062,0.109114,-0.036154,0.017979,0.109085,-0.035568,0.027186,0.110686,-0.040395,0.030163,0.108314,-0.041226,0.016591,0.106682,-0.014638,-0.010980,0.118745,-0.012694,-0.002312,0.116929,-0.011626,0.005360,0.116196,-0.023403,-0.010085,0.113236,-0.021078,-0.001063,0.113474,-0.024340,-0.019435,0.108718,-0.015220,-0.020859,0.114643,-0.014293,-0.027011,0.103197,-0.011538,-0.006750,0.096632,-0.019844,-0.006333,0.095631,-0.001263,0.004978,0.116316,-0.000434,-0.001515,0.118404,0.000218,-0.009107,0.120204,-0.000460,-0.027748,0.104325,0.000540,-0.020983,0.117177,-0.003077,-0.006450,0.096621,-0.028206,0.003185,0.110089,-0.030484,-0.005415,0.108062,0.072067,0.145246,0.032524,0.065598,0.143694,0.049512,0.067815,0.122314,0.045894,0.072032,0.124413,0.030700,0.070002,0.134723,0.039658,0.070050,0.103557,0.031861,0.071727,0.102304,0.023242,0.074475,0.118244,0.017268,0.071871,0.112739,0.025698,0.071409,0.090412,0.024853,0.072118,0.092052,0.020527,0.072700,0.099978,0.015144,0.071850,0.095639,0.021102,0.073856,0.085312,0.021743,0.073980,0.090068,0.020764,0.072808,0.088291,0.021772,0.072407,0.081731,0.022737,0.073238,0.086751,0.021993,0.072991,0.092657,0.018570,0.071718,0.084034,0.023340,0.072500,0.089826,0.021213,0.033806,0.103328,0.082223,0.029424,0.105408,0.085200,0.024367,0.105119,0.082876,0.029132,0.104385,0.080139,0.029288,0.105113,0.082838,0.019717,0.103365,0.085303,0.016254,0.099657,0.081688,0.020134,0.102395,0.079218,0.019777,0.103162,0.082359,0.014322,0.095601,0.084632,0.013695,0.090184,0.081147,0.014715,0.094577,0.077765,0.014273,0.095132,0.081274,0.014376,0.086443,0.084684,0.016153,0.081054,0.081423,0.014819,0.084803,0.077277,0.014363,0.085407,0.081117,0.019000,0.079255,0.085394,0.022669,0.074522,0.082511,0.019533,0.076383,0.078017,0.019032,0.077309,0.081975,0.026300,0.075375,0.085909,0.030455,0.072090,0.082710,0.026829,0.071454,0.078866,0.026629,0.072800,0.082788,0.036269,0.073141,0.081302,0.033549,0.070754,0.078351,0.033475,0.075072,0.085384,0.033726,0.072301,0.082171,0.039507,0.075803,0.079555,0.037747,0.072800,0.076997,0.038070,0.077105,0.083223,0.038141,0.074329,0.080380,0.040433,0.079827,0.081122,0.041240,0.079573,0.078494,0.040124,0.076325,0.076123,0.040506,0.077563,0.078913,0.041761,0.090264,0.078705,0.041170,0.094264,0.080582,0.039746,0.096765,0.080102,0.040707,0.092822,0.077533,0.041101,0.093407,0.079272,0.042055,0.084428,0.078271,0.042046,0.088545,0.079708,0.041685,0.086509,0.076549,0.042055,0.087265,0.078378,0.041679,0.083384,0.079967,0.041382,0.080899,0.076062,0.041763,0.081835,0.078297,0.036957,0.099731,0.079091,0.037516,0.100831,0.082826,0.037344,0.100283,0.081187,0.015376,0.089271,0.074207,0.018124,0.092714,0.072093,0.017882,0.097788,0.075345,0.015989,0.093768,0.074645,0.020393,0.088233,0.069756,0.024225,0.090009,0.068870,0.022583,0.094326,0.070788,0.021034,0.091454,0.070148,0.024356,0.084804,0.068369,0.018195,0.084737,0.071512,0.022630,0.081425,0.069739,0.021154,0.084753,0.069606,0.017879,0.080363,0.074239,0.016068,0.084673,0.074044,0.023507,0.073828,0.075253,0.021795,0.077658,0.072199,0.020421,0.076683,0.074735,0.025119,0.076741,0.070716,0.025959,0.079203,0.068981,0.023759,0.078735,0.070221,0.027321,0.077136,0.069540,0.029366,0.076883,0.069346,0.028608,0.079279,0.068342,0.027784,0.078430,0.068748,0.029167,0.074689,0.070982,0.027007,0.073468,0.072987,0.027103,0.075403,0.070952,0.030225,0.071056,0.075468,0.026941,0.071938,0.075522,0.035036,0.071883,0.074522,0.031990,0.072692,0.072631,0.032920,0.071134,0.075084,0.032074,0.075423,0.070292,0.030779,0.074808,0.070697,0.034256,0.077370,0.069626,0.031220,0.078131,0.068728,0.035157,0.074386,0.071668,0.033235,0.076266,0.069911,0.038015,0.074565,0.073592,0.036692,0.073039,0.073984,0.022273,0.098963,0.073704,0.024807,0.102730,0.077068,0.020941,0.100914,0.076260,0.028969,0.101006,0.074995,0.033035,0.101516,0.077349,0.029023,0.102925,0.077451,0.035258,0.097540,0.074607,0.038505,0.095473,0.076154,0.036275,0.098767,0.076828,0.038409,0.081459,0.071401,0.039827,0.078537,0.073483,0.040616,0.083388,0.073981,0.040329,0.080834,0.073666,0.032454,0.083147,0.068380,0.035558,0.080465,0.069487,0.035504,0.084662,0.069815,0.035567,0.082444,0.069574,0.030208,0.081734,0.067926,0.028618,0.083902,0.067905,0.030324,0.082966,0.067938,0.032641,0.080018,0.068415,0.037359,0.077405,0.071192,0.035098,0.078766,0.069494,0.039059,0.076429,0.073438,0.029804,0.080181,0.068042,0.030700,0.080755,0.067997,0.026733,0.086858,0.068066,0.026642,0.085132,0.067951,0.028578,0.088983,0.068465,0.026535,0.088649,0.068312,0.032823,0.087945,0.069076,0.030575,0.090651,0.069061,0.030526,0.089222,0.068712,0.036398,0.089263,0.070959,0.038853,0.086382,0.072235,0.036023,0.086944,0.070338,0.040489,0.089225,0.074967,0.040699,0.086227,0.074432,0.033605,0.091553,0.070140,0.038348,0.091853,0.073442,0.035317,0.093953,0.072116,0.036189,0.091589,0.071550,0.039832,0.092287,0.075536,0.031728,0.098169,0.073048,0.031932,0.095359,0.071244,0.033846,0.096304,0.072675,0.030140,0.093027,0.069769,0.031330,0.091711,0.069477,0.026245,0.098561,0.072552,0.029074,0.096952,0.071524,0.028963,0.098944,0.072983,0.026666,0.095319,0.070562,0.029393,0.094975,0.070494,0.024200,0.096888,0.071716,0.029690,0.079414,0.068218,0.037037,0.086451,0.094031,0.035719,0.085919,0.095852,0.037529,0.086139,0.094706,0.038160,0.086778,0.093139,0.037303,0.086367,0.094414,0.019512,0.087600,0.099163,0.022780,0.086933,0.099494,0.019673,0.087972,0.097847,0.016705,0.088328,0.097358,0.019577,0.087885,0.098450,0.014432,0.089457,0.095064,0.013637,0.089680,0.095256,0.014731,0.089263,0.095570,0.015459,0.088900,0.094938,0.014457,0.089285,0.095259,0.013584,0.089645,0.095751,0.013112,0.090038,0.095422,0.013042,0.090144,0.096102,0.012998,0.089657,0.096310,0.012970,0.089870,0.095778,0.026317,0.086005,0.099988,0.022801,0.086255,0.100447,0.026406,0.084821,0.100275,0.029988,0.085167,0.099224,0.026337,0.085484,0.100230,0.017089,0.087325,0.098900,0.020167,0.086334,0.100092,0.019748,0.087053,0.099723,0.023288,0.084722,0.100654,0.026695,0.083154,0.100074,0.030100,0.083804,0.099327,0.026542,0.084044,0.100269,0.018315,0.086064,0.099686,0.020865,0.084675,0.100318,0.020587,0.085534,0.100319,0.016601,0.085944,0.099086,0.016081,0.086662,0.098770,0.016850,0.086237,0.099161,0.023632,0.082861,0.100078,0.026785,0.081382,0.098982,0.030205,0.082111,0.098670,0.026793,0.082249,0.099629,0.040481,0.085642,0.091049,0.040546,0.086339,0.090632,0.039812,0.086947,0.091004,0.039705,0.086108,0.091665,0.040143,0.086248,0.091094,0.041084,0.085621,0.090295,0.040425,0.084899,0.091280,0.041296,0.084891,0.089958,0.040848,0.085205,0.090665,0.038986,0.086641,0.092337,0.038651,0.085887,0.093539,0.039581,0.085337,0.092459,0.039245,0.086016,0.092463,0.036035,0.085274,0.096393,0.037921,0.085007,0.094979,0.037713,0.085609,0.094870,0.033335,0.085530,0.097696,0.033447,0.084479,0.098052,0.033396,0.085089,0.097902,0.036226,0.083945,0.096497,0.033515,0.082945,0.097777,0.033499,0.083742,0.098045,0.038070,0.083579,0.094444,0.039118,0.084493,0.093369,0.038044,0.084291,0.094858,0.040114,0.084101,0.091576,0.039850,0.084675,0.092165,0.041250,0.084012,0.089673,0.042874,0.084123,0.087643,0.042537,0.085288,0.088484,0.041953,0.084590,0.088976,0.039411,0.083223,0.092128,0.040802,0.082882,0.089603,0.040437,0.083559,0.090740,0.036136,0.082369,0.095586,0.038090,0.082084,0.092956,0.038093,0.082849,0.093805,0.033363,0.081216,0.096581,0.033498,0.082081,0.097283,0.029833,0.085784,0.098574,0.026280,0.085690,0.098783,0.026324,0.086091,0.099490,0.032901,0.085395,0.096744,0.033138,0.085678,0.097290,0.035115,0.085149,0.094523,0.032322,0.083159,0.094671,0.029544,0.084041,0.097058,0.032651,0.084281,0.095929,0.025681,0.083267,0.096367,0.022718,0.085916,0.097852,0.026108,0.084417,0.097833,0.019444,0.087005,0.096218,0.016840,0.088666,0.096367,0.019582,0.087602,0.097213,0.022173,0.084585,0.094973,0.028562,0.082422,0.093959,0.025029,0.082668,0.093153,0.025249,0.082918,0.094699,0.034493,0.084001,0.091526,0.031541,0.082365,0.091229,0.031749,0.082868,0.092849,0.026772,0.087568,0.103281,0.030433,0.085293,0.102174,0.033787,0.087217,0.100556,0.030875,0.090064,0.102555,0.030564,0.087274,0.102375,0.036327,0.085513,0.098413,0.038857,0.086992,0.096295,0.036925,0.089640,0.098204,0.036486,0.087163,0.098408,0.039778,0.089890,0.088952,0.038725,0.087214,0.092273,0.037757,0.088260,0.092371,0.039542,0.091978,0.088660,0.038924,0.089047,0.090584,0.041312,0.091297,0.084594,0.040818,0.091447,0.086318,0.040854,0.093527,0.085701,0.041527,0.092939,0.083568,0.041303,0.092436,0.084950,0.040623,0.090295,0.086171,0.041167,0.090189,0.083317,0.040530,0.089386,0.085305,0.041016,0.090321,0.084738,0.039570,0.088693,0.087910,0.040115,0.087993,0.084284,0.039139,0.087460,0.087256,0.039864,0.088441,0.086184,0.039193,0.087220,0.091352,0.038551,0.087248,0.091784,0.038748,0.087009,0.092120,0.040005,0.087853,0.090174,0.039368,0.088060,0.090052,0.039583,0.087501,0.090732,0.037764,0.086779,0.092291,0.036455,0.085561,0.092123,0.036752,0.086071,0.093338,0.038346,0.087087,0.090175,0.038480,0.085876,0.086314,0.037388,0.085754,0.089366,0.038294,0.086613,0.088325,0.036233,0.084120,0.088582,0.036257,0.084968,0.090385,0.038971,0.087913,0.090221,0.038443,0.087361,0.091270,0.039874,0.089256,0.088169,0.039384,0.088587,0.089152,0.040205,0.089320,0.088830,0.040486,0.090183,0.087060,0.040322,0.089848,0.087403,0.040089,0.089126,0.089356,0.040367,0.090211,0.087769,0.040736,0.087222,0.090107,0.041791,0.086133,0.089435,0.041033,0.086279,0.090136,0.042802,0.086823,0.088613,0.044728,0.086142,0.086463,0.043043,0.086061,0.088263,0.040639,0.088265,0.089732,0.040439,0.088241,0.089835,0.041090,0.087164,0.090665,0.043015,0.087729,0.089307,0.041245,0.086998,0.091963,0.042040,0.087097,0.090065,0.039779,0.086368,0.093998,0.040678,0.088278,0.093805,0.040295,0.086949,0.094064,0.039856,0.087281,0.091718,0.040382,0.087971,0.090495,0.038004,0.085781,0.095437,0.039152,0.086479,0.093470,0.033299,0.085065,0.099391,0.035743,0.085853,0.095971,0.035908,0.085319,0.097467,0.026405,0.085485,0.101630,0.030066,0.085621,0.099257,0.030184,0.085042,0.100862,0.013845,0.090667,0.095915,0.015069,0.090109,0.096467,0.013602,0.089742,0.096914,0.013777,0.090256,0.096344,0.013588,0.090207,0.095277,0.013287,0.090601,0.095559,0.013302,0.090162,0.095203,0.014122,0.089932,0.095237,0.014254,0.090450,0.095413,0.013766,0.090852,0.095384,0.013824,0.090303,0.095308,0.013776,0.091441,0.095724,0.014531,0.092043,0.095800,0.013805,0.091126,0.095752,0.014138,0.091530,0.095393,0.013955,0.092146,0.095434,0.013778,0.091517,0.095400,0.014860,0.090018,0.095447,0.015261,0.089503,0.094925,0.014643,0.089628,0.095264,0.015676,0.090184,0.094516,0.015444,0.089067,0.094053,0.015440,0.089893,0.093699,0.015650,0.089574,0.094313,0.015377,0.090731,0.095208,0.014646,0.091107,0.095341,0.014830,0.090566,0.095429,0.014246,0.092093,0.095252,0.014751,0.091815,0.095135,0.014413,0.091637,0.095326,0.018627,0.089740,0.097645,0.021554,0.092710,0.096768,0.026266,0.088440,0.098213,0.021968,0.087093,0.099878,0.021766,0.089199,0.098308,0.030198,0.093181,0.095713,0.033628,0.088033,0.095903,0.030271,0.088020,0.097382,0.036401,0.092900,0.092254,0.036070,0.088102,0.094160,0.038732,0.095804,0.088455,0.040497,0.096260,0.085472,0.040023,0.094585,0.086881,0.033540,0.098128,0.092334,0.036875,0.100108,0.088688,0.036622,0.097114,0.090315,0.025267,0.097574,0.095003,0.029469,0.102099,0.092427,0.029687,0.098271,0.093959,0.017630,0.094721,0.095845,0.020585,0.099161,0.093872,0.020944,0.096282,0.095587,0.015022,0.094032,0.095193,0.016400,0.091772,0.096250,0.015741,0.093228,0.095689,0.016446,0.088588,0.097712,0.016640,0.089962,0.096835,0.012640,0.089616,0.097298,0.014546,0.088687,0.098039,0.012925,0.089341,0.098210,0.013315,0.089262,0.097624,0.015791,0.088201,0.099785,0.018792,0.087463,0.100038,0.016191,0.088040,0.098870,0.021992,0.086414,0.102563,0.022142,0.086435,0.101261,0.021986,0.090704,0.103209,0.018014,0.088793,0.101723,0.021963,0.088008,0.103073,0.014678,0.088244,0.097527,0.013958,0.087580,0.097880,0.015210,0.087394,0.098209,0.014787,0.089126,0.096254,0.013292,0.089302,0.096685,0.014656,0.088823,0.096768,0.012135,0.089390,0.097262,0.012696,0.089509,0.096858,0.041463,0.094668,0.083221,0.041879,0.091865,0.081673,0.041655,0.091072,0.082308,0.041735,0.092728,0.082593,0.039772,0.086206,0.083849,0.039511,0.084028,0.083871,0.037870,0.084064,0.086118,0.038905,0.085075,0.084932,0.037188,0.081938,0.086419,0.034652,0.082195,0.088641,0.036579,0.083111,0.087344,0.032326,0.080127,0.089061,0.028404,0.081374,0.091140,0.031770,0.081455,0.090042,0.021972,0.083310,0.091934,0.025281,0.080741,0.090255,0.025013,0.082027,0.091741,0.041655,0.088919,0.081493,0.041018,0.088606,0.082453,0.041395,0.089746,0.082257,0.040957,0.086462,0.082052,0.040493,0.087416,0.083000,0.014078,0.090805,0.091146,0.014748,0.090081,0.092511,0.014929,0.088296,0.091155,0.014253,0.088774,0.089390,0.014437,0.089527,0.091106,0.024774,0.103381,0.091981,0.017352,0.098400,0.091987,0.020412,0.102185,0.090373,0.020599,0.101043,0.092054,0.033861,0.103441,0.089370,0.029569,0.105277,0.089600,0.029510,0.104259,0.091118,0.037523,0.101961,0.085994,0.039421,0.099233,0.085616,0.037201,0.101580,0.087398,0.040977,0.096508,0.083005,0.040771,0.096860,0.084229,0.041780,0.092693,0.081194,0.042017,0.088553,0.080971,0.042037,0.090295,0.080861,0.040819,0.083562,0.081805,0.039109,0.081076,0.083887,0.040088,0.082259,0.082729,0.035794,0.078830,0.086550,0.037766,0.079941,0.085192,0.029498,0.077701,0.088303,0.032989,0.077948,0.087674,0.022331,0.079661,0.088195,0.025802,0.078314,0.088368,0.041720,0.086621,0.081002,0.041522,0.087914,0.080931,0.041372,0.085039,0.081221,0.013714,0.089880,0.087728,0.014836,0.085741,0.087650,0.014271,0.087644,0.087357,0.024452,0.105242,0.088427,0.016385,0.099881,0.087778,0.019846,0.103101,0.088279,0.034211,0.104270,0.086155,0.029570,0.105623,0.087657,0.039961,0.098505,0.082925,0.037698,0.101636,0.084430,0.041206,0.095464,0.081871,0.013826,0.092565,0.091388,0.014230,0.091958,0.092491,0.013611,0.091566,0.089724,0.013876,0.091833,0.091251,0.013417,0.091794,0.088134,0.013641,0.091093,0.088478,0.014178,0.092810,0.094877,0.014122,0.093272,0.095164,0.014087,0.092566,0.095205,0.014649,0.094551,0.094540,0.014537,0.094014,0.095020,0.014362,0.093724,0.094147,0.015073,0.095315,0.093236,0.014622,0.094563,0.093944,0.013624,0.093090,0.089998,0.014305,0.094438,0.091723,0.014146,0.093151,0.092738,0.013905,0.093294,0.091570,0.014957,0.096604,0.089955,0.015321,0.096208,0.091819,0.013706,0.093453,0.087922,0.013646,0.092394,0.088623,0.014463,0.096253,0.087596,0.015423,0.090822,0.094103,0.015268,0.091467,0.094677,0.015598,0.090862,0.094656,0.014548,0.092415,0.094556,0.014890,0.092069,0.094047,0.014913,0.091955,0.094657,0.014413,0.092986,0.093817,0.014469,0.092971,0.094389,0.014748,0.091347,0.093414,0.014420,0.092529,0.093381,0.014568,0.092042,0.093388,0.015073,0.090540,0.093477,0.014319,0.092904,0.093371,0.014862,0.089320,0.095909,0.019497,0.085731,0.093317,0.017377,0.087802,0.094384,0.019483,0.086427,0.094811,0.016012,0.087993,0.092807,0.016026,0.088536,0.094074,0.017250,0.086206,0.091497,0.015475,0.086265,0.089687,0.015760,0.087270,0.091270,0.019242,0.083544,0.090109,0.019379,0.084836,0.091798,0.016574,0.083641,0.088091,0.015511,0.085204,0.088215,0.019174,0.081518,0.088045,0.011690,0.091178,0.097980,0.011529,0.089912,0.097898,0.013784,0.089976,0.099236,0.012284,0.090046,0.098540,0.015764,0.091603,0.100378,0.015566,0.089532,0.100253,0.010959,0.089714,0.097293,0.012264,0.088780,0.097450,0.011610,0.089532,0.097343,0.020836,0.082940,0.099679,0.018521,0.084772,0.099608,0.020945,0.083793,0.100077,0.016130,0.085031,0.098775,0.014571,0.086414,0.098331,0.016367,0.085536,0.098978,0.012702,0.087551,0.097721,0.013236,0.087654,0.097795,0.026293,0.078994,0.097569,0.029964,0.080131,0.097279,0.023444,0.080912,0.098944,0.026624,0.080259,0.098325,0.046090,0.082183,0.085212,0.045424,0.084584,0.085347,0.043155,0.082381,0.087372,0.044372,0.083321,0.086326,0.042859,0.080350,0.088291,0.039932,0.081312,0.090167,0.041631,0.081728,0.088644,0.038485,0.079347,0.091649,0.035859,0.080430,0.093977,0.038158,0.080922,0.092014,0.032768,0.078719,0.095227,0.033103,0.080151,0.095805,0.048171,0.085658,0.082771,0.047203,0.088427,0.083996,0.046443,0.086247,0.084409,0.008774,0.093866,0.096801,0.009982,0.090933,0.097344,0.011831,0.094823,0.098254,0.010713,0.092543,0.097262,0.008533,0.089606,0.097155,0.010787,0.088600,0.097303,0.010046,0.089741,0.097177,0.020234,0.080764,0.098379,0.018023,0.083178,0.098906,0.020599,0.082029,0.099097,0.015112,0.083161,0.097994,0.013692,0.085589,0.098108,0.015760,0.084315,0.098420,0.010943,0.086355,0.097736,0.012030,0.087207,0.097735,0.036004,0.108026,0.105284,0.028466,0.103392,0.106577,0.032438,0.099958,0.102941,0.039345,0.101754,0.101169,0.034483,0.102850,0.104710,0.045929,0.104381,0.096362,0.040266,0.097374,0.097182,0.045091,0.098446,0.092669,0.043092,0.100249,0.096960,0.049311,0.091282,0.082621,0.047132,0.093668,0.086260,0.045599,0.090205,0.086814,0.047483,0.091027,0.084595,0.049098,0.098088,0.087461,0.043930,0.094359,0.090747,0.046277,0.096072,0.089042,0.020192,0.103951,0.108459,0.016011,0.101064,0.102485,0.021169,0.101026,0.103469,0.021424,0.102907,0.105691,0.011465,0.099512,0.100562,0.014673,0.096771,0.099949,0.013321,0.098041,0.099889,0.021440,0.096262,0.103045,0.018156,0.093369,0.101816,0.026632,0.093416,0.104064,0.021823,0.093629,0.103340,0.015675,0.094393,0.100435,0.016140,0.093055,0.100741,0.031177,0.095672,0.103050,0.035004,0.092924,0.100641,0.031078,0.093086,0.102872,0.038329,0.094236,0.097990,0.039675,0.091092,0.095558,0.037760,0.092339,0.098118,0.041915,0.091530,0.092445,0.042469,0.089048,0.090949,0.041253,0.089933,0.093233,0.044042,0.089159,0.088426,0.043232,0.088591,0.089205,0.017352,0.097635,0.101239,0.015579,0.096264,0.100336,0.026359,0.098588,0.103757,0.021096,0.098559,0.102903,0.035540,0.096948,0.100670,0.031423,0.097742,0.102861,0.041090,0.094390,0.094503,0.038864,0.095663,0.097673,0.043810,0.091124,0.089673,0.042702,0.092941,0.091818,0.044552,0.089998,0.088252,0.003009,-0.013289,0.076642,0.010238,-0.013077,0.062983,0.004675,-0.010213,0.047764,-0.003386,-0.012820,0.062152,0.003806,-0.012865,0.062581,0.014049,-0.013012,0.076436,0.019322,-0.013182,0.062983,0.016223,-0.010619,0.048814,0.015239,-0.013147,0.063175,0.022356,-0.012216,0.075725,0.026974,-0.012341,0.061404,0.023973,-0.011240,0.048016,0.023204,-0.013117,0.062318,0.029135,-0.008814,0.074618,0.033299,-0.005955,0.060280,0.031277,-0.008904,0.046365,0.030433,-0.010129,0.060655,0.037167,0.007727,0.060072,0.037182,0.000305,0.046210,0.033529,0.001403,0.073992,0.035602,0.000204,0.060157,0.035261,0.016868,0.073894,0.037088,0.024711,0.060879,0.039569,0.015886,0.046658,0.037545,0.016164,0.060150,0.034772,0.003204,0.028052,0.035320,-0.002939,0.035024,0.039436,0.007712,0.035228,0.037799,0.001415,0.035047,0.039900,0.025002,0.036234,0.034744,0.017186,0.027699,0.040130,0.016017,0.035589,0.027665,0.006641,0.092957,0.031410,0.010439,0.085122,0.029378,-0.002250,0.085270,0.030705,0.003476,0.085175,0.025176,-0.001709,0.093180,0.024645,-0.008542,0.085866,0.027412,-0.006169,0.085522,0.030575,-0.001118,0.028332,0.027949,-0.007058,0.035792,0.031885,-0.005473,0.035116,0.022199,-0.003991,0.029811,0.020765,-0.007584,0.037598,0.024283,-0.007674,0.036804,0.016602,-0.003971,0.030033,0.017850,0.001985,0.024672,0.007970,0.000802,0.024735,0.015980,-0.000871,0.026175,0.021797,0.009854,0.023849,0.026669,0.003544,0.025080,0.018918,-0.005282,0.093795,0.016864,-0.010457,0.086648,0.021025,-0.009839,0.086228,0.014870,0.009158,0.101164,0.019985,0.002916,0.097901,0.012797,0.001686,0.098903,0.016654,0.002009,0.098297,0.019964,0.010642,0.100206,0.023826,0.007274,0.097422,0.022373,0.004673,0.097616,0.007913,0.009150,0.102974,0.010433,-0.006032,0.095095,0.004879,0.001465,0.100664,0.008855,0.001590,0.099771,-0.003142,0.001040,0.101719,0.000452,0.008753,0.104787,0.001471,-0.006277,0.096360,0.000844,0.001207,0.101348,0.007635,-0.010831,0.087746,-0.003177,-0.011180,0.088344,0.002290,-0.010933,0.088121,0.012455,-0.010722,0.087202,0.011755,-0.007010,0.036621,0.016821,-0.007258,0.037337,0.004964,-0.003109,0.028126,-0.002281,-0.006751,0.035277,0.005249,-0.006828,0.035841,-0.001530,0.000962,0.023877,0.003728,0.000145,0.024656,0.004187,0.047007,0.030873,0.010033,0.048320,0.040082,0.004389,0.048419,0.053487,-0.001773,0.048902,0.039621,0.004639,0.048713,0.039888,0.005530,0.043290,0.025939,-0.001108,0.043399,0.025615,0.003016,0.044342,0.026448,-0.000613,0.026939,0.106400,-0.003831,0.029413,0.104260,0.000663,0.032177,0.101042,0.003397,0.029331,0.103932,-0.000093,0.029381,0.104154,0.006442,0.035871,0.095295,-0.003458,0.036122,0.096280,0.003022,0.041379,0.086648,0.001789,0.036001,0.095907,0.009437,0.045377,0.070729,-0.002644,0.046284,0.070643,0.003838,0.045905,0.070759,0.023368,0.021734,0.097309,0.020184,0.022973,0.099895,0.021294,0.026562,0.098536,0.025746,0.026949,0.094004,0.022453,0.024520,0.097808,0.017765,0.025598,0.101209,0.018093,0.028606,0.100305,0.022710,0.031008,0.096421,0.019850,0.027877,0.099398,0.021571,0.029594,0.024561,-0.001229,0.020268,0.022381,0.020310,0.019500,0.023812,0.010592,0.042904,0.026132,0.012283,0.046591,0.031218,0.009178,0.044059,0.026804,0.016949,0.047531,0.039873,0.014040,0.047442,0.053466,0.013954,0.048005,0.040090,0.016555,0.044487,0.070251,0.012304,0.040517,0.086054,0.013501,0.044870,0.070557,0.008014,0.032125,0.100338,0.013091,0.035661,0.094312,0.010119,0.035725,0.094773,0.005417,0.026969,0.105945,0.009191,0.029118,0.103236,0.006481,0.029245,0.103626,0.010209,0.026712,0.104883,0.013478,0.032068,0.099419,0.013923,0.028995,0.102005,0.011636,0.029025,0.102703,0.018338,0.032061,0.098241,0.014317,0.026461,0.103106,0.016086,0.028915,0.101189,0.023808,0.035598,0.092164,0.018382,0.035709,0.093590,0.023501,0.040296,0.083751,0.021074,0.035765,0.093101,0.017983,0.040119,0.085284,0.015772,0.035648,0.093968,0.027950,0.042997,0.067402,0.022059,0.044097,0.069244,0.025195,0.045732,0.051934,0.024918,0.043833,0.068467,0.019744,0.046658,0.052804,0.019320,0.044258,0.069823,0.022401,0.046343,0.039500,0.022472,0.044741,0.031091,0.028248,0.044626,0.038902,0.025020,0.045783,0.039113,0.018572,0.045644,0.031348,0.019742,0.046890,0.039612,0.017614,0.040176,0.025913,0.016718,0.043433,0.027209,0.036076,0.038573,0.038404,0.031816,0.042414,0.050768,0.030288,0.040399,0.030951,0.032281,0.042336,0.038772,0.034822,0.033431,0.029975,0.037676,0.032672,0.048443,0.038644,0.032809,0.037283,0.026113,0.036317,0.026614,0.033850,0.037520,0.064254,0.029570,0.038494,0.080417,0.031071,0.041065,0.065971,0.028468,0.032829,0.088728,0.026366,0.034786,0.090647,0.031007,0.024158,0.085568,0.033879,0.030900,0.076121,0.030013,0.029299,0.086889,0.021853,0.014187,0.099642,0.024505,0.014433,0.097196,0.024483,0.010616,0.097299,0.021551,0.018705,0.099468,0.027478,0.018119,0.092836,0.024070,0.018291,0.097129,0.031481,0.017653,0.085093,0.035862,0.032028,0.062412,0.086625,0.064615,-0.003487,0.086675,0.069386,-0.004915,0.086102,0.072782,-0.003878,0.086782,0.068439,-0.002753,0.086565,0.068807,-0.003930,0.087349,0.083329,-0.007541,0.087404,0.085461,-0.006095,0.086861,0.088856,-0.005320,0.086237,0.086837,-0.007463,0.087101,0.086265,-0.006721,0.087177,0.080471,-0.008200,0.085920,0.083360,-0.007887,0.086045,0.078847,-0.007004,0.086872,0.076863,-0.008132,0.086597,0.079932,-0.008016,0.086091,0.074151,-0.006093,0.084780,0.081329,-0.004919,0.085345,0.077075,-0.004487,0.085631,0.077832,-0.005802,0.084847,0.089051,-0.005251,0.084457,0.085507,-0.005502,0.085318,0.086476,-0.006979,0.087567,0.077034,-0.007939,0.088220,0.079264,-0.006799,0.087758,0.080064,-0.007669,0.088954,0.075226,-0.005693,0.089971,0.078533,-0.005795,0.088435,0.081755,-0.005859,0.088918,0.078675,-0.005947,0.091123,0.080219,-0.009737,0.090022,0.076595,-0.011256,0.087981,0.081369,-0.011633,0.089597,0.084611,-0.010279,0.089986,0.080890,-0.010928,0.090815,0.084821,-0.006238,0.091182,0.082813,-0.008123,0.090786,0.086556,-0.007999,0.090602,0.088083,-0.005657,0.091022,0.085583,-0.007057,0.090964,0.075236,-0.006654,0.090101,0.071187,-0.005697,0.090321,0.066642,-0.006608,0.091069,0.071331,-0.007925,0.090836,0.071232,-0.006946,0.091221,0.075840,-0.008766,0.090492,0.066531,-0.008542,0.090607,0.071649,-0.010208,0.091021,0.071481,-0.009006,0.091132,0.079094,-0.007538,0.090508,0.081724,-0.006355,0.090805,0.078750,-0.006552,0.091321,0.079597,-0.008574,0.087003,0.088514,-0.009590,0.089260,0.090386,-0.007422,0.089385,0.087705,-0.009080,0.090043,0.091721,-0.004728,0.086528,0.093957,-0.005494,0.088129,0.095549,-0.002590,0.088921,0.093059,-0.005476,0.089666,0.089525,-0.003172,0.089128,0.092671,-0.001532,0.090111,0.090492,-0.003945,0.082322,0.094495,0.003961,0.082467,0.093271,0.002115,0.083403,0.093009,-0.001181,0.083435,0.094758,0.001738,0.082907,0.094130,0.001657,0.085250,0.093052,-0.000740,0.084193,0.093386,0.003424,0.082914,0.094968,0.005520,0.084148,0.094347,0.002682,0.085715,0.091152,0.004008,0.083588,0.093175,0.006809,0.085642,0.090864,0.000525,0.084474,0.092179,0.003750,0.087469,0.086951,-0.003792,0.087728,0.088610,-0.001886,0.086444,0.090192,-0.002742,0.086763,0.089152,-0.002062,0.088092,0.090354,0.000066,0.087610,0.092946,0.002937,0.085449,0.092882,0.006759,0.087051,0.091702,0.003666,0.089767,0.086594,-0.003997,0.088871,0.088870,-0.002441,0.089298,0.084045,-0.004841,0.090261,0.084290,-0.005436,0.088024,0.084469,-0.005112,0.085131,0.091827,-0.004182,0.086235,0.091179,-0.003523,0.083208,0.090575,-0.002582,0.084031,0.091301,-0.003575,0.082680,0.090695,0.000441,0.083418,0.087870,-0.002197,0.082960,0.089881,-0.001561,0.083704,0.084052,-0.001679,0.083900,0.084675,-0.003595,0.084688,0.080033,-0.001700,0.085663,0.076262,-0.001537,0.085288,0.076501,-0.003073,0.083851,0.082535,0.001793,0.083135,0.085782,0.002383,0.084019,0.083153,0.000136,0.086318,0.076730,-0.012205,0.083624,0.080660,-0.010204,0.084827,0.085255,-0.010535,0.085710,0.081354,-0.011618,0.083840,0.066341,-0.009672,0.082329,0.071246,-0.007733,0.082739,0.075927,-0.009057,0.084646,0.071632,-0.011437,0.083302,0.071360,-0.009759,0.083191,0.056020,-0.005781,0.083314,0.061355,-0.007498,0.085071,0.060739,-0.008873,0.084059,0.060995,-0.008159,0.084524,0.053850,0.000473,0.082945,0.050874,0.003735,0.085035,0.053174,0.000356,0.086550,0.057473,-0.002550,0.084818,0.053662,0.000281,0.083345,0.096346,-0.001245,0.080334,0.096519,0.003844,0.081352,0.098673,0.005727,0.085178,0.098225,0.001075,0.082707,0.097844,0.002082,0.081284,0.094260,0.006314,0.080743,0.093949,0.009093,0.079782,0.092968,0.008845,0.081147,0.094438,0.007539,0.081118,0.093217,0.010046,0.078837,0.092311,0.012044,0.080432,0.092913,0.010327,0.083001,0.048843,0.004381,0.080653,0.047641,0.007591,0.078945,0.043576,0.010804,0.080897,0.044438,0.007782,0.080703,0.045991,0.007873,0.079317,0.051884,0.010833,0.080920,0.054302,0.010037,0.078032,0.054666,0.012706,0.077867,0.051412,0.013617,0.079045,0.053183,0.012090,0.076906,0.092577,0.007023,0.077546,0.095362,0.008207,0.078939,0.093340,0.003118,0.078423,0.094437,0.005621,0.076264,0.051172,0.016155,0.074817,0.047502,0.016470,0.076854,0.047644,0.013603,0.076508,0.049377,0.015014,0.075370,0.087218,0.020464,0.077088,0.088603,0.019037,0.077672,0.092843,0.018021,0.075564,0.091044,0.019508,0.076285,0.089897,0.019395,0.074771,0.089376,0.014632,0.077162,0.091396,0.012019,0.076059,0.090976,0.014145,0.074285,0.088642,0.015536,0.075285,0.090284,0.014049,0.073447,0.087464,0.015724,0.073284,0.086788,0.016446,0.072710,0.085467,0.016177,0.073280,0.087045,0.016137,0.071694,0.083012,0.017098,0.071636,0.083153,0.016796,0.072463,0.084802,0.016957,0.071856,0.083608,0.016981,0.070954,0.081848,0.016828,0.071606,0.082553,0.017293,0.071388,0.082446,0.017004,0.072275,0.054923,0.011849,0.073929,0.055426,0.010361,0.074114,0.055919,0.007687,0.071849,0.055443,0.009808,0.073162,0.055125,0.009840,0.076034,0.094290,0.017598,0.074605,0.093380,0.018100,0.074956,0.092132,0.019194,0.070739,0.054110,0.013566,0.070518,0.053865,0.014926,0.071748,0.055117,0.013978,0.071376,0.054614,0.013554,0.069368,0.067011,0.017880,0.067828,0.067550,0.017505,0.069377,0.068003,0.017695,0.069104,0.067744,0.017586,0.070644,0.071592,0.011814,0.069715,0.073408,0.013074,0.070738,0.073148,0.014018,0.071620,0.070627,0.012591,0.070617,0.072014,0.012845,0.071181,0.080634,0.014766,0.070608,0.080783,0.015595,0.070210,0.079685,0.014781,0.070958,0.079548,0.013380,0.070691,0.080166,0.014678,0.070975,0.081743,0.016301,0.070618,0.081278,0.016264,0.070733,0.081197,0.016100,0.070521,0.080861,0.016343,0.070627,0.081233,0.016477,0.069942,0.079800,0.015803,0.069502,0.078370,0.015290,0.069848,0.078202,0.013743,0.069814,0.079066,0.015001,0.070618,0.080709,0.016683,0.070116,0.079842,0.016398,0.070248,0.080366,0.016234,0.069838,0.078533,0.016332,0.069892,0.076241,0.015720,0.069235,0.076218,0.014413,0.069460,0.077494,0.015623,0.070736,0.080029,0.016904,0.070901,0.078639,0.016969,0.070298,0.079339,0.016700,0.074339,0.079238,0.016819,0.075331,0.080242,0.018141,0.074695,0.077957,0.018969,0.074602,0.076999,0.016999,0.074840,0.078558,0.017652,0.075565,0.082086,0.017504,0.076600,0.084653,0.018595,0.075471,0.082899,0.019838,0.075923,0.082264,0.018514,0.076019,0.095857,0.015509,0.078352,0.096343,0.015573,0.078343,0.098067,0.012649,0.077157,0.096387,0.015423,0.080191,0.094574,0.015701,0.081373,0.097837,0.012579,0.079432,0.095713,0.015696,0.078027,0.097506,0.010098,0.081696,0.099294,0.008951,0.079731,0.098810,0.009378,0.082571,0.095084,0.012752,0.084435,0.094316,0.009701,0.086672,0.095892,0.005913,0.084465,0.097750,0.009192,0.084810,0.096073,0.009526,0.087723,0.095913,0.001563,0.087761,0.094425,0.002195,0.085413,0.098766,0.004904,0.087145,0.097426,0.001146,0.083372,0.098863,0.008913,0.080236,0.091407,0.015100,0.078758,0.090136,0.017319,0.080473,0.093010,0.015490,0.071558,0.081637,0.017372,0.071938,0.080518,0.017353,0.071137,0.080754,0.017110,0.072616,0.083205,0.017599,0.071921,0.082406,0.017411,0.075512,0.083845,0.017100,0.075210,0.085091,0.016962,0.077733,0.087733,0.016118,0.077180,0.086308,0.017430,0.076371,0.085671,0.016955,0.073883,0.083120,0.017234,0.074101,0.085704,0.017165,0.073775,0.084291,0.017401,0.082697,0.092777,0.009753,0.079846,0.091606,0.012136,0.081911,0.092862,0.009813,0.081594,0.092106,0.012563,0.083610,0.093146,0.009742,0.077463,0.090210,0.014349,0.074990,0.088657,0.015867,0.076840,0.090732,0.014356,0.076010,0.087955,0.015987,0.073894,0.086627,0.016898,0.074527,0.086748,0.016843,0.073475,0.086697,0.016687,0.078641,0.089618,0.014416,0.077962,0.089793,0.014305,0.079511,0.090184,0.014656,0.077537,0.087272,0.018267,0.073748,0.081166,0.016953,0.074645,0.082413,0.016995,0.072670,0.078882,0.016707,0.073122,0.079968,0.016847,0.073637,0.073823,0.015472,0.073547,0.076715,0.015869,0.074325,0.074053,0.017232,0.074194,0.075429,0.016275,0.072565,0.070463,0.013671,0.072388,0.073601,0.014471,0.073114,0.070625,0.015151,0.073048,0.072195,0.014602,0.071771,0.076443,0.015848,0.072234,0.077771,0.016395,0.071152,0.074809,0.015108,0.072342,0.068044,0.010899,0.072306,0.067017,0.012042,0.072322,0.068926,0.012400,0.073908,0.058519,0.004945,0.075677,0.061383,0.002538,0.074824,0.064315,0.003449,0.072748,0.060267,0.006217,0.074207,0.060977,0.003900,0.076219,0.058659,0.003820,0.076165,0.057125,0.006675,0.074947,0.057234,0.005761,0.084901,0.056788,0.003195,0.082339,0.056426,0.008430,0.083171,0.054128,0.005187,0.083053,0.055115,0.006894,0.082225,0.050985,0.004777,0.079247,0.048220,0.009243,0.081115,0.049262,0.006711,0.085081,0.056500,0.000096,0.081060,0.051982,0.007580,0.083383,0.053244,0.002786,0.083135,0.053532,0.003876,0.078843,0.049818,0.010491,0.079691,0.051162,0.009837,0.077412,0.044464,0.012888,0.077830,0.047414,0.011642,0.085709,0.057172,-0.001629,0.083951,0.053502,0.001441,0.087574,0.072243,-0.006643,0.088526,0.066871,-0.005110,0.088704,0.071363,-0.005384,0.086693,0.071828,-0.006764,0.086943,0.074275,-0.007689,0.086956,0.066049,-0.005119,0.086705,0.070290,-0.005773,0.088632,0.061859,-0.004828,0.087228,0.061973,-0.004185,0.087883,0.061999,-0.004472,0.086512,0.060840,-0.003006,0.086801,0.061445,-0.003675,0.086149,0.060060,-0.000998,0.086203,0.060373,-0.002148,0.086053,0.060253,0.002891,0.086924,0.064009,-0.000517,0.086262,0.059952,0.000655,0.083031,0.058626,0.006723,0.079188,0.058191,0.008697,0.078294,0.056942,0.011004,0.080934,0.057744,0.008959,0.082685,0.061528,0.005340,0.085801,0.064522,0.003806,0.084905,0.060979,0.004943,0.076108,0.056352,0.009373,0.079244,0.059057,0.006081,0.077496,0.057626,0.007749,0.078760,0.061501,0.003088,0.080635,0.065223,0.003341,0.080540,0.061615,0.004440,0.070696,0.078268,0.011815,0.072045,0.078475,0.009824,0.072178,0.079380,0.011904,0.071362,0.078966,0.011733,0.075212,0.073871,0.004362,0.075837,0.069102,0.003049,0.077626,0.065230,0.001790,0.078679,0.069715,0.002858,0.077255,0.069676,0.002559,0.069686,0.076132,0.012510,0.070579,0.076335,0.010314,0.070137,0.077272,0.012099,0.070116,0.073633,0.011676,0.069521,0.074853,0.013002,0.071833,0.069884,0.009863,0.071206,0.073328,0.009603,0.070814,0.072022,0.010818,0.072887,0.072043,0.006277,0.072062,0.076395,0.007327,0.071529,0.074874,0.008355,0.075013,0.077599,0.007593,0.073530,0.077525,0.007087,0.071417,0.081848,0.016037,0.071898,0.083428,0.016565,0.071387,0.082510,0.016514,0.072272,0.080361,0.013751,0.072197,0.081777,0.015450,0.071708,0.081151,0.015080,0.072216,0.083307,0.016105,0.072534,0.084966,0.015750,0.072244,0.084275,0.016224,0.073435,0.083106,0.013993,0.073022,0.084250,0.014038,0.072668,0.084565,0.015023,0.072757,0.083180,0.015291,0.072876,0.083788,0.014688,0.075330,0.082082,0.012019,0.074154,0.083085,0.012630,0.074686,0.081461,0.013306,0.074416,0.082503,0.013133,0.073390,0.081590,0.014441,0.072548,0.082474,0.015564,0.074449,0.078662,0.010698,0.074163,0.079943,0.012813,0.073163,0.079523,0.012310,0.078238,0.073643,0.005374,0.077741,0.077329,0.009701,0.076278,0.077124,0.008493,0.076384,0.079847,0.012109,0.074793,0.080643,0.013241,0.082377,0.084799,0.005000,0.082062,0.082413,0.006218,0.084197,0.079598,0.002026,0.083028,0.082382,0.003827,0.084823,0.076491,0.002788,0.086538,0.072501,-0.000851,0.085583,0.076320,0.000305,0.086727,0.068474,0.001253,0.084682,0.073035,0.004471,0.082488,0.069106,0.004082,0.085596,0.068790,0.003773,0.086926,0.068335,-0.001022,0.081526,0.079927,0.007133,0.080518,0.077783,0.008133,0.083541,0.076818,0.005907,0.079049,0.084580,0.009154,0.077731,0.082571,0.009346,0.080019,0.082382,0.008211,0.075077,0.082675,0.011418,0.074922,0.083268,0.011181,0.073653,0.083891,0.012662,0.074327,0.083319,0.012050,0.073770,0.084846,0.012531,0.073204,0.085278,0.013705,0.073218,0.084549,0.013293,0.075324,0.084143,0.010685,0.076420,0.086492,0.011094,0.074231,0.086028,0.012803,0.074734,0.085312,0.011650,0.073352,0.086779,0.015265,0.075049,0.088974,0.014112,0.074063,0.088167,0.015098,0.073273,0.085979,0.014491,0.072855,0.085535,0.015119,0.074922,0.087645,0.013535,0.073694,0.086225,0.013759,0.081734,0.092807,0.005148,0.082102,0.089751,0.004291,0.082136,0.091957,0.003117,0.080369,0.092409,0.007847,0.081494,0.093729,0.005905,0.077977,0.090693,0.011126,0.078919,0.091839,0.009912,0.080787,0.087473,0.007963,0.082138,0.087212,0.005028,0.077916,0.089119,0.011481,0.076500,0.089541,0.012785,0.078701,0.087395,0.010576,0.076383,0.082140,0.010228,0.075959,0.082892,0.010108,0.077169,0.080693,0.010739,0.075983,0.081884,0.010918,0.078173,0.079052,0.010458,0.080195,0.069487,0.003528,0.077212,0.061406,0.002146,0.073469,0.066944,0.006315,0.074498,0.067984,0.004241,0.072578,0.064826,0.008787,0.072749,0.067192,0.008854,0.071079,0.067023,0.013853,0.070679,0.062092,0.009592,0.070947,0.064551,0.011057,0.069091,0.068947,0.017072,0.068970,0.068665,0.017355,0.067256,0.067915,0.016360,0.068470,0.068304,0.016394,0.068548,0.068633,0.016890,0.069659,0.068334,0.017570,0.069628,0.068822,0.017471,0.070125,0.068342,0.017694,0.069906,0.068553,0.017531,0.069498,0.068339,0.017480,0.069177,0.068776,0.016633,0.069753,0.068972,0.016964,0.069448,0.069004,0.017135,0.068294,0.066246,0.014880,0.069433,0.068225,0.015978,0.068829,0.068069,0.015999,0.068402,0.039792,0.025959,0.069940,0.040011,0.025599,0.070269,0.041986,0.025309,0.068381,0.042530,0.026174,0.069284,0.041014,0.025949,0.071284,0.040371,0.024802,0.072767,0.041576,0.023183,0.070883,0.044589,0.023198,0.071386,0.042157,0.024379,0.069418,0.038459,0.025320,0.071404,0.038008,0.024289,0.070642,0.039081,0.025056,0.070466,0.035977,0.023590,0.072471,0.035843,0.021995,0.073545,0.038378,0.022591,0.072108,0.036835,0.023225,0.075414,0.039288,0.019845,0.073341,0.043552,0.019292,0.074170,0.040687,0.021440,0.074242,0.049947,0.018110,0.071493,0.047264,0.019721,0.073036,0.047003,0.018066,0.069503,0.047316,0.023207,0.070057,0.049459,0.020825,0.070282,0.047203,0.021572,0.068898,0.049527,0.023423,0.068629,0.049475,0.024224,0.068617,0.046374,0.025259,0.068973,0.048109,0.024062,0.067172,0.046777,0.026251,0.066316,0.041991,0.026158,0.067664,0.044336,0.026293,0.061868,0.061952,0.012624,0.060493,0.064292,0.013037,0.059270,0.062822,0.013156,0.060284,0.060516,0.012094,0.060321,0.062465,0.012713,0.058619,0.061024,0.015479,0.058462,0.059723,0.014614,0.058388,0.060414,0.013973,0.058384,0.062224,0.014997,0.058263,0.060884,0.014692,0.061026,0.066709,0.013689,0.059838,0.065857,0.013523,0.062300,0.065375,0.013261,0.060781,0.065698,0.013272,0.064651,0.066291,0.014431,0.064051,0.063124,0.013151,0.066389,0.064458,0.014246,0.064347,0.064863,0.013683,0.062692,0.067208,0.014643,0.065151,0.067385,0.016140,0.064935,0.067138,0.015304,0.059966,0.066898,0.014257,0.061139,0.067375,0.015148,0.061108,0.067266,0.014380,0.059387,0.066044,0.014702,0.059033,0.064773,0.014081,0.059354,0.066026,0.014118,0.060054,0.066815,0.015618,0.059929,0.065920,0.015963,0.059000,0.065072,0.015232,0.059369,0.066081,0.015365,0.059148,0.063728,0.015902,0.058668,0.063494,0.014616,0.058564,0.063710,0.015282,0.058699,0.061409,0.013525,0.058780,0.063157,0.013966,0.064214,0.056270,0.015785,0.062935,0.057145,0.014082,0.060745,0.057421,0.013671,0.062345,0.056976,0.015333,0.062545,0.056828,0.014730,0.064197,0.056319,0.016629,0.060544,0.058188,0.015207,0.062901,0.057897,0.016499,0.062510,0.057288,0.015972,0.065738,0.055258,0.017260,0.065746,0.055599,0.015997,0.065168,0.055735,0.016567,0.066578,0.053926,0.017078,0.066564,0.055948,0.018404,0.066832,0.054165,0.018484,0.066354,0.054712,0.017896,0.069492,0.053082,0.015015,0.069907,0.054743,0.012583,0.068315,0.053559,0.014933,0.069615,0.053758,0.014054,0.070880,0.058025,0.009370,0.068752,0.057251,0.012223,0.070355,0.056168,0.010851,0.068846,0.061553,0.011955,0.071014,0.060027,0.008857,0.067546,0.060983,0.012980,0.067657,0.063292,0.013828,0.065783,0.060166,0.013392,0.063584,0.059354,0.013092,0.063837,0.061188,0.012940,0.066930,0.057042,0.014178,0.067320,0.058769,0.013208,0.067469,0.052814,0.016780,0.067035,0.054762,0.015518,0.067246,0.053594,0.016024,0.065062,0.057115,0.014559,0.066333,0.056000,0.015195,0.061534,0.058515,0.012383,0.063291,0.057985,0.013516,0.059205,0.059493,0.012234,0.059911,0.058155,0.012364,0.060198,0.059010,0.011912,0.058822,0.058795,0.012973,0.058673,0.059923,0.013082,0.059289,0.058365,0.013993,0.059466,0.057959,0.013205,0.059354,0.059733,0.015391,0.059224,0.058910,0.014803,0.059935,0.062171,0.016059,0.061167,0.060211,0.016138,0.059592,0.060856,0.015802,0.060741,0.064749,0.016161,0.062122,0.062931,0.016287,0.060346,0.063527,0.016173,0.068122,0.050904,0.024713,0.067679,0.054102,0.026334,0.066464,0.049088,0.026800,0.067261,0.050112,0.025762,0.072001,0.065719,0.020946,0.071768,0.064411,0.021783,0.071702,0.061857,0.021922,0.072199,0.063625,0.020914,0.072020,0.063853,0.021458,0.071439,0.065610,0.022124,0.071561,0.066450,0.021394,0.071624,0.065444,0.021801,0.071370,0.068664,0.021035,0.071813,0.070877,0.020523,0.071509,0.072804,0.022635,0.071086,0.069092,0.022428,0.071429,0.070480,0.021584,0.070449,0.069093,0.017556,0.070783,0.069014,0.016206,0.070105,0.068939,0.016687,0.072966,0.071097,0.016982,0.072118,0.069468,0.015726,0.073881,0.074807,0.019329,0.072483,0.071546,0.018980,0.073632,0.072776,0.018197,0.070717,0.066821,0.018069,0.071054,0.068190,0.018239,0.070580,0.068247,0.017901,0.071682,0.067622,0.019305,0.071807,0.066190,0.018817,0.071440,0.069288,0.018907,0.071382,0.067886,0.018772,0.072215,0.065839,0.019906,0.071556,0.068996,0.019735,0.071773,0.067500,0.020267,0.071803,0.067573,0.019759,0.071739,0.070334,0.019517,0.071659,0.067183,0.020835,0.071980,0.061275,0.020536,0.072114,0.063606,0.019684,0.072242,0.063544,0.020321,0.067562,0.055079,0.019610,0.067350,0.053497,0.019870,0.067175,0.052749,0.018423,0.067198,0.053696,0.019073,0.068065,0.065523,0.017722,0.070424,0.065392,0.018135,0.069550,0.063807,0.018129,0.069616,0.065631,0.018117,0.068296,0.059400,0.018391,0.068118,0.056901,0.019049,0.065571,0.057918,0.017816,0.067253,0.057529,0.018602,0.063991,0.060428,0.016789,0.063404,0.059016,0.016803,0.065112,0.063665,0.016710,0.067462,0.061918,0.017609,0.064601,0.061961,0.016671,0.061248,0.066485,0.016013,0.062808,0.065411,0.016171,0.061054,0.065739,0.016044,0.062930,0.066950,0.015875,0.061220,0.067049,0.015779,0.065425,0.066241,0.016765,0.065332,0.066956,0.016578,0.065394,0.065164,0.016768,0.069853,0.060983,0.018509,0.069087,0.061765,0.018262,0.070668,0.062511,0.018626,0.071538,0.064329,0.018536,0.071029,0.064869,0.018220,0.071505,0.061452,0.019369,0.071876,0.063857,0.019028,0.071709,0.058871,0.019691,0.070534,0.056826,0.019495,0.070915,0.059440,0.018826,0.071381,0.058996,0.019153,0.069789,0.057758,0.018704,0.070435,0.060130,0.018624,0.069083,0.055848,0.019735,0.068642,0.056285,0.019371,0.068664,0.052418,0.016722,0.069829,0.053154,0.016633,0.069638,0.052916,0.015861,0.068277,0.052107,0.018535,0.067822,0.052354,0.017532,0.070634,0.053480,0.017944,0.070908,0.054372,0.016258,0.069351,0.052624,0.018534,0.070103,0.053367,0.017395,0.070632,0.052252,0.019350,0.068984,0.051952,0.020074,0.068881,0.050877,0.021869,0.069506,0.051252,0.020463,0.072014,0.054913,0.016340,0.073317,0.055851,0.013003,0.071983,0.055407,0.014832,0.075667,0.054778,0.014699,0.073105,0.053241,0.017666,0.074916,0.052471,0.017002,0.075559,0.055933,0.011983,0.076750,0.055711,0.012602,0.074673,0.055750,0.011145,0.071558,0.053444,0.017954,0.067843,0.052305,0.020306,0.068691,0.052027,0.019440,0.068902,0.051489,0.023531,0.068533,0.053693,0.024383,0.068605,0.051384,0.024052,0.069435,0.052876,0.022489,0.069012,0.051160,0.022974,0.069507,0.055356,0.023231,0.070503,0.058850,0.022737,0.070560,0.062323,0.023672,0.068807,0.056966,0.024755,0.069450,0.057765,0.023838,0.071260,0.057074,0.020585,0.070843,0.056981,0.021608,0.070207,0.055000,0.021784,0.070304,0.055439,0.020657,0.070781,0.055851,0.021223,0.068811,0.053544,0.021470,0.069776,0.054113,0.022158,0.068494,0.054581,0.020657,0.067635,0.053456,0.020799,0.069629,0.055541,0.020106,0.071726,0.059316,0.021041,0.071858,0.059037,0.020332,0.071312,0.059324,0.021811,0.070655,0.066577,0.024363,0.071064,0.066278,0.022930,0.069250,0.060687,0.025906,0.070095,0.070818,0.025837,0.068994,0.063068,0.026849,0.069889,0.065553,0.025820,0.068344,0.057157,0.026330,0.068561,0.056673,0.025586,0.068234,0.060916,0.028122,0.068194,0.058723,0.027067,0.064240,0.042677,0.026220,0.067085,0.054704,0.029166,0.065307,0.046263,0.029516,0.065852,0.047925,0.027993,0.061192,0.076850,0.067393,0.057554,0.074621,0.075368,0.058032,0.062821,0.074221,0.061375,0.061323,0.063574,0.059759,0.068844,0.070239,0.039021,0.010701,0.098459,0.040753,0.000187,0.090979,0.045004,0.005307,0.087569,0.041695,0.017917,0.097101,0.041783,0.008341,0.093981,0.027349,0.029635,0.108343,0.027196,0.024255,0.108591,0.030807,0.020044,0.106392,0.031742,0.025212,0.105997,0.029367,0.024745,0.107406,0.053318,0.007818,0.041040,0.046814,-0.004023,0.040949,0.049691,-0.005033,0.027666,0.055457,0.009986,0.028981,0.051024,0.003244,0.033982,0.043318,-0.007220,0.078651,0.048639,-0.001248,0.069732,0.050326,0.014252,0.081728,0.047739,0.002075,0.079155,0.059989,0.021735,0.043355,0.058670,0.021491,0.058752,0.052009,0.004307,0.055637,0.056365,0.012681,0.049100,0.061211,0.042661,0.060968,0.057192,0.047764,0.074339,0.054783,0.029484,0.076166,0.058341,0.034739,0.067658,0.053652,0.066519,0.082362,0.051923,0.055426,0.084276,0.055364,0.058366,0.079023,0.047295,0.063730,0.089888,0.043211,0.054881,0.094281,0.048509,0.041902,0.088461,0.047730,0.054101,0.089546,0.045215,0.028443,0.093586,0.050254,0.028261,0.085593,0.041836,-0.013868,0.066107,0.044754,-0.008593,0.054155,0.047461,-0.004954,0.061181,0.035667,-0.022792,0.055817,0.038499,-0.020860,0.040959,0.041652,-0.013310,0.048018,0.023120,0.032843,0.110453,0.026833,0.036469,0.107841,0.021715,0.039715,0.109180,0.024827,0.034673,0.109106,0.017356,0.021006,0.103914,0.016697,0.021966,0.105882,0.017050,0.021817,0.104453,0.018483,0.020547,0.102275,0.017364,0.021462,0.103985,0.016226,0.021872,0.106087,0.018469,0.018948,0.102376,0.016359,0.020435,0.104751,0.017055,0.020644,0.104161,0.016591,0.047777,0.108204,0.016616,0.043062,0.109916,0.021036,0.046168,0.107903,0.018927,0.044168,0.108714,0.012170,0.055636,0.112155,0.012299,0.053636,0.114041,0.011822,0.051729,0.113020,0.012036,0.053403,0.111013,0.012219,0.053538,0.112331,0.011617,0.051298,0.111621,0.010488,0.049426,0.115946,0.010821,0.049461,0.113239,0.011270,0.050353,0.113393,0.009297,0.047894,0.114622,0.007035,0.047365,0.117909,0.005356,0.047239,0.118139,0.007298,0.046783,0.115717,0.007285,0.047035,0.116674,0.005995,0.052070,0.118509,0.005585,0.051044,0.119194,0.007134,0.049267,0.119896,0.006430,0.050916,0.120525,0.006012,0.050793,0.119844,0.007732,0.048090,0.118622,0.005312,0.049747,0.119447,0.004788,0.048904,0.119497,0.006212,0.048048,0.119151,0.009871,0.050055,0.118868,0.008982,0.048867,0.118455,0.004751,0.051996,0.117297,0.003896,0.051311,0.118158,0.004891,0.051134,0.118454,0.001726,0.081551,0.113971,0.003685,0.081396,0.108890,0.001936,0.086859,0.108266,0.000240,0.087415,0.114358,0.001834,0.084456,0.111448,-0.000090,0.043070,0.121512,-0.002061,0.041292,0.122187,-0.000369,0.039731,0.122233,0.001812,0.041494,0.120866,-0.000176,0.041528,0.121878,0.000758,0.053124,0.129146,-0.000539,0.052917,0.128045,-0.000120,0.053310,0.127399,0.002113,0.053673,0.128070,0.000622,0.053409,0.128335,0.001249,0.051024,0.121037,0.001819,0.051814,0.119405,0.000776,0.053078,0.119797,0.000692,0.052405,0.121900,0.001179,0.052148,0.120561,0.003104,0.050575,0.119299,0.002454,0.052293,0.117598,0.002758,0.051536,0.118481,0.006129,0.052495,0.120066,0.008531,0.050570,0.121074,0.006816,0.051445,0.122058,0.006767,0.051099,0.121153,0.010030,0.052416,0.121404,0.011606,0.052675,0.117804,0.010247,0.051234,0.119899,0.007982,0.052481,0.123681,0.009776,0.055595,0.122167,0.007394,0.054666,0.125823,0.009050,0.053675,0.123312,0.005357,0.053152,0.122628,0.005360,0.052836,0.125209,0.006428,0.052026,0.123443,-0.003734,0.042603,0.121716,-0.006018,0.040672,0.121166,-0.004170,0.039031,0.121732,-0.003952,0.040892,0.121700,-0.005120,0.047051,0.123006,-0.003272,0.046494,0.122660,-0.001353,0.047464,0.122181,-0.003156,0.047612,0.123193,-0.003178,0.047039,0.122880,-0.001883,0.048981,0.123287,-0.003347,0.048683,0.124446,-0.004952,0.047892,0.124011,-0.003264,0.048142,0.123723,0.006147,0.023546,0.112299,0.003478,0.023633,0.115280,0.001159,0.023664,0.113683,0.004283,0.023751,0.110688,0.003930,0.023657,0.113032,-0.002132,0.023510,0.116662,-0.004715,0.023629,0.114308,-0.001368,0.023669,0.111563,-0.001821,0.023570,0.114198,0.000217,0.024590,0.118491,-0.002719,0.025916,0.120947,-0.005173,0.024430,0.118746,-0.002385,0.024426,0.118851,0.005383,0.024296,0.116583,0.002163,0.026254,0.119889,0.002946,0.024609,0.117581,0.012774,0.038124,0.114782,0.016095,0.033092,0.114563,0.019271,0.033874,0.112607,0.015461,0.039855,0.112439,0.016112,0.036343,0.113598,0.012328,0.045607,0.110739,0.010921,0.043356,0.112789,0.013908,0.043057,0.111311,0.006543,0.040500,0.117906,0.009841,0.036769,0.117274,0.008888,0.041817,0.115286,0.009495,0.039452,0.116223,0.007448,0.045380,0.114487,0.005626,0.044113,0.116600,0.008089,0.043755,0.114639,0.005067,0.046503,0.116565,0.009127,0.046824,0.112713,0.007097,0.046570,0.114773,0.001677,0.044404,0.120007,0.000006,0.045414,0.121168,-0.001785,0.044198,0.122018,-0.000035,0.044362,0.121324,0.000169,0.047120,0.121026,-0.001572,0.046037,0.122057,0.001605,0.046499,0.119672,0.000070,0.046313,0.121078,0.003528,0.048519,0.119538,0.001780,0.048103,0.119940,0.003328,0.047370,0.118533,0.003496,0.047909,0.119101,0.002099,0.049745,0.120268,0.003411,0.049436,0.119726,-0.000057,0.049991,0.122143,0.000579,0.048851,0.121130,0.000958,0.049879,0.121156,0.000321,0.047942,0.121070,0.003340,0.045484,0.118159,0.003262,0.046535,0.118193,0.003784,0.042893,0.118849,0.003533,0.044298,0.118395,0.004041,0.039157,0.120243,0.003944,0.041162,0.119416,-0.006215,0.036928,0.121426,-0.004293,0.035071,0.122383,-0.002454,0.037459,0.122457,-0.004314,0.037027,0.121795,-0.000634,0.035676,0.123017,0.001517,0.037598,0.122036,-0.000603,0.037744,0.122556,-0.006140,0.032868,0.123724,-0.003762,0.030366,0.124343,-0.002118,0.033342,0.123735,-0.004069,0.032961,0.123670,0.000151,0.031048,0.123569,0.001580,0.033281,0.122795,-0.000350,0.033547,0.123670,0.007132,0.030961,0.119808,0.003819,0.034665,0.121242,0.004878,0.029960,0.121085,0.004104,0.032414,0.121449,0.006720,0.035694,0.119413,0.003919,0.036947,0.120894,0.010189,0.031425,0.118441,0.013108,0.032131,0.116509,0.010072,0.033996,0.118105,0.015104,0.027987,0.115013,0.017752,0.028263,0.113850,0.015697,0.030281,0.115079,0.019637,0.022237,0.110855,0.021855,0.021017,0.109677,0.023236,0.023039,0.110243,0.020575,0.024182,0.111668,0.021437,0.022542,0.110603,0.026105,0.020667,0.108561,0.023799,0.026932,0.110713,0.025150,0.023655,0.109549,0.020718,0.028157,0.112558,0.021909,0.030521,0.111761,0.018120,0.024591,0.112652,0.019404,0.026102,0.112862,0.017754,0.022752,0.111512,0.017355,0.022134,0.110295,0.018434,0.021670,0.110094,0.018213,0.022205,0.110809,0.016338,0.022738,0.111717,0.016128,0.024705,0.113390,0.017061,0.023525,0.112289,0.016212,0.022187,0.107892,0.015612,0.022191,0.109767,0.014922,0.022295,0.109331,0.015969,0.022096,0.106811,0.015683,0.022187,0.108429,0.016358,0.022381,0.107553,0.016444,0.022355,0.108946,0.016403,0.022383,0.107584,0.016423,0.022175,0.110040,0.016823,0.022013,0.109561,0.016757,0.022147,0.109720,0.015084,0.022646,0.111832,0.015846,0.022322,0.110791,0.011029,0.023408,0.114365,0.012669,0.023948,0.114369,0.010482,0.027034,0.117783,0.008434,0.026295,0.118104,0.010734,0.024929,0.116399,0.009812,0.023311,0.110538,0.007730,0.023285,0.113440,0.008402,0.023673,0.109406,0.008043,0.023403,0.111497,0.009317,0.023241,0.114222,0.006834,0.025269,0.117594,0.007367,0.023891,0.115396,0.011940,0.023586,0.107273,0.013005,0.022970,0.108120,0.011270,0.023108,0.111340,0.011460,0.023153,0.109414,0.015604,0.022423,0.105790,0.017386,0.022205,0.103147,0.016524,0.022098,0.104991,0.014028,0.022577,0.108786,0.015137,0.023163,0.104820,0.014415,0.022746,0.106860,0.012635,0.022725,0.111769,0.011131,0.023016,0.112986,0.013918,0.022565,0.111847,0.013884,0.022478,0.110517,0.014421,0.024460,0.114188,0.014073,0.023141,0.112948,0.012691,0.027623,0.116413,0.014703,0.026113,0.114810,0.010242,0.029232,0.118246,0.003320,0.028313,0.120944,0.005901,0.027575,0.119512,-0.001158,0.028533,0.122557,0.000983,0.028606,0.121965,-0.005732,0.027864,0.123166,-0.003391,0.028141,0.122876,0.034028,0.014071,0.103791,0.036094,0.006502,0.099729,0.035849,0.019129,0.103039,0.036458,0.012543,0.101501,0.028964,0.016743,0.106624,0.031227,0.011141,0.104428,0.031492,0.015472,0.105351,0.007548,-0.027204,0.103227,0.015710,-0.022659,0.106312,0.009038,-0.020021,0.114879,0.000113,-0.025444,0.111195,0.008594,-0.024754,0.109749,-0.001059,-0.029997,0.098463,0.004375,-0.032314,0.092625,0.012841,-0.027946,0.095265,0.006297,-0.029305,0.097377,0.019888,-0.023392,0.097298,0.025510,-0.017206,0.097876,0.021304,-0.015969,0.106156,0.021102,-0.020205,0.102231,0.015607,-0.029829,0.087942,0.022985,-0.023998,0.088926,0.018182,-0.026175,0.092336,0.038706,-0.009661,0.084870,0.033083,-0.017944,0.082313,0.037106,-0.017129,0.075140,0.038186,-0.013553,0.079904,0.036857,-0.001937,0.094708,0.035294,-0.009812,0.090869,0.038469,-0.005596,0.089922,0.025937,-0.025220,0.081592,0.029580,-0.017485,0.089525,0.028052,-0.021350,0.085486,0.029865,-0.010032,0.097930,0.030360,-0.013640,0.093734,0.032275,0.004503,0.101700,0.032124,-0.002792,0.099227,0.034661,0.001402,0.098758,0.027649,0.009916,0.105466,0.027979,0.003805,0.104319,0.029967,0.007271,0.103858,0.023619,0.004129,0.107378,0.021849,-0.001558,0.107828,0.026863,-0.002636,0.103801,0.025220,0.000822,0.105740,0.017340,0.021423,0.109816,0.017899,0.020407,0.109850,0.019679,0.020235,0.109537,0.018293,0.021014,0.109773,0.024079,0.018829,0.108431,0.026173,0.015175,0.106954,0.026465,0.017888,0.107603,0.021101,0.018168,0.108571,0.021710,0.019520,0.109012,0.022877,0.014924,0.107842,0.023822,0.010000,0.107456,0.025247,0.012540,0.106825,0.018385,0.018596,0.109454,0.019247,0.015465,0.109730,0.020190,0.016844,0.108752,0.016214,0.020928,0.110353,0.016399,0.019288,0.110586,0.017266,0.019870,0.109974,0.013219,0.022708,0.110625,0.011427,0.022805,0.110338,0.009092,0.023077,0.113091,0.012021,0.022396,0.112343,0.011534,0.022776,0.111855,0.016139,0.022378,0.109108,0.015979,0.021850,0.109998,0.016542,0.021897,0.109622,0.015299,0.022444,0.108417,0.016000,0.022409,0.107829,0.014634,0.022410,0.110404,0.014353,0.021802,0.111312,0.015278,0.021850,0.110553,0.014395,0.022107,0.107580,0.014386,0.022571,0.109363,0.010876,0.021613,0.113853,0.013973,0.020130,0.112197,0.012971,0.021649,0.112318,0.013069,0.018021,0.114306,0.016370,0.016599,0.111751,0.015120,0.018689,0.112110,0.015832,0.012273,0.112928,0.019816,0.010892,0.109954,0.017919,0.013928,0.111002,0.019043,0.005407,0.110422,0.021760,0.007533,0.108767,0.014236,0.007313,0.113237,0.011130,0.002763,0.113650,0.016858,0.000322,0.111120,0.015615,0.003829,0.112027,0.013292,-0.004354,0.113539,0.019374,-0.007185,0.109788,0.018133,-0.003290,0.110519,0.024555,-0.009221,0.104611,0.028472,-0.006313,0.101263,0.015686,-0.013119,0.113086,0.020538,-0.011449,0.108530,0.008203,-0.008831,0.118057,0.000484,-0.014710,0.119764,0.008863,-0.014233,0.117487,-0.004513,0.049445,0.128080,-0.003211,0.049711,0.126595,-0.002061,0.051052,0.127659,-0.003015,0.050458,0.129298,-0.003113,0.050120,0.127911,-0.002299,0.050079,0.125131,-0.004680,0.048738,0.125694,-0.003327,0.049227,0.125406,-0.000052,0.051384,0.123229,-0.001296,0.050565,0.124073,-0.000812,0.050165,0.123103,-0.000387,0.052468,0.124898,-0.000020,0.053533,0.123347,0.000165,0.052452,0.123409,-0.000987,0.052020,0.125691,-0.000424,0.053691,0.126365,-0.000592,0.052779,0.126230,-0.001571,0.051658,0.126467,-0.001541,0.051086,0.125211,-0.000819,0.052332,0.128837,-0.001327,0.052104,0.127696,0.002715,0.054223,0.126157,0.004711,0.053832,0.127729,0.003780,0.053483,0.126952,0.003512,0.054609,0.130012,0.005564,0.056052,0.129120,0.005405,0.054826,0.128311,0.000884,0.053423,0.130622,0.003085,0.055529,0.131492,0.000211,0.053703,0.132448,0.001909,0.054313,0.131282,-0.001287,0.051827,0.130341,-0.000046,0.052699,0.129822,-0.002501,0.051459,0.132139,-0.004628,0.050032,0.130892,-0.002834,0.050826,0.130684,-0.001269,0.054942,0.134916,-0.004772,0.052135,0.134553,-0.001985,0.052780,0.133600,0.002842,0.057476,0.133149,0.000023,0.061463,0.135157,-0.004654,0.058166,0.137289,-0.000471,0.057908,0.135807,0.005933,0.058847,0.129022,0.004626,0.057005,0.130800,0.003917,0.062676,0.130031,0.008179,0.059300,0.123441,0.005854,0.062966,0.124668,0.006411,0.060975,0.126811,0.001714,0.070963,0.124141,-0.001958,0.074301,0.125604,-0.005206,0.073106,0.128301,-0.001030,0.070776,0.128238,-0.001532,0.072455,0.126906,-0.004800,0.069635,0.130962,-0.000010,0.066995,0.131374,0.002932,0.067161,0.126676,-0.000485,0.069055,0.129703,-0.004475,0.065163,0.134647,0.000153,0.064501,0.133284,0.005943,0.023181,0.112635,0.008722,0.021183,0.108775,0.006532,0.017735,0.108150,0.002706,0.021485,0.110491,0.005847,0.021404,0.109705,0.002730,0.023767,0.115754,-0.000851,0.023179,0.114101,-0.004236,0.023579,0.116935,-0.000571,0.023172,0.118237,-0.000889,0.023664,0.116595,0.004370,0.021870,0.117782,-0.003942,0.021637,0.119701,0.001218,0.019746,0.120766,0.000211,0.021796,0.119498,0.006715,0.022897,0.115395,0.009119,0.019698,0.116285,0.007939,0.021733,0.115718,0.006104,0.023522,0.114503,-0.000275,0.018037,0.109133,-0.003920,0.021208,0.111597,-0.000655,0.021372,0.111193,0.016604,0.018025,0.103620,0.013373,0.020725,0.106270,0.015194,0.020396,0.105576,0.012380,0.017651,0.105786,0.011197,0.021059,0.107476,0.006239,-0.001249,0.116238,-0.000108,-0.004918,0.119607,0.007260,-0.004613,0.117372,0.004738,0.005389,0.115842,-0.000831,0.001538,0.116875,0.005387,0.002028,0.115469,0.009149,0.009526,0.116231,0.011711,0.014207,0.116088,0.012923,0.010785,0.114680,0.007112,0.016998,0.119111,0.010410,0.017368,0.116822,-0.003006,0.015941,0.121482,0.003262,0.012402,0.119190,0.002419,0.016350,0.121158,-0.001767,0.008468,0.117140,0.004052,0.008675,0.117305,-0.003492,0.045088,0.122250,-0.005594,0.044001,0.121456,-0.003605,0.044013,0.121962,-0.005300,0.045997,0.122304,-0.003384,0.045878,0.122464,0.061721,0.159529,0.049512,0.054570,0.157782,0.065050,0.058233,0.143722,0.066728,0.060283,0.151598,0.057914,0.047958,-0.018036,-0.036306,0.049563,-0.011994,-0.031043,0.053016,-0.024255,-0.024549,0.052096,-0.031638,-0.030503,0.050597,-0.021215,-0.030538,0.055363,0.180703,0.035008,0.050682,0.186407,0.032050,0.043904,0.186693,0.045656,0.049680,0.179722,0.049337,0.049731,0.183722,0.041388,0.038227,0.198035,-0.019355,0.034375,0.202219,-0.002719,0.041470,0.197153,0.008141,0.048205,0.192597,-0.010394,0.040986,0.197931,-0.006412,0.057888,0.182868,0.020648,0.055145,0.186889,0.004935,0.047059,0.191619,0.021158,0.052931,0.187311,0.019889,0.063590,0.178305,-0.009785,0.055924,0.183898,-0.028438,0.056101,0.186033,-0.011351,0.039083,0.193130,0.037347,0.033625,0.199235,0.025369,0.040551,0.195551,0.023194,0.025140,0.198931,0.041683,0.026525,0.205009,0.012725,0.017101,0.205208,0.028880,0.025986,0.202431,0.027251,0.006497,0.203361,0.044599,0.007007,0.209758,0.014224,-0.004858,0.207771,0.030921,0.006608,0.207183,0.030215,-0.005335,0.188610,0.078809,0.005402,0.182048,0.086288,0.015338,0.186788,0.076331,0.005817,0.193739,0.069033,0.005544,0.188048,0.078132,0.016072,0.197160,0.056481,-0.004877,0.199652,0.058225,0.006191,0.199022,0.057905,0.060763,0.028399,0.005446,0.061463,0.034991,0.013692,0.060485,0.029610,0.018869,0.059167,0.021060,0.012494,0.060144,0.028769,0.012705,0.062491,0.036232,0.023579,0.062963,0.035801,0.028053,0.060464,0.025040,0.024705,0.061457,0.031503,0.023719,0.060292,0.022739,0.032278,0.058266,0.014256,0.019909,0.058900,0.017557,0.026318,0.058178,-0.022064,-0.005109,0.057802,-0.007253,-0.011703,0.059600,0.002061,-0.003705,0.058160,-0.011123,0.003031,0.058928,-0.009337,-0.004466,0.055235,-0.015968,-0.018597,0.051847,-0.003507,-0.026036,0.056157,0.004857,-0.019331,0.055557,-0.005121,-0.018930,0.052263,0.015159,-0.028595,0.058600,0.022293,-0.020415,0.059899,0.012706,-0.011292,0.057230,0.013979,-0.019858,0.061465,0.020262,-0.002771,0.059317,0.011713,0.004610,0.060579,0.011798,-0.003171,0.055317,-0.028333,0.009416,0.056852,0.001822,0.011967,0.052263,-0.014714,0.017718,0.055654,-0.012521,0.010592,0.058229,0.012530,0.012436,0.062223,0.028669,-0.011070,0.064077,0.035491,-0.001406,0.062362,0.028025,-0.002359,0.056308,0.031353,-0.031317,0.062108,0.037719,-0.022056,0.060104,0.030050,-0.020929,0.079324,0.055239,-0.004736,0.077122,0.051815,-0.002633,0.074886,0.052867,-0.003086,0.077852,0.058276,-0.005797,0.077302,0.054507,-0.004482,0.074402,0.045653,0.004263,0.073120,0.045627,0.004112,0.073949,0.048293,0.000849,0.075714,0.048228,0.001011,0.074340,0.046779,0.002600,0.079228,0.052162,-0.002698,0.077633,0.048512,0.001041,0.077313,0.049951,-0.000799,0.081465,0.058672,-0.005388,0.081259,0.054491,-0.003457,0.080581,0.055116,-0.004196,0.079257,0.050302,0.000001,0.082227,0.057519,-0.004988,0.081113,0.052863,-0.002537,0.081240,0.053674,-0.002906,0.075591,0.045643,0.004847,0.077109,0.046251,0.003988,0.077405,0.047403,0.002802,0.068339,0.042302,0.013733,0.068290,0.042573,0.012477,0.069463,0.043128,0.010477,0.070078,0.043136,0.011528,0.069036,0.042890,0.012229,0.072385,0.042947,0.010226,0.070331,0.042311,0.012706,0.072806,0.044069,0.008458,0.071328,0.043191,0.010794,0.071702,0.044775,0.004980,0.070058,0.043103,0.007037,0.069430,0.043413,0.003177,0.072551,0.046720,0.001444,0.071367,0.044525,0.004382,0.065678,0.040180,0.006899,0.067702,0.044302,-0.003725,0.066370,0.041433,0.001091,0.070886,0.043639,0.007684,0.068438,0.042395,0.010193,0.069593,0.043047,0.008884,0.066999,0.041373,0.013783,0.066519,0.040540,0.011169,0.067472,0.041778,0.012057,0.068237,0.041163,0.014753,0.066166,0.039779,0.015871,0.067302,0.041243,0.014760,0.071092,0.041283,0.012488,0.068938,0.039438,0.014881,0.069560,0.041112,0.013939,0.079257,0.047996,0.001029,0.082329,0.050737,-0.003055,0.081383,0.051884,-0.002657,0.075552,0.039951,0.008054,0.077732,0.043550,0.004634,0.080992,0.045384,0.001008,0.079035,0.041715,0.005504,0.078277,0.042406,0.004957,0.075074,0.043175,0.007531,0.077335,0.044851,0.004380,0.085353,0.055092,-0.006275,0.084524,0.049753,-0.002522,0.083480,0.049964,-0.003040,0.086524,0.066397,-0.011439,0.087701,0.060580,-0.009133,0.086405,0.060594,-0.009314,0.088214,0.071840,-0.012088,0.086390,0.071810,-0.012195,0.089361,0.066391,-0.010728,0.089651,0.071787,-0.011290,0.089225,0.060988,-0.007461,0.087261,0.055278,-0.005199,0.088642,0.060754,-0.008382,0.083366,0.046703,0.003831,0.078980,0.039908,0.010423,0.080498,0.042281,0.006975,0.080832,0.043217,0.007477,0.089425,0.061450,-0.005882,0.087858,0.056071,-0.003788,0.089510,0.061239,-0.006558,0.087499,0.056861,-0.002972,0.089141,0.061652,-0.005347,0.085559,0.051987,0.000254,0.085309,0.052601,0.000393,0.085640,0.050640,-0.000780,0.085704,0.051326,-0.000117,0.082780,0.045101,0.002325,0.085252,0.050040,-0.001675,0.077226,0.038048,0.009036,0.079833,0.041709,0.006244,0.070169,0.034765,0.021827,0.072265,0.034404,0.019358,0.074071,0.035866,0.019913,0.072262,0.034962,0.020778,0.070626,0.037429,0.013850,0.068197,0.035688,0.016303,0.066459,0.037829,0.016898,0.068401,0.037489,0.015667,0.066460,0.038961,0.025297,0.064071,0.039888,0.024127,0.064625,0.037765,0.022856,0.065150,0.039551,0.024819,0.067981,0.036897,0.024400,0.066790,0.035715,0.022239,0.068674,0.035590,0.023175,0.067921,0.038346,0.025344,0.077892,0.038984,0.013484,0.076702,0.039494,0.016270,0.077784,0.041519,0.013546,0.074926,0.035724,0.017800,0.075597,0.037367,0.018543,0.075248,0.035363,0.015511,0.075976,0.035776,0.012666,0.077275,0.037029,0.013156,0.071012,0.033970,0.017334,0.073401,0.034538,0.017546,0.071634,0.034553,0.014762,0.066729,0.035096,0.018892,0.068908,0.034432,0.016822,0.073461,0.036348,0.011857,0.074483,0.035618,0.012211,0.072878,0.040315,0.010707,0.073122,0.038255,0.011322,0.072779,0.041919,0.010283,0.072654,0.044407,0.006572,0.073960,0.044840,0.006180,0.072087,0.044473,0.005906,0.072512,0.050593,-0.003588,0.073636,0.049898,-0.000912,0.071078,0.056849,-0.009556,0.066609,0.047172,-0.014562,0.069356,0.050024,-0.006905,0.061776,0.046209,-0.035369,0.067099,0.055014,-0.027380,0.064596,0.046285,-0.024558,0.067562,0.063831,-0.040560,0.059919,0.053207,-0.048707,0.056277,0.061051,-0.062997,0.066526,0.075801,-0.055874,0.063183,0.062767,-0.052100,0.075878,0.080755,-0.000145,0.076825,0.076240,-0.003880,0.075690,0.079247,-0.005271,0.074603,0.083777,0.000601,0.075680,0.079833,-0.001919,0.079899,0.063269,-0.006249,0.076079,0.063709,-0.007107,0.078050,0.069332,-0.005803,0.078235,0.063481,-0.006704,0.071086,0.063757,-0.019522,0.074340,0.071526,-0.012095,0.073039,0.063874,-0.011141,0.072403,0.073863,-0.030754,0.069672,0.063947,-0.029595,0.074428,0.081017,-0.019948,0.074395,0.090463,-0.043981,0.077132,0.096682,-0.026540,0.074846,0.085280,-0.030312,0.075283,0.087183,-0.008436,0.074883,0.079444,-0.011564,0.079426,0.075126,-0.004286,0.077932,0.076298,-0.003894,0.077317,0.079598,-0.001565,0.079087,0.078168,-0.003175,0.078367,0.077479,-0.003286,0.082292,0.066700,-0.007056,0.081029,0.071528,-0.005253,0.080672,0.075521,-0.005450,0.081601,0.071330,-0.006342,0.082182,0.062518,-0.005873,0.082703,0.061873,-0.006694,0.080904,0.067668,-0.005748,0.081451,0.063010,-0.005919,0.079030,0.072419,-0.005181,0.080206,0.071837,-0.005022,0.077843,0.073839,-0.004892,0.073974,0.085696,0.004019,0.074368,0.087400,0.006417,0.075586,0.086665,0.004777,0.075383,0.083919,0.002918,0.074802,0.085805,0.004789,0.080640,0.079251,-0.005517,0.081061,0.083124,-0.005841,0.082010,0.079801,-0.007594,0.078931,0.081342,-0.001960,0.079851,0.078724,-0.003867,0.079540,0.089257,-0.001735,0.077695,0.089539,0.002724,0.080990,0.093425,-0.002050,0.079126,0.091626,0.000626,0.084090,0.091391,-0.006715,0.083692,0.094171,-0.004327,0.082071,0.087445,-0.006515,0.084367,0.088473,-0.008879,0.078784,0.085045,-0.001555,0.080138,0.086278,-0.003848,0.077006,0.086089,0.002085,0.076134,0.089667,0.006068,0.076504,0.087905,0.004057,0.076887,0.082814,0.000832,0.077736,0.083916,0.000032,0.076283,0.081826,0.000752,0.073971,0.088261,0.005725,0.074297,0.088219,0.002857,0.073999,0.086421,0.003322,0.075126,0.091166,0.000558,0.074528,0.091771,0.005273,0.074838,0.090143,0.003035,0.075180,0.149141,-0.035826,0.079652,0.139440,-0.015421,0.079795,0.118512,-0.025717,0.075414,0.128682,-0.047521,0.078564,0.134056,-0.031563,0.070957,0.076486,0.024231,0.070310,0.078143,0.026044,0.070517,0.076828,0.025185,0.072786,0.077129,0.021726,0.071704,0.076745,0.023046,0.074173,0.080584,0.020915,0.074034,0.077479,0.020331,0.074643,0.083990,0.021009,0.074072,0.092503,0.010594,0.073874,0.090642,0.008187,0.074085,0.092024,0.007731,0.074270,0.093635,0.009863,0.073994,0.092153,0.009166,0.074897,0.089865,0.008143,0.075143,0.092353,0.009606,0.075693,0.091099,0.007917,0.073939,0.088967,0.007414,0.075316,0.094550,0.011404,0.075555,0.095814,0.013533,0.076530,0.095969,0.010893,0.074099,0.094257,0.012726,0.074566,0.093408,0.011267,0.073976,0.094943,0.012425,0.074423,0.093768,0.007548,0.074023,0.097199,0.009433,0.074279,0.095055,0.010010,0.056222,0.170984,0.049590,0.069052,0.160009,0.032194,0.063050,0.172059,0.031857,0.063105,0.166405,0.040832,0.075539,0.150572,0.017067,0.078216,0.131248,0.004205,0.075345,0.158775,-0.001974,0.078328,0.145478,0.001372,0.066598,0.173820,0.010606,0.071015,0.165804,-0.023008,0.070199,0.169570,-0.006265,0.061155,0.177711,0.024816,0.072733,0.152965,0.027340,0.070382,0.085999,0.030482,0.068410,0.099836,0.041631,0.069130,0.079985,0.036510,0.069951,0.092336,0.035788,0.069176,0.072010,0.029153,0.068201,0.064714,0.032180,0.068228,0.062820,0.029675,0.070401,0.081414,0.027342,0.064295,0.062786,0.052217,0.063914,0.041359,0.046851,0.063003,0.051873,0.055737,0.064072,0.038554,0.035105,0.062433,0.030868,0.038852,0.066672,0.054136,0.034886,0.064868,0.043421,0.031843,0.066592,0.091622,0.050421,0.064124,0.082749,0.058540,0.067041,0.070249,0.043078,0.065796,0.076330,0.050909,0.067879,0.066928,0.036537,0.063007,0.112973,0.058080,0.066015,0.107462,0.049131,0.062064,0.121494,-0.074192,0.066730,0.139475,-0.064362,0.070617,0.108195,-0.059659,0.069578,0.124726,-0.062086,0.044554,0.113780,-0.091127,0.052628,0.132693,-0.083944,0.053989,0.101435,-0.082245,0.053717,0.117731,-0.083847,0.034605,0.127535,-0.096674,0.033982,0.093587,-0.095421,0.022685,0.109016,-0.101321,0.034397,0.110679,-0.096835,0.024523,0.190107,-0.059443,0.011902,0.183252,-0.074636,-0.002633,0.192050,-0.063696,0.011063,0.197871,-0.049725,0.011596,0.191696,-0.062724,0.009408,0.207274,-0.021251,0.022126,0.201613,-0.032820,-0.002673,0.203751,-0.037869,0.010369,0.203086,-0.036271,0.018697,0.208223,-0.002717,-0.003547,0.210545,-0.004736,0.008144,0.209910,-0.003858,0.028767,0.203402,-0.015704,0.027297,0.205535,-0.001915,0.034628,0.194522,-0.040010,0.031565,0.199439,-0.027676,0.034632,0.156658,-0.087271,0.043546,0.143769,-0.088174,0.023417,0.142712,-0.097593,0.034499,0.142865,-0.093392,0.043904,0.166677,-0.073722,0.024532,0.170517,-0.082492,0.035579,0.178926,-0.066970,0.035115,0.168675,-0.078160,0.050160,0.155112,-0.077390,0.057235,0.147029,-0.074647,0.051029,0.145041,-0.081975,0.062560,0.170638,-0.042072,0.052889,0.171131,-0.058605,0.045753,0.184187,-0.048567,0.054753,0.178388,-0.044945,0.066618,0.155850,-0.053736,0.069648,0.161249,-0.039174,0.057108,0.158636,-0.066580,0.062372,0.150849,-0.065468,0.051046,0.163478,-0.069496,0.035729,0.187665,-0.054021,0.011074,0.158707,-0.093717,-0.002692,0.172648,-0.085222,0.011695,0.172124,-0.084985,0.010008,0.126213,-0.103644,-0.003619,0.143911,-0.101226,0.010450,0.143238,-0.100282,0.006655,0.063698,-0.094142,-0.004874,0.075480,-0.100052,0.008835,0.091299,-0.102504,0.020588,0.076432,-0.096640,0.008011,0.075922,-0.099307,-0.003478,0.108702,-0.105333,0.009640,0.108503,-0.104391,0.029935,0.064960,-0.088234,0.044060,0.080399,-0.087593,0.032689,0.077581,-0.092775,0.050727,0.070266,-0.076097,0.061896,0.089346,-0.070661,0.053632,0.084981,-0.080289,0.069621,0.091528,-0.058470,0.044906,0.049992,-0.068634,0.038297,0.056223,-0.079519,0.048162,0.058352,-0.072358,0.224380,-0.162209,-0.040738,0.224804,-0.154325,-0.046663,0.226645,-0.155124,-0.033170,0.225627,-0.156913,-0.039972,0.176830,-0.112870,-0.033004,0.172927,-0.113199,-0.025139,0.178820,-0.119907,-0.017418,0.192458,-0.122464,-0.024471,0.181865,-0.116815,-0.024955,0.164557,-0.114854,-0.019322,0.154517,-0.119478,-0.011409,0.172705,-0.128219,-0.007045,0.168663,-0.120265,-0.013620,0.117060,-0.141167,0.019763,0.128313,-0.132479,0.008122,0.110901,-0.126536,0.005660,0.100519,-0.132674,0.019152,0.114105,-0.132562,0.013265,0.143719,-0.143373,0.010546,0.158380,-0.135884,0.001548,0.141409,-0.125449,-0.002300,0.143195,-0.133599,0.004255,0.217432,-0.178370,-0.045426,0.210870,-0.186213,-0.019935,0.200716,-0.195958,-0.050233,0.206226,-0.186655,-0.075649,0.210088,-0.187762,-0.047931,0.207440,-0.171566,-0.088336,0.195254,-0.192261,-0.102683,0.194637,-0.176299,-0.110120,0.201900,-0.182495,-0.096617,0.218081,-0.153245,-0.065603,0.217836,-0.167023,-0.062196,0.203178,-0.153382,-0.087663,0.213058,-0.161459,-0.077788,0.222483,-0.168681,-0.023716,0.221932,-0.169296,-0.042775,0.185270,-0.179165,0.022967,0.201944,-0.176630,0.012622,0.197743,-0.160066,0.010007,0.180438,-0.165293,0.017088,0.191923,-0.170154,0.017194,0.139896,-0.162215,0.025812,0.124893,-0.161230,0.030848,0.121007,-0.175129,0.041886,0.143130,-0.176486,0.034585,0.132621,-0.169537,0.033983,0.168004,-0.184617,0.029743,0.162443,-0.171184,0.024945,0.149044,-0.193173,0.032025,0.155775,-0.181260,0.032493,0.155257,-0.156863,0.016745,0.171838,-0.150108,0.008278,0.168022,-0.160934,0.016614,0.173029,-0.196030,0.022338,0.186406,-0.191785,0.018498,0.178675,-0.187988,0.026392,0.199323,-0.189781,0.002703,0.180594,-0.199643,0.005721,0.191222,-0.199258,-0.019359,0.190210,-0.195648,0.004342,0.214799,-0.173693,-0.003994,0.207671,-0.182406,0.000002,0.224488,-0.155623,-0.017356,0.213421,-0.156756,-0.001256,0.220741,-0.164404,-0.009536,0.204918,-0.137941,-0.009660,0.188381,-0.142595,0.000731,0.202073,-0.148789,0.001404,0.173578,-0.138822,0.000347,0.131462,-0.151210,0.020463,0.143000,-0.153325,0.017786,0.107725,-0.152530,0.031777,0.120134,-0.151476,0.025555,0.098814,-0.165201,0.043928,0.086340,-0.178457,0.052903,0.108740,-0.192197,0.043289,0.104837,-0.178007,0.048532,0.089628,-0.141881,0.030676,0.077780,-0.153004,0.040057,0.093522,-0.153106,0.037187,0.083960,-0.126271,0.016236,0.072756,-0.132864,0.026803,0.086733,-0.132819,0.023949,0.060301,-0.067882,-0.014656,0.061928,-0.084648,-0.006670,0.070075,-0.095293,-0.011597,0.067952,-0.076531,-0.021060,0.065450,-0.081537,-0.013218,0.059047,-0.125391,0.021170,0.046716,-0.126239,0.027779,0.059474,-0.140050,0.034945,0.058999,-0.130917,0.028460,0.052246,0.082440,0.080089,0.053588,0.075257,0.081168,0.055534,0.084483,0.076421,0.054798,0.079115,0.078421,0.050697,0.087710,0.080466,0.053254,0.091702,0.078509,0.051779,0.096098,0.082484,0.051225,0.091601,0.080725,0.049154,0.082074,0.082806,0.050052,0.084507,0.081326,0.015569,0.076105,0.098852,0.013256,0.079680,0.098288,0.009581,0.079863,0.100813,0.012122,0.075605,0.101569,0.012535,0.077646,0.099687,0.005930,0.076019,0.108618,0.008753,0.075966,0.104956,0.006384,0.080784,0.104579,0.006102,0.078597,0.106801,0.006382,0.070749,0.111466,0.008363,0.071087,0.108139,0.003854,0.075849,0.112761,0.006057,0.073321,0.110156,0.008302,0.066238,0.110219,0.004759,0.070703,0.115326,0.006760,0.066282,0.113448,0.006563,0.068392,0.112500,0.011262,0.050734,0.110821,0.011732,0.053742,0.109282,0.011748,0.052337,0.110421,0.010307,0.048782,0.111294,0.010588,0.049152,0.112442,0.012905,0.048812,0.108980,0.011076,0.047485,0.110665,0.013079,0.053061,0.107707,0.016453,0.052924,0.107103,0.014623,0.050636,0.107867,0.011608,0.057948,0.109136,0.012853,0.057749,0.107123,0.011840,0.055535,0.108100,0.013153,0.067173,0.105451,0.014771,0.062758,0.106032,0.018284,0.063573,0.104629,0.016530,0.067982,0.103245,0.015687,0.065429,0.104897,0.011822,0.062193,0.107171,0.015881,0.057978,0.106597,0.013808,0.060150,0.106609,0.012084,0.056495,0.114395,0.011360,0.058959,0.111696,0.010554,0.059752,0.114848,0.011764,0.057781,0.113053,0.011430,0.056266,0.117885,0.009474,0.059763,0.118639,0.009938,0.057798,0.120376,0.012207,0.054689,0.115842,0.009235,0.062545,0.112348,0.005580,0.066606,0.117387,0.007933,0.062871,0.115776,0.007186,0.064429,0.114552,0.003405,0.070829,0.119663,0.004447,0.066965,0.121796,0.003975,0.068892,0.120745,0.006842,0.063034,0.119801,0.005024,0.064915,0.123047,0.008743,0.061415,0.117114,0.010177,0.062124,0.109465,0.010765,0.060380,0.110525,0.010292,0.066513,0.107553,0.010001,0.064195,0.108415,0.011060,0.071430,0.105075,0.010653,0.069000,0.106476,0.014422,0.071840,0.102176,0.011567,0.073621,0.103392,0.021729,0.073945,0.098207,0.019354,0.077285,0.097901,0.017973,0.072688,0.099641,0.018607,0.074896,0.098334,0.020317,0.069155,0.101087,0.017341,0.070475,0.101483,0.020454,0.052444,0.106870,0.019645,0.058394,0.106007,0.018066,0.055482,0.106758,0.024124,0.058871,0.104691,0.022378,0.064570,0.102833,0.021090,0.061456,0.104628,0.026092,0.044132,0.107045,0.025367,0.051869,0.106224,0.023157,0.048725,0.107159,0.037324,0.026687,0.102029,0.032050,0.032446,0.105450,0.034355,0.025829,0.104278,0.038391,0.037244,0.100692,0.040873,0.027729,0.098804,0.032004,0.041464,0.104986,0.029187,0.038649,0.106479,0.031079,0.051172,0.104085,0.037312,0.050575,0.099878,0.034812,0.045160,0.102602,0.029113,0.059628,0.102498,0.027453,0.055561,0.104607,0.031330,0.068151,0.098538,0.026774,0.065935,0.100718,0.034338,0.061339,0.099376,0.030343,0.063919,0.100233,0.039326,0.065137,0.095703,0.038757,0.057982,0.097642,0.039365,0.074735,0.092798,0.035741,0.071245,0.095870,0.043186,0.070594,0.091939,0.039544,0.070781,0.094151,0.032244,0.074641,0.096023,0.028213,0.072456,0.097665,0.031920,0.071830,0.097117,0.024217,0.070466,0.099079,0.023433,0.067631,0.100864,0.025450,0.075438,0.097509,0.024860,0.073149,0.098046,0.022804,0.078141,0.097744,0.029186,0.077070,0.096533,0.025924,0.077397,0.097386,0.045392,0.075637,0.088699,0.049482,0.071530,0.086881,0.046576,0.070853,0.089549,0.049736,0.077487,0.084308,0.051804,0.072847,0.084044,0.046235,0.079334,0.086388,0.047937,0.080455,0.084583,0.041782,0.077884,0.090178,0.044209,0.078550,0.088339,0.035851,0.076978,0.093860,0.032513,0.076899,0.095397,0.038949,0.077339,0.091994,0.017022,0.080442,0.097827,0.019865,0.079259,0.097872,0.011621,0.083067,0.097898,0.014261,0.081629,0.097791,0.062120,-0.099861,-0.108023,0.066060,-0.083005,-0.092633,0.094258,-0.102993,-0.099987,0.084108,-0.123510,-0.118044,0.076601,-0.100623,-0.104220,0.022283,-0.052086,-0.087439,0.020254,-0.034141,-0.077926,0.032550,-0.038000,-0.070929,0.037534,-0.058554,-0.084437,0.027424,-0.045508,-0.079972,0.043719,-0.033458,-0.052761,0.046129,-0.046896,-0.062698,0.033816,-0.020755,-0.060347,0.038352,-0.034085,-0.061603,0.052120,-0.038616,-0.037454,0.056661,-0.048742,-0.022912,0.059979,-0.056049,-0.029690,0.054988,-0.043370,-0.030091,0.069274,-0.066552,-0.049383,0.087212,-0.080961,-0.044440,0.096116,-0.082880,-0.061364,0.069953,-0.068132,-0.062931,0.080250,-0.074563,-0.054904,0.217770,-0.140133,-0.024713,0.204055,-0.127613,-0.040492,0.205954,-0.130601,-0.023961,0.224703,-0.146021,-0.039757,0.225578,-0.148999,-0.027667,0.213362,-0.138949,-0.056195,0.222043,-0.147787,-0.052688,0.183244,-0.119954,-0.059800,0.195493,-0.135271,-0.076068,0.200425,-0.129292,-0.058272,0.137925,-0.118522,-0.098459,0.121383,-0.130442,-0.115999,0.113489,-0.096106,-0.080642,0.116031,-0.110055,-0.098804,0.186410,-0.156804,-0.108140,0.175303,-0.135463,-0.096042,0.190598,-0.144482,-0.093278,0.184056,-0.186343,-0.120651,0.171508,-0.166312,-0.123493,0.184153,-0.170952,-0.118686,0.159471,-0.183341,-0.129347,0.142739,-0.157800,-0.128072,0.156968,-0.142586,-0.114002,0.157762,-0.161930,-0.126224,0.160088,-0.116142,-0.079692,0.157745,-0.126903,-0.097622,0.141403,-0.101621,-0.064015,0.165485,-0.108652,-0.047483,0.163426,-0.110671,-0.062306,0.103588,-0.117740,-0.011067,0.116291,-0.109731,-0.020935,0.095657,-0.099220,-0.025604,0.084226,-0.109229,-0.014963,0.099466,-0.110063,-0.019189,0.122614,-0.120966,-0.006676,0.093594,-0.122195,0.002876,0.107406,-0.122195,-0.002483,0.135896,-0.114423,-0.015918,0.138714,-0.119517,-0.009261,0.162387,-0.108326,-0.030630,0.149332,-0.109370,-0.023805,0.162606,-0.110874,-0.024828,0.147070,-0.102739,-0.039001,0.164145,-0.107729,-0.037490,0.131058,-0.103725,-0.029673,0.133438,-0.109202,-0.022462,0.123883,-0.094177,-0.050007,0.109313,-0.094276,-0.036919,0.128197,-0.098404,-0.038622,0.117837,-0.092173,-0.064069,0.077874,-0.080731,-0.031092,0.092235,-0.088849,-0.034009,0.064584,-0.061691,-0.038427,0.067508,-0.068874,-0.029708,0.045446,-0.024061,-0.043934,0.053306,-0.046315,-0.045691,0.048376,-0.035117,-0.044931,0.057788,-0.055555,-0.055096,0.060760,-0.056783,-0.046796,0.056954,-0.064207,-0.075458,0.057221,-0.058854,-0.064266,0.046792,-0.080136,-0.098828,0.051487,-0.070253,-0.087303,0.053388,-0.121114,-0.120476,0.038535,-0.097923,-0.111496,0.049074,-0.097727,-0.109674,0.003370,-0.202208,-0.085241,0.017373,-0.203138,-0.039935,0.008879,-0.200067,0.004855,-0.004913,-0.202748,-0.041163,0.006166,-0.202848,-0.040703,0.044312,-0.147323,-0.131241,0.071505,-0.148029,-0.130657,0.059076,-0.173307,-0.134739,0.056396,-0.147390,-0.130939,0.027242,-0.097021,-0.112401,0.034113,-0.122437,-0.122599,0.033069,-0.103835,-0.114852,0.010231,-0.147642,-0.132258,0.018986,-0.120632,-0.122728,0.026911,-0.147630,-0.131694,0.019203,-0.173562,-0.132405,0.018860,-0.147588,-0.132003,0.036011,-0.173253,-0.133270,0.049183,-0.194841,-0.122744,0.044442,-0.204391,-0.091818,0.029119,-0.194220,-0.117881,0.038384,-0.194519,-0.120061,0.023419,-0.202765,-0.085778,0.011319,-0.193810,-0.116321,0.020281,-0.193954,-0.116710,0.034922,-0.147599,-0.131540,0.078098,-0.196266,-0.124879,0.066753,-0.206449,-0.101965,0.062256,-0.195238,-0.124790,0.127956,-0.201887,0.021319,0.087793,-0.201033,0.025353,0.105923,-0.206721,-0.010806,0.108216,-0.201699,0.023145,0.069484,-0.190877,0.051278,0.051247,-0.197980,0.036594,0.063713,-0.203900,-0.003383,0.068663,-0.199641,0.031286,0.130074,-0.178853,-0.133428,0.108295,-0.151345,-0.130129,0.126255,-0.154198,-0.129333,0.099966,-0.208032,-0.096502,0.093402,-0.175232,-0.135167,0.116029,-0.198934,-0.122685,0.096805,-0.197638,-0.124002,0.089393,-0.149337,-0.130438,0.148247,-0.200883,-0.118986,0.136329,-0.209565,-0.093172,0.133232,-0.200038,-0.121021,0.158760,-0.202391,0.012622,0.169019,-0.206143,-0.017006,0.170401,-0.201698,0.008688,0.142435,-0.207641,-0.011200,0.144873,-0.202287,0.017252,0.174002,-0.200766,-0.112892,0.164321,-0.209013,-0.090343,0.161677,-0.201319,-0.116367,0.187890,-0.202879,-0.084821,0.185549,-0.198309,-0.108265,0.178867,-0.206801,-0.053545,0.190170,-0.202339,-0.052222,0.154103,-0.210437,-0.053510,0.166973,-0.209355,-0.053940,0.122682,-0.210053,-0.052721,0.139613,-0.210545,-0.052651,0.084564,-0.208634,-0.062741,0.103269,-0.209241,-0.055302,0.065592,-0.207355,-0.060669,0.072416,-0.208479,-0.075103,0.041095,-0.204691,-0.042680,0.054064,-0.205906,-0.049242,0.033885,-0.201298,0.006832,0.028872,-0.203733,-0.040049,0.001538,-0.173741,-0.132560,-0.008338,-0.147804,-0.132279,0.000825,-0.120735,-0.123182,0.001031,-0.147776,-0.132355,0.009708,-0.093933,-0.112120,-0.008693,-0.094138,-0.111805,-0.000244,-0.070679,-0.101360,0.000465,-0.093981,-0.112126,0.017981,-0.071433,-0.100586,0.018894,-0.094313,-0.111904,0.012490,-0.040094,-0.083186,0.006690,-0.053017,-0.091559,0.014879,-0.053580,-0.090612,0.014134,-0.106288,0.027188,0.005943,-0.097088,0.030671,-0.001027,-0.109223,0.025397,0.008920,-0.119509,0.024797,0.006888,-0.108084,0.026224,0.025460,-0.103839,0.025932,0.019456,-0.095301,0.028450,0.022538,-0.114898,0.026568,0.020370,-0.105077,0.027367,0.019303,-0.126615,0.030482,0.031649,-0.134774,0.038465,0.033319,-0.123212,0.027753,0.027020,-0.125185,0.030058,0.031997,-0.108247,0.022298,0.030355,-0.094400,0.024802,0.029208,-0.102148,0.024434,0.040946,-0.111324,0.018608,0.037177,-0.118588,0.022684,0.053132,-0.057342,0.007579,0.056872,-0.039434,0.001515,0.050526,-0.047087,0.014689,0.054454,-0.043303,0.008326,0.055854,-0.040518,-0.017393,0.057083,-0.058876,-0.009509,0.057065,-0.054061,-0.016065,0.057093,-0.031632,-0.011718,0.055304,-0.027781,-0.018211,0.057089,-0.049378,-0.004540,0.057641,-0.035542,-0.005162,0.057532,-0.075855,-0.002092,0.055404,-0.066987,0.002424,0.056821,-0.063115,-0.003343,0.052394,-0.082979,0.007881,0.048186,-0.074497,0.012611,0.052448,-0.070726,0.007730,0.044165,-0.064605,0.018494,0.037535,-0.081601,0.022148,0.043365,-0.092008,0.016642,0.043140,-0.078393,0.017421,0.056291,-0.089368,0.003270,0.059972,-0.096478,-0.000138,0.058958,-0.086882,-0.001227,0.065347,-0.107519,-0.002713,0.076718,-0.118684,-0.002524,0.073368,-0.108290,-0.008487,0.068738,-0.124075,0.010275,0.058070,-0.114103,0.005430,0.049988,-0.114707,0.013400,0.057796,-0.121758,0.011957,0.080865,-0.123257,0.007292,0.055720,-0.101083,0.005588,0.059414,-0.105454,0.001968,0.050076,-0.098605,0.011460,0.053533,-0.093406,0.007398,0.045802,-0.104505,0.015438,0.025477,-0.083858,0.028657,0.032295,-0.070125,0.026945,0.031649,-0.082937,0.026072,0.013741,-0.040341,0.061929,0.012748,-0.042959,0.057513,0.021238,-0.040255,0.050219,0.024041,-0.034033,0.060044,0.018867,-0.038860,0.057220,0.004572,-0.043964,0.062152,0.006982,-0.041356,0.066899,-0.004071,-0.043500,0.066202,0.005539,-0.042635,0.064690,-0.004018,-0.046498,0.060664,0.005474,-0.048523,0.056126,0.004899,-0.045701,0.059342,0.013997,-0.067752,0.041237,0.019925,-0.074635,0.033770,0.026645,-0.060579,0.031891,0.021342,-0.054507,0.039086,0.020506,-0.064278,0.036433,0.039467,-0.054021,0.024665,0.046417,-0.035776,0.021833,0.045534,-0.050700,0.020322,0.042505,-0.025372,0.028858,0.047949,-0.019512,0.023741,0.034126,-0.044345,0.029723,0.033016,-0.057197,0.028200,0.029116,-0.039089,0.038752,0.036165,-0.031806,0.033627,0.014177,-0.051112,0.047770,0.021809,-0.045990,0.043280,-0.003729,-0.054889,0.054020,0.005720,-0.061952,0.048620,0.005534,-0.054151,0.051918,-0.003201,-0.070961,0.046076,0.005687,-0.078445,0.039746,0.005759,-0.070054,0.044504,0.013246,-0.086581,0.033707,0.019439,-0.085092,0.030895,-0.002429,-0.087472,0.035544,0.005747,-0.087484,0.035572,0.000759,-0.131705,0.026766,0.012033,-0.138742,0.034362,0.010770,-0.129390,0.028904,0.000683,-0.149950,0.036803,0.011364,-0.159517,0.046477,0.022713,-0.146811,0.045334,0.012178,-0.148435,0.040496,0.035317,-0.160753,0.050705,0.047119,-0.148795,0.044036,0.034367,-0.147104,0.046099,0.064885,-0.164139,0.048825,0.050754,-0.175538,0.055476,0.067764,-0.177277,0.054713,0.061742,-0.151607,0.041502,0.022200,-0.195212,0.036972,0.009532,-0.185026,0.050277,-0.002144,-0.194421,0.033844,0.009760,-0.194664,0.034996,0.035915,-0.187380,0.054097,0.035809,-0.196416,0.038217,0.022171,-0.172553,0.054689,0.035839,-0.173818,0.055764,-0.001154,-0.171504,0.050047,0.010042,-0.171774,0.052091,0.000483,0.075045,0.121658,-0.002597,0.079380,0.122960,-0.005708,0.077300,0.125608,-0.002344,0.076568,0.124299,0.002117,0.075556,0.117237,0.002749,0.073013,0.118511,-0.000246,0.080844,0.118902,0.001811,0.078494,0.115836,-0.002918,0.085987,0.119218,-0.006186,0.083184,0.121832,-0.002894,0.082617,0.121277,-0.006157,0.089760,0.117544,-0.002479,0.092396,0.114294,-0.002613,0.089230,0.116775,-0.002777,0.098426,0.111908,0.000871,0.101038,0.110659,-0.001957,0.103702,0.113767,-0.006059,0.101248,0.113151,-0.002376,0.101189,0.112577,-0.006092,0.095727,0.113631,0.000024,0.095102,0.109646,-0.002747,0.095473,0.112518,0.006322,0.100968,0.104990,0.007145,0.097853,0.099475,0.011902,0.102710,0.106248,0.008954,0.100505,0.102358,0.004371,0.085132,0.103221,0.003838,0.088942,0.100611,0.001665,0.091878,0.105568,0.002373,0.088202,0.104373,0.007601,0.083646,0.099466,0.006805,0.082408,0.102023,0.007416,0.087085,0.098054,0.009216,0.084908,0.097878,0.005157,0.091968,0.097233,0.006082,0.089363,0.097894,0.003499,0.095422,0.101321,0.005719,0.095109,0.097637,0.002699,0.098312,0.106175,0.001929,0.095257,0.105792,0.004889,0.103252,0.110486,0.003690,0.101001,0.107867,0.002697,0.105989,0.114694,0.011554,0.105038,0.111790,0.009427,0.110024,0.114876,0.006764,0.105760,0.113159,-0.007241,0.133425,0.111379,0.000373,0.124616,0.114926,0.008970,0.133049,0.111535,0.002313,0.144483,0.110127,0.001194,0.133289,0.111561,-0.006998,0.116852,0.116478,-0.001177,0.110633,0.116006,0.005972,0.116562,0.116898,-0.000503,0.116710,0.116821,0.014479,0.124656,0.114514,0.022083,0.132990,0.108420,0.017958,0.143092,0.107423,0.015900,0.132939,0.110496,0.026504,0.124437,0.109275,0.018419,0.116473,0.113825,0.021110,0.109567,0.111533,0.030709,0.116003,0.107730,0.024579,0.116344,0.111153,0.016528,0.104464,0.110182,0.042147,0.113512,0.099042,0.037388,0.123121,0.101173,0.036770,0.115341,0.103705,0.043742,0.129029,0.092630,0.041493,0.140612,0.092973,0.032939,0.132756,0.101570,0.038291,0.131670,0.097280,0.050404,0.144334,0.081094,0.050954,0.131115,0.082256,0.058341,0.127185,0.070261,0.054709,0.137421,0.075401,0.049154,0.105918,0.089222,0.046819,0.116984,0.091049,0.046265,0.110239,0.093955,0.052435,0.104802,0.082438,0.051108,0.101125,0.085384,0.056523,0.111733,0.072990,0.061103,0.099881,0.065018,0.059489,0.113779,0.066341,0.058772,0.090037,0.071248,0.055774,0.099485,0.076096,0.055687,0.091316,0.075439,0.061848,0.087345,0.065545,0.051469,0.116996,0.082050,0.054205,0.108489,0.078344,0.047969,0.124068,0.087126,0.013227,0.155420,0.105114,0.004900,0.166543,0.100632,-0.006230,0.157195,0.106856,0.004015,0.156543,0.106241,0.027865,0.153825,0.100422,0.022742,0.164190,0.096666,0.021019,0.154546,0.103195,-0.005667,0.175281,0.094454,0.015040,0.173665,0.091850,0.005216,0.174862,0.093778,0.030433,0.170465,0.085757,0.023549,0.179105,0.081514,0.023344,0.172236,0.089154,0.047575,0.155635,0.079126,0.049342,0.168593,0.063804,0.042915,0.165640,0.076916,0.048819,0.162314,0.071395,0.043479,0.177630,0.062213,0.049673,0.174567,0.056651,0.023835,0.190146,0.064929,0.031481,0.192402,0.052017,0.024359,0.194879,0.054454,0.030739,0.182772,0.070428,0.023618,0.184937,0.073661,0.037261,0.185237,0.058583,0.037826,0.189546,0.049056,0.037323,0.174778,0.074192,0.037261,0.180353,0.066696,0.036030,0.161182,0.089498,0.036903,0.168355,0.081741,0.039797,0.151209,0.092021,0.045166,0.148550,0.086604,0.030278,0.142864,0.101853,0.034044,0.152852,0.096680,0.027574,0.133006,0.105244,0.012284,0.116473,0.115910,-0.006130,0.106839,0.114726,-0.001606,0.106591,0.114783,0.017899,-0.031850,0.081471,0.005211,-0.035562,0.087160,0.007691,-0.037384,0.080663,0.011543,-0.034226,0.084258,-0.003232,-0.035580,0.089300,0.001871,-0.034802,0.089461,-0.004047,-0.042230,0.070741,0.020018,-0.035128,0.067861,0.008624,-0.039640,0.072612,0.008243,-0.040415,0.069427,0.032002,-0.024898,0.066907,0.028563,-0.029364,0.063445,0.028483,-0.026158,0.074779,0.035063,-0.020812,0.070745,0.017563,-0.034162,0.076425,0.023083,-0.029449,0.078367,-0.004304,-0.040562,0.077730,0.007496,-0.038901,0.076479,0.014851,0.013344,-0.068908,0.007503,0.025605,-0.069643,0.017799,0.028886,-0.070779,0.024961,0.019564,-0.065652,0.016195,0.022592,-0.069405,0.038579,0.038758,-0.062972,0.032763,0.042896,-0.072737,0.049561,0.045075,-0.056138,0.041336,0.044207,-0.065328,0.053540,0.039048,-0.043549,0.056721,0.045719,-0.045949,0.047921,0.024508,-0.039508,0.043783,0.032635,-0.051719,0.050601,0.032116,-0.041508,0.034626,0.025984,-0.059500,0.028298,0.032983,-0.068212,0.036403,0.032876,-0.061131,0.045068,-0.006078,-0.038913,0.046180,0.005971,-0.035459,0.047976,-0.003298,-0.033026,0.039186,-0.009409,-0.049385,0.044337,-0.013761,-0.042221,0.023631,-0.003734,-0.066667,0.032165,0.006681,-0.057015,0.032223,-0.006561,-0.058640,0.039988,0.016009,-0.047241,0.046087,0.015758,-0.037473,0.033140,0.017454,-0.057733,0.025235,0.047864,-0.080981,0.016299,0.055044,-0.087327,0.027422,0.055329,-0.084309,0.021021,0.038186,-0.074384,0.012813,0.042293,-0.080520,0.023035,0.042482,-0.077511,0.003842,0.047289,-0.085374,-0.005921,0.054360,-0.088926,0.005158,0.054514,-0.089164,0.000377,0.032448,-0.070803,-0.007304,0.035777,-0.073785,0.001864,0.038764,-0.077602,0.010037,0.035227,-0.073890,0.001137,0.035997,-0.073822,-0.006829,0.042328,-0.081056,0.002744,0.042271,-0.081439,0.019334,0.033861,-0.072218,0.004446,-0.025908,-0.077594,0.013729,-0.014922,-0.073302,0.012555,-0.028138,-0.077789,-0.003249,-0.010796,-0.073222,-0.009445,0.004689,-0.071160,-0.001560,0.018133,-0.069066,0.005025,0.003210,-0.070090,-0.002630,0.004723,-0.070078,0.014115,0.000039,-0.070140,-0.002558,-0.038451,-0.083560,-0.009566,-0.052265,-0.091892,-0.001499,-0.052473,-0.091934,-0.010074,-0.024942,-0.078070,-0.003116,-0.025098,-0.077698,-0.008063,0.026439,-0.069873,-0.000542,0.026919,-0.069157,0.001814,0.058127,0.115497,0.002744,0.059614,0.115100,0.002246,0.060800,0.115455,0.001283,0.059889,0.115935,0.002019,0.059741,0.115443,0.003395,0.061219,0.118614,0.001923,0.060169,0.120810,0.001423,0.061219,0.119402,0.002886,0.062025,0.117946,0.002432,0.061319,0.119210,0.006114,0.058992,0.116413,0.004871,0.060801,0.116922,0.004288,0.061572,0.116314,0.005091,0.060245,0.115499,0.005165,0.060533,0.116159,0.004428,0.059862,0.118609,0.003967,0.061817,0.117275,0.004257,0.061070,0.117802,0.004065,0.057814,0.114870,0.004097,0.059781,0.114909,0.002854,0.060829,0.115163,0.003452,0.059625,0.114985,0.005917,0.058063,0.114950,0.003539,0.061346,0.115600,0.004685,0.059979,0.115098,0.000041,0.058588,0.116910,0.001018,0.060985,0.116248,0.000136,0.060130,0.117223,0.000611,0.060007,0.116535,-0.000889,0.059007,0.118997,0.000688,0.061274,0.117019,0.000154,0.060687,0.118635,-0.000009,0.060369,0.117937,-0.000376,0.059635,0.121006,0.001546,0.061836,0.117687,0.000612,0.060984,0.119179,0.003038,0.061913,0.116717,0.003575,0.061941,0.117005,0.001944,0.061832,0.116310,0.002498,0.061973,0.116486,0.002049,0.061411,0.115667,0.001437,0.061432,0.116189,0.002457,0.061305,0.115355,0.003168,0.055898,0.115188,0.004772,0.053940,0.115507,0.005881,0.055715,0.115020,0.004620,0.055724,0.115006,0.003516,0.052824,0.116245,0.005689,0.052848,0.116620,0.004730,0.052751,0.116271,0.000527,0.056571,0.116372,0.001891,0.054361,0.115990,0.001727,0.056193,0.115601,0.000958,0.053542,0.117606,0.002138,0.053067,0.116649,-0.001070,0.057083,0.118647,-0.000373,0.055176,0.118007,-0.000402,0.056874,0.117359,-0.000311,0.054305,0.120637,0.000124,0.053906,0.118879,-0.001387,0.057549,0.121781,-0.001249,0.055718,0.121554,-0.001453,0.057296,0.120210,-0.000788,0.054608,0.124631,-0.000537,0.054616,0.122737,0.000145,0.058365,0.123247,-0.000830,0.056235,0.124645,-0.000884,0.057931,0.122918,0.000456,0.055371,0.126241,-0.000546,0.054851,0.125826,0.003178,0.058616,0.121158,0.001734,0.057107,0.124253,0.001581,0.058618,0.122543,0.003628,0.055338,0.123664,0.002017,0.055549,0.125426,0.005848,0.057893,0.118309,0.004831,0.056737,0.120828,0.004610,0.058372,0.119672,0.005962,0.054502,0.120226,0.005081,0.054999,0.121835,0.007263,0.056459,0.115974,0.006973,0.055510,0.118006,0.006873,0.057200,0.117073,0.006633,0.053368,0.117948,0.006415,0.053925,0.118928,0.006859,0.054170,0.116020,0.006892,0.055927,0.115204,0.006326,0.053036,0.117169,0.064564,0.037028,0.019264,0.064126,0.038355,0.017146,0.065006,0.038274,0.017414,0.065205,0.036292,0.020876,0.062579,0.037621,0.019879,0.063212,0.039130,0.023471,0.064112,0.038399,0.012109,0.063026,0.037488,0.015779,0.065284,0.039597,0.010227,0.074947,0.107324,0.007257,0.078452,0.112992,-0.006288,0.076830,0.117659,0.005982,0.075349,0.098874,0.001720,0.073977,0.101539,0.008124,0.076686,0.098096,-0.010094,0.075854,0.093813,-0.003905,0.078804,0.105841,-0.017704,0.074474,0.092534,0.006829,-0.007472,-0.193863,-0.116307,0.002061,-0.193880,-0.116226,0.003732,0.014135,0.106625,-0.003496,0.013981,0.107365,0.000083,0.014055,0.107141,0.010436,0.014146,0.104556,0.007183,0.014184,0.105718,0.016153,0.014387,0.102644,0.013498,0.014156,0.103492,0.019426,0.015772,0.101476,0.018163,0.014922,0.102008,0.019987,0.018100,0.100905,0.019940,0.016833,0.101070,0.019332,0.021026,0.101171,0.019788,0.019536,0.100956,0.017514,0.023417,0.102104,0.018555,0.022381,0.101535,0.014702,0.024450,0.103951,0.016211,0.024070,0.102895,0.011046,0.024819,0.106180,0.012936,0.024703,0.105093,0.007041,0.024910,0.107798,0.009108,0.024857,0.107102,0.002002,0.024780,0.108528,0.004700,0.024868,0.108246,-0.004149,0.024759,0.108924,-0.001001,0.024730,0.108775,0.073926,0.094089,0.016746,0.074891,0.094808,0.016055,0.073683,0.094758,0.015120,0.073364,0.093979,0.016849,0.073836,0.094772,0.013605,-0.077256,0.143415,0.047726,-0.080870,0.145630,0.031632,-0.081615,0.124571,0.029982,-0.078936,0.121379,0.045284,-0.080212,0.134553,0.038308,-0.081568,0.102355,0.023053,-0.080740,0.103423,0.030624,-0.083075,0.118981,0.017753,-0.081778,0.112999,0.025262,-0.081503,0.092054,0.020369,-0.080583,0.090480,0.025188,-0.082155,0.099945,0.015994,-0.081354,0.096257,0.021411,-0.082740,0.089731,0.018472,-0.082284,0.085146,0.020092,-0.081384,0.081638,0.021264,-0.081657,0.088018,0.020569,-0.081856,0.086510,0.020451,-0.082355,0.092123,0.017141,-0.081029,0.084935,0.022867,-0.081526,0.089653,0.020524,-0.039814,0.108062,0.084347,-0.044105,0.106597,0.081042,-0.038982,0.107147,0.078677,-0.034059,0.107495,0.081812,-0.039409,0.107808,0.081612,-0.024509,0.101550,0.081188,-0.029130,0.105243,0.084756,-0.028841,0.104546,0.078188,-0.028822,0.105217,0.081565,-0.020375,0.092158,0.081022,-0.022349,0.097287,0.084584,-0.021795,0.096580,0.077211,-0.021702,0.097008,0.081011,-0.021856,0.083459,0.081152,-0.021033,0.088512,0.084882,-0.020618,0.087031,0.076831,-0.020434,0.087575,0.080989,-0.025006,0.081702,0.085095,-0.024962,0.079143,0.077225,-0.028438,0.077405,0.081680,-0.024632,0.079974,0.081428,-0.032810,0.077981,0.085015,-0.032980,0.074999,0.077403,-0.037177,0.075743,0.080943,-0.032868,0.076021,0.081526,-0.040676,0.075188,0.076367,-0.043885,0.077505,0.079240,-0.040909,0.078080,0.083419,-0.040903,0.076320,0.080135,-0.045574,0.077927,0.074985,-0.047791,0.080820,0.077723,-0.046372,0.080686,0.081415,-0.046136,0.079043,0.078417,-0.050035,0.084969,0.076997,-0.049375,0.084201,0.079781,-0.048467,0.081839,0.074313,-0.049052,0.082808,0.077240,-0.051632,0.099334,0.080360,-0.051594,0.095663,0.077968,-0.050654,0.097919,0.076477,-0.049968,0.101452,0.079312,-0.051153,0.098551,0.078567,-0.052198,0.093772,0.079293,-0.051357,0.089934,0.077183,-0.051109,0.092026,0.075361,-0.051627,0.092765,0.077501,-0.051139,0.088294,0.079015,-0.050237,0.086516,0.074543,-0.050804,0.087312,0.076991,-0.047124,0.103767,0.077789,-0.048069,0.104729,0.082296,-0.047686,0.104313,0.080204,-0.025029,0.094987,0.071066,-0.021669,0.091441,0.073483,-0.025546,0.099918,0.074373,-0.022915,0.095882,0.073839,-0.031383,0.092830,0.067478,-0.027005,0.090791,0.068592,-0.030090,0.096875,0.069460,-0.028041,0.093967,0.068927,-0.031039,0.087822,0.066994,-0.028799,0.084371,0.068436,-0.024243,0.087217,0.070545,-0.027480,0.087478,0.068406,-0.023436,0.082913,0.073403,-0.021917,0.086994,0.073322,-0.027565,0.080606,0.070985,-0.029248,0.077042,0.073978,-0.025952,0.079533,0.073713,-0.032372,0.082532,0.067489,-0.031253,0.080040,0.069247,-0.029846,0.081847,0.068833,-0.036091,0.080682,0.067726,-0.033779,0.080679,0.067975,-0.035397,0.082932,0.066776,-0.034387,0.081985,0.067193,-0.035743,0.078536,0.069336,-0.033212,0.077083,0.071429,-0.033425,0.078970,0.069389,-0.036833,0.075131,0.073710,-0.033082,0.075576,0.073985,-0.038910,0.076999,0.070849,-0.042412,0.076671,0.072583,-0.039951,0.075598,0.073189,-0.039129,0.079679,0.068576,-0.037601,0.078871,0.069005,-0.038294,0.082256,0.067085,-0.041733,0.081960,0.067899,-0.042635,0.079158,0.069841,-0.040507,0.080720,0.068183,-0.045933,0.079792,0.071704,-0.044355,0.078082,0.072055,-0.030414,0.101337,0.072349,-0.033848,0.105202,0.075614,-0.029336,0.103155,0.075047,-0.038125,0.103876,0.073313,-0.042846,0.104876,0.075727,-0.038545,0.105758,0.075849,-0.044847,0.101340,0.072952,-0.048414,0.099975,0.074757,-0.046201,0.102723,0.075309,-0.048254,0.083947,0.071746,-0.046791,0.086461,0.069739,-0.049544,0.088765,0.072470,-0.049000,0.086250,0.072036,-0.043402,0.085026,0.067802,-0.040049,0.087104,0.066784,-0.043746,0.089060,0.068254,-0.043579,0.086911,0.067936,-0.037403,0.085510,0.066349,-0.035735,0.087388,0.066384,-0.037606,0.086667,0.066365,-0.040016,0.084244,0.066776,-0.045314,0.082412,0.069407,-0.042769,0.083386,0.067781,-0.047234,0.081777,0.071616,-0.036837,0.084040,0.066461,-0.037856,0.084611,0.066409,-0.033862,0.090031,0.066603,-0.033617,0.088349,0.066487,-0.036157,0.092278,0.066920,-0.033813,0.091747,0.066838,-0.040939,0.091839,0.067519,-0.038667,0.094099,0.067467,-0.038415,0.092762,0.067141,-0.045226,0.093578,0.069356,-0.047814,0.091250,0.070676,-0.044531,0.091339,0.068794,-0.050048,0.094354,0.073621,-0.049943,0.091509,0.073019,-0.042183,0.095341,0.068503,-0.044491,0.097889,0.070446,-0.047873,0.096422,0.071887,-0.045267,0.095766,0.069904,-0.049625,0.097179,0.074200,-0.040676,0.098753,0.069555,-0.040801,0.101415,0.071317,-0.043023,0.099915,0.070965,-0.038406,0.096333,0.068161,-0.039603,0.095177,0.067861,-0.037638,0.099961,0.069853,-0.034695,0.101252,0.070952,-0.037788,0.101864,0.071289,-0.034733,0.098179,0.069000,-0.037763,0.098114,0.068865,-0.032196,0.099474,0.070246,-0.036628,0.083215,0.066633,-0.045689,0.086804,0.096701,-0.047833,0.086589,0.094891,-0.049114,0.086544,0.094198,-0.047947,0.086052,0.095621,-0.047820,0.086491,0.095374,-0.031946,0.088474,0.098609,-0.029057,0.088943,0.098199,-0.026304,0.089952,0.096721,-0.028864,0.089293,0.097129,-0.028887,0.089366,0.097619,-0.023551,0.091191,0.095390,-0.023811,0.090719,0.095191,-0.024741,0.090256,0.094749,-0.024267,0.090605,0.095355,-0.024041,0.090687,0.095363,-0.023200,0.091422,0.095466,-0.023375,0.090997,0.095628,-0.022838,0.090913,0.096266,-0.023267,0.091278,0.095961,-0.023024,0.091197,0.095761,-0.032407,0.087403,0.099664,-0.035592,0.087270,0.099541,-0.039559,0.086315,0.099546,-0.036106,0.085797,0.100172,-0.035853,0.086657,0.099977,-0.029796,0.087410,0.099410,-0.026883,0.088973,0.098085,-0.029369,0.088290,0.098895,-0.036527,0.084027,0.099710,-0.033045,0.085633,0.100023,-0.039993,0.084609,0.099386,-0.036364,0.084944,0.100042,-0.030521,0.085636,0.099546,-0.028000,0.087423,0.099019,-0.030249,0.086496,0.099672,-0.026167,0.087772,0.098406,-0.025713,0.088584,0.098178,-0.026534,0.087967,0.098507,-0.033197,0.083796,0.099410,-0.040086,0.082560,0.098506,-0.036280,0.081997,0.098717,-0.036498,0.083030,0.099196,-0.050923,0.086039,0.091605,-0.051037,0.085538,0.092031,-0.050586,0.085830,0.092796,-0.050537,0.086530,0.092051,-0.050750,0.085949,0.092131,-0.051430,0.085679,0.091363,-0.051784,0.085257,0.091068,-0.051103,0.084976,0.092256,-0.051350,0.085343,0.091707,-0.049975,0.086253,0.093480,-0.050472,0.085103,0.093367,-0.049504,0.085476,0.094441,-0.050213,0.085661,0.093526,-0.046021,0.085852,0.097176,-0.048362,0.084782,0.095465,-0.048166,0.085450,0.095666,-0.042838,0.086774,0.098306,-0.043219,0.085466,0.098358,-0.043036,0.086219,0.098470,-0.046402,0.084270,0.096603,-0.043628,0.083630,0.097783,-0.043421,0.084614,0.098108,-0.049893,0.084309,0.093909,-0.048717,0.083400,0.094608,-0.048558,0.084088,0.095113,-0.050921,0.084244,0.092406,-0.050673,0.084643,0.092985,-0.051995,0.084545,0.090733,-0.052955,0.085833,0.089697,-0.053762,0.085167,0.088776,-0.052584,0.085218,0.090134,-0.050310,0.083225,0.092712,-0.051807,0.083368,0.090586,-0.051301,0.083860,0.091622,-0.046662,0.082464,0.095585,-0.048951,0.081842,0.093399,-0.048841,0.082688,0.094022,-0.043434,0.081320,0.096607,-0.043613,0.082503,0.097214,-0.035435,0.087291,0.098497,-0.039088,0.087159,0.098715,-0.035382,0.087546,0.099020,-0.042675,0.086877,0.097209,-0.042640,0.087084,0.097731,-0.045832,0.085953,0.095215,-0.039359,0.085514,0.097490,-0.042441,0.084387,0.094734,-0.042884,0.085748,0.096451,-0.031945,0.087183,0.097444,-0.034967,0.084809,0.096420,-0.035535,0.086019,0.097789,-0.026308,0.089885,0.095844,-0.028681,0.088201,0.095677,-0.028882,0.088727,0.096563,-0.030899,0.085772,0.094619,-0.033431,0.083758,0.092291,-0.037747,0.083471,0.093438,-0.034087,0.084254,0.094331,-0.044523,0.084297,0.091077,-0.040577,0.082846,0.089875,-0.041347,0.083680,0.092199,-0.042433,0.084550,0.100307,-0.038036,0.086264,0.102512,-0.043500,0.088474,0.102493,-0.046762,0.085832,0.099645,-0.043150,0.085783,0.101476,-0.050565,0.086025,0.095606,-0.048424,0.085088,0.096814,-0.049590,0.087858,0.098215,-0.049107,0.086041,0.097521,-0.049635,0.087479,0.092235,-0.050223,0.089880,0.089900,-0.050150,0.093578,0.089369,-0.048776,0.090332,0.091918,-0.049783,0.090125,0.090986,-0.050589,0.091654,0.087451,-0.050888,0.092537,0.085505,-0.051138,0.095319,0.084372,-0.050804,0.095226,0.086677,-0.050886,0.093718,0.085911,-0.050532,0.090185,0.087245,-0.050587,0.090196,0.085885,-0.050883,0.092494,0.083708,-0.050729,0.091429,0.085532,-0.050390,0.088263,0.088601,-0.049823,0.087588,0.087531,-0.050101,0.089764,0.084376,-0.050240,0.088923,0.086592,-0.049812,0.086920,0.092894,-0.050119,0.086814,0.092445,-0.049754,0.086679,0.093290,-0.050200,0.087509,0.091072,-0.050402,0.087109,0.091040,-0.050245,0.086982,0.091704,-0.049225,0.086355,0.093175,-0.047625,0.085312,0.092639,-0.047952,0.086053,0.094149,-0.049719,0.086460,0.090778,-0.048222,0.085563,0.089473,-0.048752,0.086687,0.086035,-0.049201,0.086460,0.088585,-0.045973,0.084481,0.087750,-0.046728,0.084972,0.090222,-0.050230,0.087275,0.091106,-0.049928,0.086750,0.092184,-0.050413,0.088550,0.089283,-0.050422,0.087963,0.090111,-0.050396,0.089643,0.088499,-0.050384,0.088300,0.089862,-0.050387,0.089231,0.088774,-0.050445,0.088338,0.090280,-0.050427,0.089747,0.088940,-0.050985,0.086580,0.091003,-0.051959,0.086169,0.090585,-0.051311,0.086106,0.091161,-0.052908,0.086720,0.090024,-0.055219,0.087236,0.088244,-0.053103,0.086402,0.089542,-0.050841,0.087392,0.090580,-0.050579,0.087343,0.090653,-0.051493,0.086587,0.091362,-0.051889,0.086188,0.092432,-0.053237,0.086880,0.090895,-0.052345,0.086487,0.091116,-0.050711,0.085834,0.093681,-0.051928,0.086719,0.093951,-0.051342,0.086047,0.093911,-0.050574,0.086777,0.092025,-0.050844,0.087219,0.091132,-0.049151,0.085697,0.094359,-0.050051,0.086226,0.093139,-0.047218,0.086893,0.094486,-0.045268,0.085245,0.097175,-0.047666,0.085340,0.095756,-0.040835,0.087154,0.097016,-0.036396,0.085745,0.099719,-0.041540,0.085348,0.098708,-0.023972,0.091730,0.095634,-0.023805,0.090841,0.096339,-0.024848,0.091276,0.095739,-0.023876,0.091245,0.095900,-0.023576,0.091637,0.095626,-0.023507,0.091418,0.095486,-0.023461,0.091499,0.095432,-0.023970,0.091414,0.095046,-0.023691,0.091126,0.095199,-0.023668,0.091818,0.095312,-0.023603,0.091412,0.095287,-0.023993,0.092307,0.095513,-0.024643,0.092873,0.095013,-0.024041,0.092080,0.095536,-0.024195,0.092871,0.095039,-0.024149,0.092257,0.094981,-0.023880,0.092328,0.095244,-0.024266,0.091168,0.095012,-0.024439,0.090844,0.094710,-0.023994,0.090970,0.094991,-0.025264,0.091040,0.094627,-0.025250,0.090900,0.093764,-0.024835,0.090392,0.093956,-0.024973,0.090701,0.094343,-0.024571,0.091855,0.095024,-0.024966,0.091514,0.094949,-0.024459,0.091434,0.095024,-0.024554,0.092836,0.094812,-0.024994,0.092589,0.094821,-0.024612,0.092360,0.094932,-0.030062,0.094057,0.095029,-0.027654,0.090842,0.096015,-0.030938,0.088266,0.098051,-0.034932,0.090532,0.096403,-0.030467,0.090721,0.096663,-0.038747,0.094452,0.093627,-0.044276,0.090038,0.094090,-0.039906,0.090219,0.095391,-0.046909,0.094806,0.091255,-0.046996,0.090281,0.092948,-0.050613,0.099158,0.085985,-0.049137,0.098444,0.088356,-0.050372,0.096992,0.087551,-0.046556,0.101773,0.087973,-0.042576,0.098558,0.090543,-0.046452,0.098889,0.089324,-0.033715,0.098068,0.092651,-0.038128,0.101781,0.090496,-0.038053,0.098381,0.091726,-0.027023,0.095829,0.093930,-0.029801,0.099702,0.091858,-0.029768,0.097203,0.093494,-0.025214,0.095022,0.093981,-0.025833,0.092656,0.094965,-0.025545,0.094187,0.094379,-0.026125,0.090069,0.096571,-0.026055,0.091092,0.095649,-0.022744,0.090511,0.097056,-0.023022,0.090384,0.097647,-0.024535,0.090138,0.097206,-0.023465,0.090421,0.097013,-0.025724,0.089269,0.098508,-0.028311,0.088878,0.098736,-0.026008,0.089489,0.097714,-0.031818,0.086416,0.100931,-0.031442,0.086957,0.099555,-0.028007,0.088897,0.100562,-0.032360,0.089924,0.102700,-0.032138,0.087507,0.102063,-0.023426,0.089350,0.097457,-0.024356,0.089890,0.096995,-0.024865,0.089281,0.097632,-0.022984,0.090457,0.096543,-0.024308,0.090522,0.095903,-0.024222,0.090281,0.096356,-0.022154,0.090383,0.097408,-0.022590,0.090546,0.096853,-0.051601,0.097959,0.083937,-0.051490,0.094216,0.082651,-0.052134,0.095805,0.082083,-0.051683,0.095901,0.083192,-0.049545,0.088470,0.083307,-0.047367,0.085314,0.084991,-0.048911,0.086472,0.082920,-0.048606,0.086807,0.084110,-0.043457,0.082903,0.087081,-0.046070,0.083383,0.084964,-0.045746,0.084003,0.085990,-0.036705,0.082070,0.089649,-0.040624,0.081245,0.087379,-0.040365,0.082120,0.088354,-0.030086,0.084762,0.091054,-0.032982,0.081994,0.089225,-0.033121,0.083103,0.090591,-0.050779,0.091601,0.082401,-0.051610,0.092619,0.081416,-0.051186,0.092878,0.082388,-0.050606,0.089847,0.081606,-0.050261,0.090118,0.082716,-0.024659,0.091258,0.092487,-0.023909,0.092059,0.091052,-0.022916,0.090415,0.089343,-0.023981,0.089893,0.090994,-0.023861,0.090929,0.091022,-0.034278,0.103687,0.090564,-0.030015,0.103558,0.089753,-0.026963,0.099514,0.090868,-0.030026,0.101921,0.090822,-0.043487,0.104460,0.088597,-0.039758,0.106498,0.088823,-0.038926,0.104518,0.089806,-0.049888,0.102246,0.085806,-0.047992,0.104732,0.085986,-0.047308,0.103692,0.087132,-0.051650,0.100467,0.083639,-0.051169,0.100229,0.084818,-0.052574,0.097453,0.081554,-0.052100,0.092974,0.080748,-0.052493,0.094956,0.080977,-0.050275,0.087354,0.081015,-0.048075,0.083847,0.082617,-0.049329,0.085564,0.081724,-0.044024,0.080905,0.084749,-0.046371,0.082282,0.083651,-0.036991,0.079543,0.086949,-0.040856,0.079888,0.085914,-0.029120,0.081680,0.087665,-0.032875,0.080168,0.087570,-0.051591,0.090869,0.080594,-0.051523,0.091850,0.080872,-0.051064,0.089146,0.080629,-0.021916,0.091650,0.087842,-0.022256,0.087756,0.087719,-0.021919,0.089540,0.087527,-0.034705,0.107044,0.087771,-0.025737,0.101210,0.087433,-0.029611,0.104673,0.087738,-0.044739,0.106831,0.085804,-0.040065,0.107755,0.087052,-0.050760,0.102726,0.083141,-0.048348,0.105049,0.084413,-0.052036,0.100102,0.082273,-0.024712,0.092935,0.092277,-0.024044,0.093627,0.091037,-0.023088,0.092931,0.089588,-0.023997,0.092975,0.091057,-0.022126,0.093202,0.088137,-0.022332,0.092618,0.088349,-0.024501,0.093951,0.094285,-0.024723,0.093510,0.094177,-0.024447,0.093238,0.094659,-0.025113,0.095450,0.093217,-0.024882,0.094901,0.093795,-0.025003,0.094523,0.093186,-0.025395,0.096319,0.092150,-0.025215,0.095401,0.092761,-0.023255,0.094218,0.089653,-0.024731,0.094052,0.092174,-0.024431,0.095410,0.091019,-0.024124,0.094278,0.091038,-0.024547,0.097680,0.089404,-0.025230,0.097262,0.090924,-0.022442,0.094815,0.087833,-0.022575,0.093728,0.088375,-0.023417,0.097615,0.087426,-0.025544,0.092298,0.094622,-0.025527,0.091734,0.094073,-0.025451,0.091652,0.094679,-0.025190,0.093352,0.094094,-0.025462,0.092953,0.093771,-0.025351,0.092847,0.094383,-0.025096,0.093856,0.093121,-0.025037,0.093790,0.093666,-0.025307,0.092301,0.093260,-0.025115,0.093442,0.092975,-0.025195,0.092957,0.093164,-0.025273,0.091563,0.093434,-0.025024,0.093778,0.092826,-0.024371,0.090543,0.095584,-0.026434,0.089183,0.093987,-0.028050,0.087157,0.092802,-0.028429,0.087767,0.094333,-0.025125,0.089487,0.092592,-0.025233,0.089924,0.093824,-0.025688,0.087921,0.091037,-0.023598,0.088183,0.089384,-0.024511,0.088978,0.090971,-0.026894,0.085380,0.089493,-0.027576,0.086470,0.091154,-0.023642,0.085797,0.087829,-0.022935,0.087203,0.088157,-0.025944,0.083671,0.087660,-0.021764,0.090671,0.097919,-0.021754,0.091617,0.098069,-0.023668,0.090595,0.098566,-0.022512,0.090773,0.098085,-0.025429,0.091362,0.099686,-0.025360,0.089924,0.099333,-0.021903,0.089980,0.097412,-0.020993,0.090597,0.097689,-0.021626,0.090438,0.097691,-0.030098,0.084037,0.098951,-0.028061,0.086215,0.098811,-0.030447,0.084820,0.099274,-0.025368,0.087054,0.098215,-0.023866,0.088522,0.097896,-0.025801,0.087480,0.098303,-0.022149,0.089219,0.097523,-0.022628,0.089331,0.097544,-0.039555,0.080312,0.097333,-0.035363,0.079973,0.097749,-0.032459,0.081997,0.098462,-0.035869,0.081098,0.097994,-0.056732,0.086852,0.086619,-0.057691,0.084736,0.085704,-0.054251,0.083722,0.088180,-0.055642,0.085193,0.087220,-0.053799,0.081450,0.088619,-0.050880,0.081712,0.090960,-0.052675,0.082590,0.089513,-0.048932,0.079690,0.092068,-0.046263,0.080518,0.094271,-0.048844,0.080992,0.092577,-0.042645,0.079018,0.095483,-0.043148,0.080201,0.096068,-0.058629,0.090600,0.087002,-0.060163,0.089081,0.084706,-0.057829,0.088633,0.086609,-0.020100,0.091519,0.097513,-0.019535,0.093856,0.097355,-0.022210,0.094640,0.098368,-0.020881,0.092644,0.097457,-0.020564,0.089874,0.097468,-0.018737,0.090746,0.097466,-0.020037,0.090722,0.097568,-0.028858,0.082280,0.098141,-0.027062,0.084869,0.098357,-0.029548,0.083221,0.098479,-0.023770,0.085602,0.097867,-0.022768,0.087790,0.097943,-0.024714,0.086445,0.098196,-0.020351,0.088309,0.097630,-0.021471,0.088880,0.097467,-0.040812,0.105244,0.105833,-0.048495,0.110241,0.105704,-0.051852,0.104436,0.102722,-0.044921,0.102046,0.103123,-0.046993,0.105232,0.105303,-0.058243,0.106780,0.098787,-0.057873,0.100416,0.095627,-0.052596,0.099295,0.098711,-0.055546,0.102735,0.099248,-0.058556,0.095271,0.090169,-0.062130,0.095074,0.086479,-0.056063,0.090533,0.089541,-0.058950,0.092899,0.088123,-0.062079,0.101380,0.091310,-0.055299,0.094847,0.093404,-0.058229,0.097977,0.092708,-0.027678,0.101140,0.102306,-0.032987,0.105188,0.107054,-0.033328,0.101401,0.103150,-0.033719,0.103862,0.104395,-0.023010,0.099390,0.100857,-0.025159,0.096517,0.099854,-0.024101,0.097920,0.100122,-0.028101,0.092846,0.101029,-0.032521,0.095991,0.103150,-0.038247,0.092647,0.104236,-0.032458,0.092992,0.102986,-0.025721,0.094037,0.099880,-0.025921,0.092574,0.100016,-0.043378,0.095714,0.103351,-0.047257,0.091437,0.100742,-0.043514,0.092097,0.103279,-0.050167,0.093342,0.098214,-0.051632,0.089255,0.095973,-0.049937,0.090484,0.098350,-0.053151,0.089976,0.093922,-0.053199,0.087402,0.092326,-0.052528,0.088041,0.093936,-0.054251,0.088139,0.090818,-0.053559,0.087324,0.091124,-0.028261,0.097352,0.101297,-0.025958,0.095892,0.100194,-0.038593,0.099239,0.103669,-0.032840,0.098729,0.102924,-0.047873,0.097781,0.101076,-0.043729,0.098871,0.102834,-0.052766,0.094347,0.095669,-0.050917,0.096229,0.098375,-0.054409,0.090440,0.091985,-0.053816,0.092372,0.093647,-0.054931,0.089258,0.090865,-0.016945,-0.013306,0.061779,-0.009662,-0.014139,0.076534,-0.010597,-0.009985,0.046928,-0.010532,-0.013151,0.061891,-0.026716,-0.012760,0.061143,-0.019891,-0.014521,0.076398,-0.023218,-0.008999,0.047056,-0.022144,-0.012996,0.061580,-0.036022,-0.012987,0.059566,-0.029093,-0.013716,0.075130,-0.032210,-0.009514,0.046912,-0.031396,-0.012956,0.060457,-0.043798,-0.008887,0.057523,-0.038134,-0.011040,0.072879,-0.040442,-0.010120,0.045925,-0.040296,-0.011970,0.058596,-0.046089,-0.003005,0.043968,-0.047098,0.004885,0.055272,-0.043733,-0.001430,0.070522,-0.045979,-0.003176,0.056302,-0.048115,0.024365,0.055607,-0.045447,0.015906,0.069841,-0.048275,0.013698,0.041533,-0.047737,0.014581,0.054889,-0.042079,-0.005026,0.035712,-0.039330,0.000976,0.028574,-0.045310,0.005109,0.033436,-0.044064,-0.001193,0.034715,-0.039211,0.014629,0.025942,-0.047340,0.022946,0.031313,-0.046322,0.013627,0.032067,-0.041870,0.009285,0.081783,-0.037636,0.006121,0.090023,-0.038806,-0.003715,0.083439,-0.040865,0.001978,0.082434,-0.033096,-0.002088,0.091921,-0.031383,-0.009764,0.085936,-0.035572,-0.007481,0.084669,-0.034949,-0.006513,0.036440,-0.035602,-0.002232,0.029372,-0.038867,-0.006370,0.036115,-0.027298,-0.005675,0.036863,-0.027619,-0.003223,0.029716,-0.031113,-0.006067,0.036739,-0.021715,-0.003496,0.029364,-0.011554,0.000305,0.024344,-0.021915,0.001228,0.024612,-0.020492,-0.000993,0.025718,-0.025143,0.007805,0.023630,-0.030581,0.001812,0.025545,-0.024521,-0.005623,0.094503,-0.021879,-0.011841,0.087930,-0.026618,-0.011103,0.087082,-0.026416,0.002713,0.097221,-0.020542,0.008612,0.101596,-0.018231,0.001552,0.099897,-0.022398,0.001908,0.098598,-0.032226,0.006692,0.095152,-0.026570,0.009622,0.099090,-0.029798,0.004253,0.096060,-0.013677,0.008873,0.104029,-0.010672,0.001231,0.101432,-0.015574,-0.006662,0.096324,-0.014354,0.001368,0.100835,-0.006875,0.008705,0.105154,-0.007413,-0.006645,0.096707,-0.006969,0.001086,0.101743,-0.013158,-0.012152,0.088539,-0.008390,-0.011716,0.088484,-0.017510,-0.012179,0.088382,-0.017175,-0.006490,0.035604,-0.022863,-0.005879,0.036270,-0.008782,-0.003532,0.027735,-0.010063,-0.006813,0.035217,-0.007016,-0.000321,0.024375,-0.014062,0.048331,0.039341,-0.007055,0.046834,0.030497,-0.008928,0.048690,0.052998,-0.008327,0.048711,0.039420,-0.007950,0.042961,0.025593,-0.005362,0.044141,0.026190,-0.007302,0.027025,0.106462,-0.011154,0.029315,0.104006,-0.008046,0.032169,0.101220,-0.007588,0.029408,0.104217,-0.013127,0.036128,0.095738,-0.009001,0.041861,0.086561,-0.008590,0.036163,0.096209,-0.014737,0.046265,0.070085,-0.009092,0.046382,0.070381,-0.029899,0.022392,0.098194,-0.033803,0.021531,0.094721,-0.037139,0.027367,0.091003,-0.031998,0.026053,0.096424,-0.033128,0.024240,0.095469,-0.027460,0.024784,0.099698,-0.033889,0.030841,0.094085,-0.028116,0.027766,0.098605,-0.030308,0.027142,0.097483,-0.025874,0.027748,0.022878,-0.023661,0.017415,0.022777,-0.013860,0.042380,0.025823,-0.015803,0.046172,0.030638,-0.012022,0.043591,0.026399,-0.022140,0.047621,0.039363,-0.019343,0.048161,0.052720,-0.018454,0.048045,0.039392,-0.018255,0.041664,0.085668,-0.022740,0.045957,0.069561,-0.019113,0.046079,0.069841,-0.015597,0.031947,0.100454,-0.020279,0.036149,0.094212,-0.016916,0.036117,0.095039,-0.013447,0.026944,0.105887,-0.017370,0.028875,0.102987,-0.014402,0.029121,0.103616,-0.018666,0.026403,0.104434,-0.022898,0.028405,0.100949,-0.021900,0.031805,0.098785,-0.020171,0.028641,0.102057,-0.028161,0.031526,0.096759,-0.023389,0.025762,0.102007,-0.025586,0.028150,0.099775,-0.034363,0.036327,0.089762,-0.032714,0.042036,0.081875,-0.027107,0.036150,0.092710,-0.030784,0.036254,0.091646,-0.025232,0.041625,0.084460,-0.023625,0.036136,0.093511,-0.038190,0.045061,0.065569,-0.034480,0.047039,0.051326,-0.030028,0.045975,0.068395,-0.034014,0.045851,0.067258,-0.026699,0.047718,0.052363,-0.026301,0.045948,0.069121,-0.029129,0.044192,0.030640,-0.029668,0.046573,0.039158,-0.037345,0.044772,0.037839,-0.033240,0.046002,0.038649,-0.023876,0.045142,0.030990,-0.025924,0.047056,0.039229,-0.022528,0.039293,0.025186,-0.021554,0.042728,0.026861,-0.043354,0.043566,0.048492,-0.046109,0.038074,0.034372,-0.038286,0.039398,0.028491,-0.042116,0.042301,0.036373,-0.042311,0.031604,0.026099,-0.049030,0.032367,0.043128,-0.047682,0.031486,0.032172,-0.032298,0.034775,0.024453,-0.040181,0.040281,0.077099,-0.045787,0.038985,0.060493,-0.042342,0.042988,0.063239,-0.039695,0.033828,0.085203,-0.037432,0.035716,0.087465,-0.041804,0.024582,0.082034,-0.044593,0.031994,0.072118,-0.041064,0.030173,0.083315,-0.034057,0.013953,0.094254,-0.029767,0.013209,0.097603,-0.033546,0.010031,0.094544,-0.030533,0.018163,0.097415,-0.038314,0.018005,0.089446,-0.034110,0.017965,0.094305,-0.042119,0.017248,0.081592,-0.047699,0.032692,0.057701,-0.095544,0.069938,-0.005822,-0.095390,0.064811,-0.003788,-0.095188,0.068700,-0.003796,-0.094786,0.073406,-0.005157,-0.095391,0.069262,-0.004855,-0.096842,0.085671,-0.006021,-0.097191,0.083748,-0.008159,-0.096339,0.086777,-0.007030,-0.096045,0.088664,-0.005147,-0.096606,0.086410,-0.006844,-0.096244,0.083924,-0.007891,-0.097319,0.081170,-0.009035,-0.097281,0.077706,-0.009252,-0.095788,0.079966,-0.008089,-0.096849,0.080778,-0.008753,-0.095473,0.075035,-0.007436,-0.094340,0.078179,-0.006017,-0.094072,0.082552,-0.006014,-0.094842,0.079048,-0.007174,-0.094184,0.086054,-0.005418,-0.094621,0.088530,-0.004746,-0.095479,0.086600,-0.006506,-0.097746,0.079875,-0.008220,-0.097313,0.077739,-0.009330,-0.097497,0.080664,-0.008861,-0.097881,0.075728,-0.007401,-0.097838,0.082382,-0.006624,-0.098950,0.079112,-0.007074,-0.098167,0.079324,-0.007317,-0.099083,0.076523,-0.012033,-0.100092,0.080893,-0.010680,-0.099000,0.085462,-0.011016,-0.097309,0.081885,-0.012388,-0.099137,0.081472,-0.011783,-0.100356,0.083691,-0.008896,-0.099867,0.085529,-0.006659,-0.099425,0.088795,-0.005937,-0.099756,0.087490,-0.008650,-0.100039,0.086434,-0.007679,-0.098221,0.071389,-0.006354,-0.099756,0.075442,-0.007615,-0.099539,0.071225,-0.007657,-0.098128,0.066783,-0.005643,-0.099051,0.071246,-0.006872,-0.100334,0.075967,-0.009738,-0.099318,0.071342,-0.010018,-0.098745,0.066541,-0.007482,-0.099634,0.071266,-0.008813,-0.099709,0.082354,-0.006915,-0.100527,0.079795,-0.008586,-0.099900,0.079303,-0.007589,-0.100456,0.080337,-0.009663,-0.098267,0.091430,-0.007723,-0.096570,0.089331,-0.009920,-0.098730,0.088578,-0.009564,-0.098601,0.092489,-0.004765,-0.096352,0.095913,-0.002361,-0.094945,0.094678,-0.005157,-0.097415,0.093959,-0.005357,-0.098358,0.089665,-0.002924,-0.097691,0.092739,-0.001455,-0.098591,0.091013,-0.003973,-0.092102,0.091057,0.001730,-0.091647,0.092375,0.003486,-0.092745,0.092935,0.001495,-0.093197,0.091140,-0.000724,-0.092385,0.091924,0.001457,-0.094554,0.091866,-0.000733,-0.091685,0.093100,0.004801,-0.093281,0.092125,0.002740,-0.093206,0.092507,0.002149,-0.092315,0.092084,0.005825,-0.094303,0.090862,0.002831,-0.094792,0.089987,0.000279,-0.093618,0.091235,0.002921,-0.096429,0.088249,-0.001693,-0.096503,0.086920,-0.003576,-0.095560,0.089571,-0.002424,-0.095785,0.088614,-0.001812,-0.096416,0.089966,-0.000064,-0.093918,0.092563,0.005692,-0.096052,0.092403,0.002294,-0.095150,0.091327,0.002619,-0.098334,0.086876,-0.003887,-0.097413,0.088649,-0.002082,-0.098125,0.084588,-0.005082,-0.099164,0.084843,-0.005613,-0.097158,0.084919,-0.005265,-0.094545,0.090537,-0.003381,-0.095530,0.090567,-0.003278,-0.093150,0.089300,-0.002073,-0.093858,0.090019,-0.002860,-0.092906,0.087307,-0.002417,-0.092346,0.089096,0.000092,-0.092759,0.088657,-0.001448,-0.092852,0.084361,-0.002775,-0.093259,0.085293,-0.004167,-0.093728,0.076639,-0.002969,-0.093196,0.080685,-0.003319,-0.094048,0.077385,-0.004627,-0.092572,0.082246,0.000352,-0.092063,0.084981,0.000946,-0.092581,0.083193,-0.001332,-0.095246,0.076784,-0.011893,-0.094403,0.085524,-0.010126,-0.093110,0.080959,-0.009329,-0.094953,0.081609,-0.011296,-0.091113,0.071479,-0.007203,-0.092745,0.067002,-0.007458,-0.093491,0.071605,-0.009869,-0.092405,0.076053,-0.007923,-0.092610,0.071556,-0.008062,-0.091847,0.062538,-0.006195,-0.091888,0.057283,-0.004479,-0.093161,0.061690,-0.007347,-0.092452,0.062131,-0.006500,-0.092466,0.051245,0.003745,-0.093396,0.054255,0.001401,-0.094751,0.057920,-0.001484,-0.094259,0.053600,0.001032,-0.093831,0.054066,0.001147,-0.088256,0.095492,0.003336,-0.091329,0.095983,-0.001092,-0.092924,0.097905,0.001226,-0.089365,0.097781,0.005313,-0.090419,0.097223,0.001999,-0.090569,0.093069,0.006011,-0.088784,0.092726,0.008404,-0.089674,0.092986,0.008390,-0.090383,0.093405,0.007136,-0.089904,0.092502,0.008901,-0.087964,0.092232,0.010756,-0.088966,0.092742,0.009192,-0.090818,0.047892,0.006676,-0.092899,0.049419,0.004032,-0.092053,0.045130,0.006831,-0.090775,0.044252,0.009501,-0.091391,0.046469,0.006903,-0.090334,0.053784,0.009140,-0.089110,0.051681,0.009897,-0.087847,0.052166,0.012848,-0.087661,0.054313,0.011448,-0.088587,0.052958,0.010890,-0.086136,0.094338,0.007336,-0.085814,0.091480,0.006157,-0.087504,0.092049,0.002409,-0.086814,0.093301,0.004892,-0.085972,0.052659,0.015366,-0.087730,0.048446,0.013031,-0.086055,0.049089,0.016396,-0.087277,0.050774,0.014768,-0.085657,0.089260,0.016834,-0.083809,0.087354,0.018599,-0.084386,0.091227,0.017072,-0.086378,0.092820,0.015518,-0.084970,0.090354,0.017093,-0.086471,0.091111,0.010528,-0.084754,0.088706,0.011797,-0.084161,0.088124,0.012363,-0.085299,0.090733,0.011730,-0.085111,0.089876,0.011687,-0.083558,0.086763,0.012409,-0.082410,0.084788,0.013011,-0.083044,0.086301,0.013281,-0.083189,0.086463,0.012707,-0.081784,0.082090,0.014782,-0.082463,0.084096,0.014387,-0.081610,0.082087,0.014486,-0.082015,0.082660,0.014533,-0.081092,0.080743,0.014837,-0.081879,0.081682,0.015050,-0.081560,0.081431,0.014851,-0.083988,0.055292,0.010008,-0.082113,0.054773,0.011475,-0.082131,0.055520,0.009431,-0.084481,0.055790,0.007248,-0.083414,0.054942,0.009487,-0.083498,0.093138,0.015814,-0.084821,0.094054,0.015356,-0.083822,0.092070,0.016616,-0.080230,0.054342,0.014389,-0.080358,0.054129,0.013043,-0.081526,0.055422,0.013554,-0.081033,0.054722,0.013094,-0.078016,0.067020,0.017195,-0.077924,0.067981,0.017009,-0.076706,0.067611,0.017041,-0.077687,0.067676,0.017047,-0.079925,0.073751,0.011559,-0.080468,0.071918,0.010434,-0.081054,0.071686,0.011422,-0.080176,0.074034,0.012773,-0.080349,0.072690,0.011473,-0.080233,0.079481,0.014295,-0.080414,0.079075,0.013747,-0.080095,0.078381,0.012435,-0.079816,0.078474,0.013685,-0.080051,0.078772,0.013701,-0.080770,0.080489,0.014514,-0.080632,0.080030,0.014614,-0.080587,0.079946,0.014532,-0.080516,0.079892,0.014689,-0.080730,0.080097,0.014764,-0.079750,0.077600,0.013723,-0.079984,0.078740,0.014353,-0.079692,0.077289,0.012660,-0.079735,0.078060,0.013684,-0.080343,0.078893,0.014659,-0.080701,0.079784,0.014914,-0.080284,0.079362,0.014645,-0.080200,0.076273,0.013891,-0.080250,0.077845,0.014430,-0.079688,0.075922,0.012817,-0.079888,0.077044,0.013804,-0.080897,0.079190,0.015028,-0.081199,0.078089,0.014939,-0.080555,0.078533,0.014817,-0.084262,0.080328,0.017128,-0.083934,0.079062,0.015729,-0.083479,0.076987,0.016315,-0.083019,0.078216,0.018164,-0.083911,0.078543,0.016807,-0.085369,0.084962,0.016977,-0.084994,0.082227,0.016234,-0.083795,0.082994,0.018420,-0.084669,0.082461,0.017264,-0.084607,0.095267,0.013690,-0.086912,0.097134,0.011341,-0.086981,0.095704,0.013725,-0.085760,0.095836,0.013741,-0.089813,0.096813,0.011405,-0.088731,0.093980,0.013540,-0.088005,0.095014,0.013680,-0.086587,0.096373,0.009012,-0.090133,0.098396,0.008348,-0.088164,0.097781,0.008439,-0.092942,0.093784,0.008803,-0.091019,0.094329,0.011384,-0.092781,0.096730,0.008562,-0.094881,0.095177,0.005284,-0.093074,0.095294,0.008680,-0.096200,0.095754,0.001423,-0.096276,0.093953,0.001825,-0.093671,0.098034,0.004914,-0.095150,0.097335,0.001124,-0.091809,0.097908,0.008430,-0.089196,0.091412,0.013157,-0.087500,0.090719,0.015056,-0.089181,0.092708,0.013401,-0.082332,0.079826,0.015219,-0.081869,0.080847,0.015204,-0.081347,0.079929,0.015146,-0.083099,0.082589,0.015168,-0.082276,0.081638,0.015070,-0.085519,0.084845,0.014741,-0.085524,0.083852,0.015434,-0.086526,0.086732,0.015462,-0.087340,0.088089,0.013994,-0.086291,0.085702,0.014886,-0.084476,0.082795,0.015247,-0.084338,0.085263,0.014633,-0.084270,0.083869,0.015013,-0.089089,0.091112,0.010549,-0.091464,0.091874,0.008500,-0.090686,0.091861,0.008433,-0.090562,0.091566,0.011094,-0.092255,0.092573,0.008682,-0.084540,0.088558,0.013145,-0.086781,0.090296,0.012148,-0.085952,0.090788,0.012110,-0.085846,0.087871,0.013314,-0.083815,0.086258,0.014202,-0.084561,0.086379,0.014165,-0.083272,0.086267,0.013868,-0.088058,0.089565,0.012265,-0.087489,0.089683,0.012095,-0.088779,0.090236,0.012639,-0.086294,0.087949,0.016199,-0.084027,0.080809,0.015467,-0.084842,0.082295,0.015539,-0.082666,0.078467,0.015051,-0.083314,0.079524,0.015240,-0.082862,0.076708,0.014887,-0.082683,0.074431,0.014587,-0.082703,0.074480,0.016362,-0.083089,0.075616,0.015526,-0.081535,0.074445,0.013497,-0.081957,0.071875,0.012738,-0.082036,0.071702,0.014462,-0.082232,0.073277,0.013639,-0.081467,0.076485,0.014475,-0.082098,0.077515,0.014816,-0.080709,0.075368,0.013827,-0.081585,0.069402,0.010075,-0.081872,0.068943,0.011605,-0.081727,0.070499,0.011536,-0.086222,0.061003,0.002733,-0.084943,0.058308,0.004798,-0.083328,0.060849,0.006126,-0.084283,0.064209,0.002895,-0.084759,0.060711,0.003867,-0.086682,0.058737,0.003915,-0.086583,0.056564,0.006139,-0.085593,0.056990,0.005368,-0.091786,0.055670,0.007941,-0.094129,0.056630,0.003648,-0.092612,0.054009,0.005421,-0.092600,0.054647,0.006839,-0.091571,0.051378,0.004602,-0.089619,0.048235,0.008241,-0.090840,0.049429,0.005955,-0.093891,0.056661,0.001100,-0.092534,0.053654,0.003377,-0.090824,0.051819,0.007187,-0.092557,0.053648,0.004284,-0.088900,0.049817,0.009497,-0.089509,0.050986,0.008882,-0.089000,0.045234,0.011677,-0.088634,0.047667,0.010648,-0.094051,0.057474,-0.000674,-0.092872,0.053996,0.002278,-0.096590,0.067210,-0.005322,-0.096683,0.072686,-0.007956,-0.097197,0.071697,-0.006660,-0.096363,0.072275,-0.007869,-0.096822,0.074921,-0.008993,-0.095635,0.066363,-0.005408,-0.095888,0.070771,-0.006753,-0.096546,0.062311,-0.003758,-0.095458,0.062245,-0.003928,-0.095883,0.062410,-0.003721,-0.094970,0.061003,-0.002757,-0.095108,0.061663,-0.003512,-0.094805,0.060050,-0.000715,-0.094879,0.060426,-0.001858,-0.095173,0.060124,0.002661,-0.095296,0.064082,-0.001377,-0.095012,0.059915,0.000773,-0.088951,0.056868,0.007937,-0.092721,0.058041,0.006583,-0.088186,0.055651,0.009873,-0.090389,0.056533,0.008284,-0.092402,0.061578,0.005309,-0.095225,0.065064,0.002939,-0.094230,0.060939,0.004521,-0.086009,0.055894,0.008775,-0.089251,0.058655,0.005689,-0.087639,0.056735,0.007080,-0.088996,0.061319,0.003198,-0.091184,0.065312,0.003388,-0.090445,0.061627,0.004616,-0.079957,0.077206,0.010908,-0.080969,0.078847,0.010124,-0.081007,0.077928,0.007500,-0.080204,0.078388,0.010192,-0.085679,0.068645,0.002203,-0.086764,0.073528,0.003621,-0.089248,0.069582,0.002242,-0.087860,0.064730,0.001558,-0.087492,0.069141,0.001908,-0.079775,0.075391,0.011383,-0.080148,0.074809,0.009319,-0.079905,0.076237,0.011277,-0.080057,0.073251,0.010282,-0.079757,0.074630,0.011494,-0.080484,0.072347,0.008508,-0.080881,0.070190,0.008679,-0.080485,0.071873,0.009448,-0.081576,0.074804,0.006084,-0.082331,0.071012,0.005206,-0.080727,0.073241,0.007466,-0.084995,0.076193,0.006217,-0.083614,0.076433,0.005198,-0.081639,0.082217,0.013906,-0.081027,0.080335,0.014138,-0.081217,0.081254,0.014324,-0.081619,0.079953,0.013617,-0.081281,0.078611,0.012829,-0.080997,0.079419,0.013749,-0.082190,0.084156,0.012644,-0.081797,0.081907,0.013400,-0.081892,0.083264,0.013312,-0.082573,0.082882,0.011320,-0.082949,0.081442,0.012023,-0.082219,0.081572,0.012827,-0.082178,0.083521,0.012033,-0.082313,0.082347,0.012064,-0.083911,0.081557,0.010968,-0.084714,0.080732,0.010670,-0.083695,0.079974,0.011995,-0.083799,0.080887,0.011590,-0.082576,0.079622,0.013003,-0.082029,0.080749,0.013298,-0.083074,0.078011,0.011911,-0.083623,0.077182,0.009416,-0.082024,0.078168,0.011097,-0.087303,0.076125,0.007890,-0.089093,0.073574,0.004695,-0.086214,0.075710,0.007235,-0.085168,0.078672,0.010752,-0.083547,0.078891,0.012122,-0.091502,0.083586,0.003591,-0.093519,0.079534,0.000971,-0.091151,0.081470,0.004908,-0.092254,0.081740,0.002601,-0.094744,0.072596,-0.001915,-0.094172,0.076513,0.002210,-0.094203,0.076424,-0.000661,-0.095609,0.068730,-0.000116,-0.092721,0.069543,0.003567,-0.093711,0.073341,0.003359,-0.095149,0.069316,0.002582,-0.095075,0.068481,-0.002312,-0.089551,0.076813,0.006465,-0.090524,0.079421,0.005712,-0.092045,0.076720,0.004525,-0.087267,0.081595,0.008127,-0.088637,0.083224,0.007405,-0.089292,0.081447,0.006686,-0.084912,0.081439,0.010001,-0.083550,0.082473,0.010525,-0.084866,0.082035,0.009639,-0.084279,0.081922,0.010331,-0.083146,0.084326,0.010650,-0.083844,0.083717,0.010020,-0.083106,0.083325,0.010649,-0.085353,0.083008,0.009144,-0.084277,0.085029,0.009849,-0.086262,0.084616,0.008849,-0.084841,0.084128,0.009451,-0.083345,0.086040,0.011992,-0.085076,0.087807,0.010928,-0.084159,0.087320,0.011879,-0.083141,0.085250,0.011310,-0.082639,0.084825,0.012017,-0.084802,0.086488,0.010238,-0.083735,0.085332,0.010499,-0.091518,0.087963,0.003143,-0.091111,0.090830,0.004439,-0.091728,0.089851,0.002357,-0.089511,0.091766,0.007292,-0.090788,0.092224,0.005421,-0.087424,0.089633,0.009359,-0.088021,0.091649,0.009083,-0.090260,0.085462,0.006162,-0.091542,0.085598,0.003650,-0.087490,0.086899,0.008643,-0.086273,0.087806,0.009837,-0.088218,0.085050,0.007892,-0.086036,0.081123,0.009079,-0.085780,0.081869,0.008965,-0.086422,0.079784,0.009382,-0.085567,0.080808,0.009723,-0.087317,0.077948,0.008733,-0.090720,0.069570,0.003066,-0.087621,0.061128,0.002449,-0.082262,0.067912,0.005720,-0.083709,0.068069,0.003359,-0.081958,0.067196,0.008739,-0.081629,0.068508,0.008174,-0.081208,0.065121,0.009718,-0.080464,0.068674,0.013061,-0.081232,0.067246,0.010862,-0.077603,0.068217,0.016686,-0.077897,0.068454,0.016409,-0.077490,0.068089,0.015752,-0.076448,0.068010,0.015751,-0.077352,0.068300,0.016258,-0.078232,0.068303,0.016966,-0.078643,0.068345,0.017053,-0.078340,0.068576,0.016664,-0.078403,0.068497,0.016922,-0.077979,0.068252,0.016876,-0.078472,0.068864,0.016266,-0.078047,0.068559,0.016014,-0.078281,0.068680,0.016385,-0.078514,0.068346,0.015150,-0.078195,0.066632,0.014244,-0.078035,0.068022,0.015309,-0.079694,0.041555,0.023085,-0.078586,0.040965,0.023699,-0.078606,0.043486,0.023812,-0.079954,0.043371,0.022694,-0.079126,0.042368,0.023476,-0.080996,0.042159,0.021940,-0.080512,0.045328,0.021036,-0.082214,0.043363,0.020057,-0.080984,0.043599,0.021548,-0.079676,0.039878,0.022954,-0.081536,0.040092,0.021564,-0.080481,0.040859,0.022454,-0.081613,0.037546,0.021281,-0.083544,0.041011,0.019456,-0.083782,0.037770,0.019725,-0.082730,0.039107,0.020566,-0.083904,0.045288,0.017647,-0.085612,0.041881,0.016881,-0.083801,0.042902,0.018360,-0.081738,0.047914,0.018993,-0.083851,0.051212,0.017366,-0.083942,0.048370,0.017768,-0.079398,0.047509,0.022020,-0.080192,0.049632,0.020232,-0.080146,0.047430,0.020438,-0.078309,0.049637,0.023795,-0.078907,0.049667,0.022758,-0.078658,0.046734,0.023701,-0.078766,0.048263,0.023116,-0.076981,0.042677,0.024367,-0.077681,0.047083,0.024904,-0.078077,0.044930,0.024357,-0.070722,0.063738,0.012612,-0.071967,0.061545,0.012151,-0.070408,0.060266,0.011189,-0.069536,0.062315,0.012256,-0.070575,0.061957,0.011809,-0.068279,0.059552,0.013973,-0.068480,0.060809,0.015348,-0.068305,0.061915,0.014682,-0.068442,0.060218,0.013186,-0.068178,0.060649,0.014120,-0.069860,0.065555,0.013421,-0.070977,0.066578,0.013799,-0.072335,0.065159,0.013396,-0.070856,0.065338,0.013273,-0.074532,0.066675,0.014465,-0.076539,0.064816,0.013824,-0.074228,0.062999,0.012910,-0.074399,0.065017,0.013643,-0.072545,0.067361,0.014751,-0.074653,0.067913,0.016030,-0.074602,0.067658,0.015147,-0.069908,0.066810,0.014346,-0.070992,0.067488,0.015181,-0.070998,0.067254,0.014496,-0.069074,0.066070,0.014801,-0.069140,0.064391,0.013841,-0.069366,0.065779,0.014125,-0.069846,0.065899,0.016368,-0.069942,0.066889,0.015790,-0.068800,0.064854,0.015556,-0.069186,0.066069,0.015631,-0.069074,0.063399,0.016388,-0.068662,0.063113,0.014290,-0.068549,0.063380,0.015243,-0.068847,0.061035,0.012741,-0.068978,0.062706,0.013307,-0.072942,0.057576,0.013579,-0.073936,0.056751,0.015656,-0.072334,0.057395,0.014777,-0.070708,0.057545,0.012986,-0.072558,0.057244,0.014148,-0.073887,0.056944,0.016796,-0.072891,0.058445,0.016297,-0.070575,0.058295,0.014554,-0.072445,0.057723,0.015599,-0.075227,0.056078,0.016134,-0.075209,0.055688,0.017481,-0.074626,0.056243,0.016819,-0.076083,0.053933,0.016854,-0.076478,0.054062,0.018211,-0.076042,0.056269,0.018383,-0.075835,0.054885,0.017934,-0.079276,0.053196,0.014437,-0.078063,0.053705,0.014323,-0.079630,0.055017,0.012186,-0.079301,0.053728,0.013401,-0.079086,0.058262,0.012306,-0.081812,0.058924,0.009479,-0.080669,0.056756,0.010696,-0.079954,0.063406,0.011841,-0.081962,0.061978,0.009284,-0.078114,0.061784,0.012955,-0.078235,0.064315,0.013222,-0.076042,0.060648,0.013390,-0.073671,0.059581,0.012624,-0.073946,0.061142,0.012646,-0.076889,0.057878,0.014212,-0.077658,0.059700,0.013386,-0.076875,0.052327,0.015909,-0.076632,0.055250,0.015413,-0.076838,0.053676,0.015555,-0.075011,0.057688,0.014398,-0.075986,0.056653,0.015276,-0.071511,0.058657,0.011737,-0.073347,0.058354,0.012990,-0.069815,0.058045,0.011634,-0.069206,0.059332,0.011473,-0.070182,0.058944,0.011252,-0.068794,0.058704,0.012278,-0.068672,0.059716,0.012339,-0.069167,0.058303,0.013207,-0.069450,0.057968,0.012403,-0.069299,0.059634,0.014998,-0.069187,0.058883,0.014087,-0.071253,0.060169,0.016204,-0.069945,0.061828,0.016543,-0.069578,0.060628,0.015867,-0.072175,0.062791,0.017398,-0.070725,0.064567,0.016909,-0.070346,0.063180,0.016906,-0.077852,0.051143,0.024844,-0.076957,0.049354,0.026246,-0.077694,0.054446,0.025917,-0.077535,0.050326,0.025532,-0.082042,0.064303,0.020951,-0.082542,0.065457,0.020142,-0.082805,0.063564,0.019463,-0.081836,0.061853,0.020666,-0.082548,0.063759,0.020216,-0.080943,0.065255,0.021869,-0.081672,0.066210,0.021065,-0.081640,0.065284,0.021269,-0.080658,0.070608,0.019903,-0.081112,0.068199,0.020652,-0.080243,0.068529,0.022089,-0.080283,0.073130,0.021503,-0.080446,0.070146,0.021090,-0.078961,0.069154,0.016819,-0.078902,0.069419,0.015188,-0.078635,0.068996,0.015871,-0.080836,0.071867,0.016268,-0.080300,0.070447,0.014812,-0.080100,0.071979,0.018330,-0.081844,0.075295,0.018410,-0.081552,0.073317,0.017328,-0.079622,0.066899,0.016997,-0.080004,0.068214,0.017322,-0.079215,0.068301,0.017199,-0.081419,0.066152,0.017243,-0.081559,0.067473,0.017971,-0.080565,0.069134,0.018081,-0.080842,0.067825,0.017529,-0.082758,0.065675,0.018493,-0.082045,0.067168,0.019435,-0.081183,0.068628,0.018902,-0.081984,0.067318,0.018624,-0.080627,0.070122,0.018924,-0.081922,0.066873,0.020337,-0.082423,0.063658,0.018054,-0.082076,0.061378,0.019516,-0.082773,0.063527,0.018749,-0.077437,0.052942,0.019110,-0.077456,0.054762,0.018796,-0.076933,0.052338,0.017874,-0.077000,0.053407,0.018586,-0.077032,0.065632,0.017712,-0.078547,0.063560,0.017896,-0.079343,0.065350,0.017052,-0.078439,0.065548,0.017280,-0.077605,0.057113,0.018382,-0.077736,0.059662,0.018372,-0.075441,0.058765,0.017981,-0.076794,0.057927,0.018415,-0.074070,0.060936,0.017532,-0.073444,0.059605,0.016936,-0.074881,0.064164,0.017965,-0.076763,0.062039,0.018304,-0.074558,0.062429,0.017916,-0.071157,0.066624,0.016385,-0.072769,0.065623,0.017066,-0.071007,0.065750,0.016692,-0.072723,0.067286,0.016080,-0.071105,0.067159,0.015893,-0.074965,0.066718,0.017007,-0.074773,0.067489,0.016674,-0.075022,0.065616,0.017483,-0.079232,0.060833,0.018260,-0.078265,0.061464,0.018406,-0.080399,0.062471,0.017770,-0.081047,0.064360,0.017201,-0.080215,0.064883,0.017032,-0.081487,0.061557,0.018409,-0.081817,0.063922,0.017498,-0.081481,0.059285,0.019037,-0.080392,0.059768,0.018095,-0.080209,0.057342,0.018424,-0.081014,0.059427,0.018431,-0.079094,0.058252,0.017882,-0.079887,0.060243,0.018108,-0.078707,0.055882,0.018742,-0.078189,0.056420,0.018499,-0.079671,0.053803,0.016099,-0.078514,0.052507,0.016113,-0.079468,0.053470,0.015376,-0.078202,0.051757,0.017738,-0.077504,0.051890,0.016858,-0.080849,0.055118,0.015534,-0.080532,0.053885,0.017037,-0.079276,0.052502,0.017622,-0.079954,0.053905,0.016675,-0.079145,0.051317,0.019227,-0.080437,0.051939,0.018308,-0.079550,0.050771,0.021331,-0.079746,0.050844,0.019817,-0.082165,0.055240,0.015438,-0.083175,0.055913,0.012658,-0.081959,0.055756,0.014266,-0.082759,0.053831,0.016623,-0.085333,0.054949,0.013875,-0.084334,0.053590,0.015982,-0.085293,0.055700,0.011371,-0.086484,0.055248,0.011629,-0.084532,0.055727,0.010716,-0.081501,0.053882,0.017015,-0.078037,0.051676,0.019474,-0.078619,0.051500,0.018486,-0.078515,0.051773,0.023354,-0.078161,0.054490,0.024272,-0.078088,0.051701,0.024136,-0.079453,0.052626,0.022090,-0.079235,0.051215,0.022500,-0.080628,0.059568,0.021704,-0.079867,0.055926,0.022480,-0.078890,0.058321,0.023423,-0.079886,0.062334,0.022543,-0.079623,0.059043,0.022514,-0.081160,0.057573,0.020993,-0.081157,0.057634,0.019845,-0.079974,0.055620,0.019771,-0.079918,0.055114,0.020960,-0.080526,0.056282,0.020465,-0.078865,0.052931,0.020617,-0.079613,0.053849,0.021543,-0.078525,0.053990,0.019629,-0.078037,0.052711,0.019802,-0.079302,0.055568,0.019188,-0.081677,0.059693,0.020233,-0.081636,0.059480,0.019693,-0.081509,0.059687,0.020879,-0.079525,0.066026,0.023453,-0.080135,0.065636,0.022524,-0.078626,0.061490,0.024378,-0.078658,0.063449,0.025384,-0.079469,0.070873,0.024499,-0.079057,0.065464,0.024508,-0.078140,0.057943,0.025148,-0.078376,0.057858,0.024353,-0.078325,0.061129,0.026995,-0.078138,0.059146,0.025872,-0.075475,0.043167,0.025155,-0.076372,0.046752,0.028921,-0.077539,0.054985,0.028518,-0.076507,0.048352,0.027284,-0.068732,0.076992,0.077036,-0.071661,0.077962,0.071446,-0.073168,0.061928,0.067027,-0.070119,0.064373,0.075760,-0.071312,0.070167,0.073186,-0.042185,-0.007946,0.095967,-0.044474,0.004703,0.100977,-0.050516,0.013305,0.098228,-0.050480,-0.001399,0.090233,-0.047162,0.001696,0.096675,-0.036428,0.022462,0.109873,-0.037758,0.028710,0.109615,-0.041413,0.023472,0.107396,-0.038628,0.017395,0.108107,-0.038829,0.022984,0.108913,-0.054246,-0.008780,0.041270,-0.062273,0.004829,0.041317,-0.063430,0.007158,0.030108,-0.056812,-0.008464,0.030215,-0.058840,-0.000823,0.035063,-0.045960,-0.014487,0.081943,-0.059602,0.010142,0.083089,-0.055898,-0.006708,0.070819,-0.053870,-0.004136,0.081362,-0.070369,0.021097,0.044998,-0.061534,0.001081,0.055749,-0.069689,0.021015,0.060908,-0.066495,0.011461,0.050191,-0.069510,0.048312,0.075135,-0.072472,0.042966,0.063299,-0.066444,0.028467,0.076985,-0.070251,0.034538,0.069292,-0.066402,0.069132,0.082420,-0.065345,0.056892,0.084060,-0.068194,0.059946,0.079530,-0.057105,0.056096,0.093699,-0.060675,0.065616,0.089772,-0.061941,0.042085,0.087154,-0.061571,0.055424,0.088849,-0.056800,0.026335,0.093234,-0.061748,0.026516,0.085688,-0.052004,-0.013071,0.053442,-0.046957,-0.019064,0.065930,-0.054683,-0.009695,0.060787,-0.043113,-0.025726,0.055440,-0.046464,-0.023361,0.043532,-0.049392,-0.017488,0.048270,-0.033597,0.032252,0.111392,-0.032331,0.039894,0.110076,-0.037885,0.036469,0.108878,-0.035486,0.034447,0.110081,-0.024772,0.021083,0.106053,-0.024793,0.019972,0.104261,-0.025957,0.019751,0.102126,-0.025342,0.021077,0.104299,-0.025163,0.020569,0.104149,-0.023666,0.020771,0.106373,-0.023482,0.019065,0.105342,-0.025222,0.017839,0.102499,-0.024299,0.019440,0.104642,-0.026789,0.043395,0.110687,-0.026044,0.048526,0.109179,-0.031309,0.046779,0.108768,-0.029095,0.044628,0.109552,-0.022704,0.055390,0.120008,-0.022926,0.057549,0.117585,-0.023947,0.055257,0.116503,-0.023232,0.053401,0.118909,-0.023384,0.055412,0.118146,-0.023816,0.052667,0.117257,-0.022503,0.050097,0.118539,-0.021066,0.050514,0.120969,-0.022887,0.051584,0.118972,-0.016780,0.048998,0.119555,-0.019708,0.047897,0.118911,-0.017330,0.047619,0.118043,-0.015311,0.048765,0.118574,-0.017124,0.048152,0.118901,-0.016205,0.051757,0.119560,-0.016690,0.052945,0.119972,-0.016909,0.052027,0.122271,-0.017419,0.050970,0.121553,-0.016805,0.051893,0.120809,-0.015655,0.050888,0.119304,-0.017571,0.049833,0.120729,-0.014972,0.050198,0.119330,-0.016210,0.050011,0.119663,-0.019689,0.051438,0.123051,-0.018916,0.050316,0.121900,-0.014674,0.052253,0.118310,-0.014078,0.051547,0.118681,-0.015164,0.051582,0.118787,-0.014313,0.083398,0.110119,-0.013197,0.082880,0.114855,-0.011712,0.087971,0.114430,-0.013140,0.088129,0.108859,-0.013134,0.085780,0.112182,-0.010106,0.041292,0.121753,-0.011618,0.043099,0.121114,-0.013997,0.041187,0.120325,-0.012319,0.039510,0.121526,-0.012072,0.041390,0.121283,-0.009668,0.051223,0.128278,-0.010579,0.051550,0.129453,-0.011161,0.052952,0.128575,-0.009640,0.052388,0.127533,-0.010277,0.052104,0.128489,-0.012025,0.051943,0.120215,-0.011438,0.051091,0.121727,-0.010644,0.052299,0.122537,-0.010979,0.053325,0.120811,-0.011354,0.052248,0.121394,-0.013447,0.050975,0.119642,-0.012498,0.052342,0.118689,-0.013033,0.051734,0.119254,-0.016336,0.053309,0.122776,-0.016172,0.052480,0.125113,-0.017847,0.051918,0.124437,-0.016666,0.052212,0.123715,-0.018927,0.053530,0.125932,-0.021138,0.054122,0.123380,-0.019582,0.052567,0.124440,-0.016637,0.053075,0.127331,-0.016257,0.054657,0.129393,-0.018844,0.056294,0.127184,-0.017841,0.054300,0.127620,-0.014663,0.053775,0.125383,-0.014157,0.053230,0.127572,-0.015355,0.052763,0.126470,-0.007856,0.042638,0.121471,-0.008119,0.039084,0.121573,-0.008044,0.040910,0.121430,-0.007093,0.046815,0.122560,-0.006941,0.047797,0.123537,-0.008870,0.047783,0.122564,-0.007031,0.047339,0.122992,-0.006454,0.048469,0.124948,-0.008270,0.048995,0.124089,-0.006719,0.048158,0.124195,-0.012373,0.023428,0.115358,-0.014555,0.023319,0.112346,-0.012655,0.023834,0.110714,-0.010214,0.023472,0.113681,-0.012526,0.023438,0.113067,-0.007730,0.023613,0.116626,-0.007425,0.023678,0.111629,-0.007562,0.023571,0.114133,-0.008004,0.025950,0.120982,-0.010257,0.024560,0.118434,-0.008120,0.024413,0.118985,-0.012264,0.025953,0.119873,-0.014180,0.024099,0.116532,-0.012325,0.024414,0.117627,-0.026888,0.032209,0.114847,-0.023879,0.037669,0.115028,-0.025942,0.039652,0.112857,-0.029760,0.033206,0.113097,-0.026845,0.035822,0.113927,-0.020953,0.043798,0.113629,-0.021756,0.046467,0.112233,-0.023916,0.043320,0.112009,-0.021666,0.036042,0.117125,-0.018345,0.040117,0.117800,-0.019779,0.041892,0.115731,-0.020887,0.039068,0.116282,-0.016216,0.044443,0.117169,-0.017588,0.046160,0.116022,-0.018395,0.044264,0.115497,-0.015180,0.047259,0.117523,-0.020099,0.047260,0.116319,-0.017470,0.047135,0.117078,-0.010794,0.045698,0.121144,-0.012706,0.044525,0.119978,-0.009437,0.044404,0.121554,-0.011155,0.044540,0.121140,-0.008933,0.046384,0.121973,-0.010590,0.047404,0.121367,-0.012103,0.046807,0.119925,-0.010551,0.046622,0.121127,-0.013791,0.049427,0.119570,-0.013575,0.047938,0.118755,-0.012231,0.048433,0.120282,-0.013703,0.048693,0.119121,-0.012485,0.050101,0.120752,-0.013730,0.050196,0.119814,-0.010895,0.049026,0.121731,-0.010172,0.049944,0.122936,-0.011303,0.050024,0.121842,-0.010673,0.048138,0.121570,-0.013735,0.045873,0.118537,-0.013546,0.047025,0.118597,-0.015216,0.042784,0.118751,-0.014329,0.044480,0.118590,-0.016637,0.038511,0.119644,-0.016034,0.040757,0.119109,-0.010226,0.037539,0.122154,-0.008125,0.035282,0.122254,-0.008107,0.037238,0.121800,-0.014589,0.037070,0.121128,-0.012441,0.035524,0.122370,-0.012414,0.037540,0.121938,-0.010351,0.033405,0.123444,-0.008255,0.030485,0.124232,-0.008202,0.033073,0.123575,-0.014712,0.032776,0.121968,-0.012574,0.030797,0.122882,-0.012557,0.033358,0.122883,-0.016910,0.033821,0.120607,-0.019129,0.029884,0.119654,-0.016666,0.029086,0.120779,-0.016896,0.031567,0.120957,-0.019360,0.034793,0.119052,-0.016873,0.036150,0.120147,-0.021661,0.030331,0.118040,-0.024298,0.031157,0.116523,-0.021912,0.033076,0.117831,-0.028185,0.026902,0.114299,-0.025509,0.026573,0.115094,-0.026372,0.029093,0.115216,-0.029750,0.019439,0.110809,-0.028035,0.020836,0.112018,-0.030049,0.022770,0.112456,-0.032281,0.021334,0.111259,-0.030144,0.020989,0.111637,-0.033870,0.018473,0.109709,-0.033679,0.025526,0.111594,-0.034277,0.021878,0.110679,-0.030941,0.026811,0.113170,-0.032203,0.029470,0.112463,-0.027716,0.023300,0.113208,-0.029394,0.024743,0.113325,-0.025640,0.020750,0.110704,-0.026535,0.021538,0.112287,-0.026471,0.020365,0.110696,-0.026530,0.020849,0.111602,-0.025132,0.021551,0.112104,-0.025574,0.023327,0.113590,-0.026268,0.022289,0.112870,-0.024103,0.021033,0.109634,-0.024654,0.021221,0.107808,-0.024636,0.021386,0.106622,-0.023530,0.021407,0.109022,-0.024283,0.021305,0.108259,-0.024656,0.020888,0.108984,-0.024337,0.021097,0.107709,-0.024547,0.021086,0.107632,-0.024765,0.020749,0.110164,-0.024761,0.020417,0.109824,-0.025050,0.020535,0.109890,-0.023732,0.021516,0.111630,-0.024359,0.021110,0.110752,-0.021572,0.023171,0.114401,-0.019583,0.022967,0.114639,-0.018176,0.025538,0.117918,-0.020658,0.025941,0.117513,-0.019994,0.024376,0.116093,-0.016111,0.022918,0.113589,-0.018226,0.023018,0.110443,-0.016861,0.023681,0.109220,-0.016422,0.023164,0.111488,-0.017698,0.022848,0.114333,-0.016050,0.024772,0.117608,-0.015920,0.023634,0.115487,-0.020735,0.023238,0.106823,-0.019540,0.022384,0.111171,-0.021746,0.022457,0.107769,-0.020012,0.022762,0.109169,-0.025871,0.021532,0.102679,-0.024442,0.021840,0.105430,-0.025152,0.021489,0.104721,-0.022696,0.021780,0.108446,-0.024071,0.022619,0.104181,-0.023263,0.022152,0.106457,-0.020953,0.021911,0.111503,-0.019398,0.022494,0.112947,-0.022321,0.021612,0.111530,-0.022371,0.021565,0.110123,-0.023552,0.023261,0.113990,-0.022731,0.022158,0.112836,-0.023074,0.026255,0.116294,-0.024533,0.024665,0.114675,-0.021230,0.028005,0.118009,-0.014389,0.027574,0.120811,-0.016257,0.026600,0.119578,-0.010332,0.028373,0.122403,-0.012441,0.028206,0.121705,-0.008117,0.028014,0.123068,-0.038694,0.000228,0.103328,-0.039659,0.009898,0.105951,-0.044036,0.015620,0.104766,-0.042013,0.007448,0.103950,-0.035214,0.007083,0.106990,-0.034771,0.013793,0.107891,-0.037320,0.012016,0.107206,-0.014849,-0.024590,0.109477,-0.008082,-0.027721,0.104421,-0.008284,-0.021181,0.116806,-0.008247,-0.025466,0.111165,-0.008189,-0.032598,0.093501,-0.013878,-0.029118,0.097310,-0.008114,-0.029821,0.098461,-0.023936,-0.023228,0.104048,-0.018934,-0.026349,0.101077,-0.020176,-0.020224,0.111720,-0.019773,-0.023975,0.106945,-0.017835,-0.031750,0.090274,-0.022400,-0.027904,0.092639,-0.018347,-0.028555,0.095327,-0.032189,-0.024812,0.086676,-0.037163,-0.018165,0.090865,-0.039582,-0.023660,0.077146,-0.038411,-0.020972,0.083990,-0.032015,-0.019037,0.098578,-0.036149,-0.010451,0.101248,-0.036676,-0.014797,0.096881,-0.027231,-0.030052,0.084571,-0.027054,-0.024233,0.095338,-0.026953,-0.026910,0.089666,-0.028310,-0.017847,0.105723,-0.027926,-0.021674,0.101065,-0.031597,-0.010257,0.106262,-0.033792,-0.001332,0.106166,-0.035025,-0.005753,0.104125,-0.029263,-0.000941,0.109116,-0.031038,0.006318,0.108795,-0.032477,0.002689,0.107652,-0.022312,-0.005447,0.113662,-0.024771,0.000679,0.111715,-0.027080,-0.008304,0.110553,-0.025861,-0.003669,0.111254,-0.025090,0.020122,0.110420,-0.027317,0.019085,0.110590,-0.025454,0.019190,0.110895,-0.026059,0.019748,0.110604,-0.031135,0.012431,0.108824,-0.030797,0.016805,0.109393,-0.032609,0.015335,0.108662,-0.027920,0.016641,0.110150,-0.028937,0.018120,0.110175,-0.028158,0.012626,0.110377,-0.027223,0.007012,0.110977,-0.029553,0.009623,0.109840,-0.025603,0.017204,0.111332,-0.025366,0.013728,0.112292,-0.026856,0.015227,0.111052,-0.023704,0.019889,0.111463,-0.023218,0.018248,0.112577,-0.024638,0.018751,0.111469,-0.018186,0.022104,0.110411,-0.020436,0.022047,0.110885,-0.019088,0.021801,0.112973,-0.016355,0.023224,0.113658,-0.018614,0.022430,0.112208,-0.023646,0.020637,0.110478,-0.023885,0.021072,0.109258,-0.024256,0.020461,0.109995,-0.022832,0.021306,0.108621,-0.023725,0.021164,0.108014,-0.021516,0.020744,0.111956,-0.022218,0.021391,0.110707,-0.022814,0.020789,0.111150,-0.021503,0.021001,0.107975,-0.021754,0.021570,0.109626,-0.020644,0.019454,0.113868,-0.017605,0.021549,0.114891,-0.019902,0.020953,0.113303,-0.022172,0.015238,0.114652,-0.018868,0.017076,0.116870,-0.021329,0.017744,0.114599,-0.023393,0.008567,0.113364,-0.019690,0.010607,0.116069,-0.022911,0.012057,0.114179,-0.020165,0.003129,0.113669,-0.023917,0.004786,0.112369,-0.011886,0.001626,0.115726,-0.015890,0.005951,0.115680,-0.017180,-0.002041,0.115112,-0.016211,0.002130,0.114615,-0.019437,-0.010947,0.115907,-0.013743,-0.006376,0.118289,-0.018407,-0.006350,0.115896,-0.024216,-0.014909,0.111822,-0.028006,-0.013179,0.108865,-0.015108,-0.015968,0.117599,-0.020130,-0.015738,0.114773,-0.007915,-0.010185,0.120632,-0.008179,-0.015661,0.120009,-0.006118,0.048982,0.126994,-0.006316,0.049601,0.129498,-0.007734,0.049733,0.128229,-0.006131,0.049303,0.128176,-0.007736,0.049339,0.126000,-0.006233,0.048732,0.125893,-0.008865,0.050136,0.125003,-0.009826,0.051029,0.123893,-0.009342,0.050007,0.123952,-0.009209,0.052028,0.125179,-0.009674,0.053396,0.123598,-0.009924,0.052167,0.123806,-0.009112,0.051224,0.126288,-0.008633,0.053183,0.126747,-0.009114,0.052232,0.126559,-0.008810,0.050307,0.127165,-0.008723,0.050245,0.126097,-0.009182,0.050628,0.129245,-0.008948,0.050383,0.128216,-0.011720,0.054408,0.127446,-0.013642,0.053098,0.129579,-0.012579,0.053461,0.128298,-0.012908,0.053674,0.131615,-0.014791,0.055693,0.131658,-0.014585,0.054210,0.130762,-0.010527,0.051965,0.131431,-0.009780,0.052845,0.133499,-0.012484,0.054932,0.133152,-0.011423,0.053281,0.132548,-0.008334,0.050581,0.130742,-0.009738,0.051114,0.130295,-0.007024,0.050864,0.132598,-0.006576,0.049991,0.130962,-0.008244,0.054761,0.135787,-0.007569,0.052358,0.134359,-0.012023,0.057530,0.134599,-0.009242,0.061618,0.135589,-0.008894,0.058057,0.136383,-0.015223,0.059038,0.131901,-0.013915,0.056791,0.132958,-0.013241,0.063367,0.132224,-0.015730,0.064208,0.128335,-0.017774,0.060128,0.128102,-0.015844,0.061724,0.130258,-0.009035,0.074693,0.126429,-0.012254,0.071752,0.125977,-0.009148,0.071140,0.129284,-0.009054,0.072817,0.127868,-0.013052,0.068034,0.129032,-0.009411,0.067252,0.132265,-0.009289,0.069306,0.130691,-0.009383,0.064681,0.133958,-0.015636,0.019871,0.109837,-0.013033,0.023148,0.112807,-0.009867,0.020892,0.111204,-0.012937,0.017326,0.108681,-0.012784,0.020417,0.110659,-0.007149,0.023358,0.114269,-0.010468,0.023747,0.116232,-0.007564,0.023190,0.118164,-0.007385,0.023612,0.116773,-0.011250,0.021948,0.118728,-0.007838,0.019522,0.120895,-0.007754,0.021810,0.119480,-0.013929,0.023085,0.116077,-0.014876,0.019758,0.118105,-0.014608,0.021999,0.116830,-0.013482,0.023643,0.115148,-0.006852,0.017895,0.109444,-0.006915,0.021228,0.111438,-0.020493,0.018891,0.107579,-0.023228,0.016474,0.104088,-0.022240,0.018850,0.106389,-0.018838,0.016340,0.106593,-0.018288,0.019250,0.108817,-0.007101,-0.002002,0.118519,-0.007556,-0.005645,0.119940,-0.006697,0.005122,0.116141,-0.006714,0.001452,0.116791,-0.011767,0.008861,0.117962,-0.016145,0.013218,0.119041,-0.016064,0.009478,0.117520,-0.012153,0.016464,0.121044,-0.015794,0.016677,0.119379,-0.007327,0.012354,0.119389,-0.007797,0.016114,0.121602,-0.006997,0.008645,0.117443,-0.007357,0.045368,0.121697,-0.007603,0.044154,0.121509,-0.007179,0.046205,0.122136,-0.066447,0.157905,0.063958,-0.072362,0.159672,0.048276,-0.071372,0.143155,0.064632,-0.072381,0.151577,0.056300,-0.060210,-0.012569,-0.028458,-0.058040,-0.018412,-0.033387,-0.061628,-0.031791,-0.027179,-0.063453,-0.024587,-0.021780,-0.060868,-0.021594,-0.027661,-0.059092,0.185930,0.032401,-0.064073,0.180483,0.035089,-0.059539,0.179270,0.048246,-0.053571,0.186148,0.044937,-0.058934,0.183221,0.040853,-0.042370,0.200921,-0.004480,-0.046361,0.196444,-0.020864,-0.056423,0.191703,-0.009890,-0.049433,0.196933,0.008818,-0.049111,0.196830,-0.007077,-0.065213,0.182584,0.022277,-0.054973,0.191342,0.022439,-0.062230,0.186698,0.007472,-0.060451,0.187026,0.021491,-0.070850,0.178180,-0.006463,-0.064479,0.181500,-0.027856,-0.063935,0.185273,-0.009444,-0.048389,0.192726,0.037620,-0.042411,0.199097,0.026046,-0.048981,0.195442,0.024135,-0.035021,0.198920,0.042238,-0.026414,0.205116,0.029508,-0.034997,0.204559,0.011349,-0.035056,0.202333,0.027846,-0.016024,0.203415,0.044743,-0.015858,0.209593,0.013404,-0.016188,0.206904,0.030667,-0.016519,0.181728,0.086076,-0.016234,0.193795,0.068613,-0.026421,0.186363,0.075722,-0.016368,0.187912,0.077870,-0.026216,0.197165,0.055850,-0.016054,0.199016,0.057450,-0.071363,0.033934,0.014330,-0.069995,0.027444,0.006044,-0.067554,0.019125,0.013006,-0.070536,0.028554,0.018970,-0.069398,0.027498,0.013063,-0.074271,0.035959,0.027272,-0.073513,0.036485,0.022672,-0.070381,0.024018,0.024885,-0.072230,0.031039,0.023432,-0.070742,0.021870,0.032710,-0.065805,0.011891,0.020904,-0.067420,0.015818,0.027056,-0.067794,-0.007866,-0.009953,-0.067008,-0.021774,-0.002804,-0.066290,-0.011662,0.004748,-0.068433,0.000836,-0.002505,-0.067682,-0.009862,-0.002707,-0.062737,-0.004341,-0.023896,-0.065715,-0.016506,-0.016365,-0.066604,0.003945,-0.017763,-0.066196,-0.005861,-0.017103,-0.062732,0.014156,-0.026542,-0.069116,0.011510,-0.010345,-0.068408,0.021580,-0.019169,-0.067334,0.012920,-0.018505,-0.067643,0.009537,0.005301,-0.069664,0.019171,-0.002429,-0.069011,0.010217,-0.002501,-0.062896,-0.027208,0.011324,-0.059578,-0.015519,0.019845,-0.065251,-0.000631,0.013467,-0.063817,-0.013279,0.012509,-0.066412,0.009998,0.013349,-0.074444,0.037826,0.000971,-0.071677,0.029773,-0.010220,-0.071384,0.028447,-0.001624,-0.065852,0.031126,-0.029091,-0.071654,0.039527,-0.020346,-0.069827,0.030433,-0.019652,-0.085575,0.052526,-0.001960,-0.086756,0.055879,-0.004353,-0.084726,0.059220,-0.004914,-0.083697,0.053365,-0.001979,-0.085083,0.055202,-0.003441,-0.081731,0.044760,0.003145,-0.083422,0.045519,0.003859,-0.084685,0.049014,0.001309,-0.082942,0.048253,0.000867,-0.083243,0.046971,0.002488,-0.087478,0.052634,-0.002602,-0.086889,0.049097,0.000972,-0.086257,0.050681,-0.000612,-0.089646,0.054906,-0.003756,-0.088592,0.059550,-0.005830,-0.088223,0.055607,-0.004446,-0.088959,0.050548,-0.000218,-0.090626,0.053332,-0.002406,-0.091043,0.058455,-0.004883,-0.090410,0.054158,-0.002885,-0.085131,0.045338,0.004552,-0.087314,0.045982,0.003672,-0.087155,0.047588,0.002530,-0.077915,0.040825,0.012945,-0.078699,0.039638,0.014235,-0.080208,0.041023,0.011028,-0.078724,0.042036,0.010332,-0.078927,0.040904,0.012273,-0.081276,0.039450,0.012142,-0.083020,0.041279,0.009237,-0.082514,0.042684,0.007485,-0.081655,0.041295,0.009907,-0.078277,0.043804,0.006840,-0.079243,0.044845,0.004377,-0.079734,0.047022,0.001366,-0.077836,0.045414,0.004051,-0.078709,0.045436,0.004157,-0.075560,0.041008,0.008071,-0.077428,0.047027,-0.001271,-0.076172,0.043623,0.003301,-0.079206,0.043312,0.007201,-0.077595,0.042013,0.010417,-0.078297,0.042877,0.008821,-0.077104,0.039304,0.014959,-0.076478,0.040218,0.012434,-0.077238,0.040595,0.012934,-0.077392,0.037585,0.016789,-0.079454,0.037742,0.014697,-0.078087,0.038437,0.015381,-0.082426,0.038500,0.011607,-0.080762,0.036313,0.014363,-0.081083,0.037596,0.013388,-0.089181,0.048199,0.000836,-0.091181,0.051498,-0.002841,-0.090808,0.052453,-0.002365,-0.088027,0.043281,0.003965,-0.086759,0.039312,0.006838,-0.089885,0.041944,0.004448,-0.090591,0.045976,0.000468,-0.088816,0.042394,0.004115,-0.085650,0.041975,0.006679,-0.087618,0.044510,0.003985,-0.093859,0.050098,-0.002995,-0.093595,0.055820,-0.005993,-0.092465,0.050479,-0.003201,-0.096111,0.061100,-0.008143,-0.094819,0.066558,-0.009885,-0.094507,0.061235,-0.008237,-0.097058,0.071548,-0.011768,-0.095217,0.071651,-0.011275,-0.097725,0.066369,-0.009529,-0.098459,0.071422,-0.011162,-0.097655,0.061338,-0.006626,-0.096157,0.055652,-0.005133,-0.097084,0.061167,-0.007514,-0.093469,0.047423,0.003130,-0.091892,0.042814,0.005841,-0.091205,0.040641,0.008894,-0.092285,0.043897,0.006498,-0.097807,0.061849,-0.004775,-0.096787,0.056449,-0.003234,-0.097950,0.061589,-0.005609,-0.096004,0.057358,-0.001905,-0.097315,0.062091,-0.004136,-0.095336,0.052254,0.000268,-0.094798,0.052988,0.000795,-0.095540,0.050652,-0.001561,-0.095671,0.051415,-0.000595,-0.092910,0.045699,0.001453,-0.094902,0.050189,-0.002376,-0.088971,0.038745,0.007648,-0.090993,0.042099,0.005081,-0.084216,0.035152,0.017609,-0.081876,0.035587,0.019859,-0.085896,0.037871,0.017702,-0.084045,0.036066,0.018856,-0.082682,0.035731,0.012752,-0.078330,0.035817,0.017403,-0.080753,0.034477,0.015966,-0.080527,0.035311,0.015380,-0.077318,0.039644,0.023434,-0.076076,0.038163,0.022107,-0.075097,0.040951,0.022611,-0.076018,0.040219,0.023367,-0.079079,0.036191,0.020836,-0.079234,0.037969,0.022389,-0.080359,0.036574,0.021153,-0.078594,0.039478,0.023256,-0.090421,0.040393,0.011658,-0.088546,0.041536,0.014144,-0.089958,0.042779,0.011877,-0.087509,0.037243,0.015981,-0.087131,0.039817,0.016157,-0.087848,0.036387,0.013685,-0.088069,0.036837,0.010788,-0.089667,0.038203,0.011238,-0.083423,0.034322,0.015979,-0.085752,0.035296,0.015843,-0.084123,0.034683,0.013342,-0.079658,0.034646,0.018697,-0.081725,0.034092,0.016194,-0.085466,0.036281,0.010159,-0.086618,0.036211,0.010456,-0.084282,0.038581,0.009540,-0.084721,0.037106,0.009844,-0.083807,0.040236,0.009331,-0.081508,0.043169,0.005637,-0.083218,0.043972,0.005410,-0.080103,0.043794,0.005104,-0.080731,0.051423,-0.002426,-0.082152,0.049550,-0.000993,-0.080776,0.058362,-0.006940,-0.076941,0.050304,-0.011593,-0.079037,0.052450,-0.004305,-0.075502,0.055898,-0.024841,-0.069323,0.047114,-0.032361,-0.073384,0.047844,-0.022489,-0.066756,0.054515,-0.044456,-0.074373,0.064487,-0.036916,-0.072671,0.075028,-0.049583,-0.062855,0.061879,-0.057551,-0.069506,0.063743,-0.047043,-0.084975,0.076175,-0.003672,-0.084745,0.080888,-0.001030,-0.083497,0.083679,-0.000062,-0.083715,0.079757,-0.005062,-0.084095,0.080098,-0.002449,-0.087035,0.064209,-0.006154,-0.085321,0.069565,-0.005092,-0.083144,0.064661,-0.005140,-0.085057,0.064426,-0.005694,-0.082874,0.072583,-0.009503,-0.080324,0.065329,-0.015539,-0.081887,0.065100,-0.008205,-0.080368,0.074495,-0.027560,-0.077920,0.064568,-0.026673,-0.082912,0.082506,-0.017579,-0.083966,0.097461,-0.023109,-0.080908,0.089157,-0.038540,-0.081914,0.085825,-0.027196,-0.083659,0.088051,-0.007219,-0.083508,0.080587,-0.009969,-0.086372,0.076057,-0.003844,-0.087446,0.074782,-0.004829,-0.087837,0.078213,-0.004150,-0.086065,0.079726,-0.002388,-0.086977,0.077377,-0.003824,-0.088654,0.071529,-0.005969,-0.090660,0.067398,-0.006480,-0.089368,0.075395,-0.005936,-0.089781,0.071472,-0.006538,-0.090011,0.063512,-0.006144,-0.091064,0.063047,-0.006074,-0.088223,0.067960,-0.005827,-0.088631,0.063876,-0.006307,-0.086772,0.072117,-0.004895,-0.087730,0.071647,-0.005327,-0.085822,0.073545,-0.004312,-0.083885,0.086407,0.005292,-0.083613,0.085041,0.003127,-0.084862,0.083587,0.001705,-0.085264,0.085882,0.003682,-0.084436,0.085118,0.003705,-0.090640,0.079457,-0.005599,-0.091007,0.083491,-0.005640,-0.092031,0.080233,-0.007199,-0.088064,0.081456,-0.002973,-0.089006,0.078822,-0.004740,-0.087438,0.088442,0.002001,-0.088770,0.088505,-0.001959,-0.089623,0.092762,-0.001979,-0.088082,0.090516,0.000106,-0.092975,0.091885,-0.006414,-0.092070,0.094277,-0.003939,-0.091311,0.087629,-0.006137,-0.093803,0.088905,-0.008452,-0.088740,0.084594,-0.001951,-0.089733,0.086089,-0.003851,-0.086765,0.085332,0.001131,-0.085705,0.088444,0.005069,-0.086327,0.086971,0.003152,-0.086075,0.082668,-0.000465,-0.087198,0.083538,-0.000982,-0.085299,0.081822,-0.000494,-0.083166,0.087300,0.004801,-0.083121,0.087744,0.002204,-0.083196,0.085865,0.002591,-0.083324,0.091138,0.000421,-0.082970,0.091375,0.004487,-0.083241,0.089868,0.002497,-0.086635,0.141289,-0.010434,-0.082875,0.147871,-0.030637,-0.082080,0.126691,-0.041852,-0.086746,0.119014,-0.021511,-0.085921,0.133972,-0.026271,-0.080517,0.077145,0.022854,-0.080243,0.079187,0.025429,-0.080373,0.077833,0.023988,-0.081137,0.077528,0.020450,-0.080809,0.077200,0.021689,-0.082227,0.080743,0.019691,-0.081897,0.077923,0.019399,-0.082950,0.083941,0.019445,-0.082915,0.089863,0.007074,-0.082918,0.091859,0.009399,-0.082801,0.092993,0.008983,-0.082791,0.091563,0.006867,-0.082820,0.091522,0.008147,-0.084203,0.091533,0.008517,-0.084110,0.088876,0.006933,-0.084924,0.090023,0.006866,-0.083264,0.087999,0.006201,-0.084394,0.094870,0.012015,-0.084236,0.093636,0.010136,-0.085267,0.094955,0.009653,-0.083101,0.093259,0.011581,-0.083591,0.092572,0.010063,-0.082652,0.094000,0.011689,-0.082776,0.096293,0.009373,-0.082905,0.093302,0.006937,-0.082737,0.094249,0.009395,-0.066300,0.170895,0.048537,-0.071370,0.172213,0.032230,-0.077150,0.160298,0.031915,-0.072273,0.166482,0.040157,-0.086026,0.132724,0.006078,-0.082545,0.151582,0.018157,-0.081797,0.160273,0.002451,-0.085044,0.147341,0.004691,-0.073509,0.174359,0.013450,-0.079010,0.165359,-0.018690,-0.076977,0.170301,-0.001931,-0.069057,0.177830,0.026061,-0.080362,0.153556,0.027048,-0.079844,0.086266,0.030101,-0.079505,0.079927,0.036504,-0.079333,0.099234,0.041492,-0.079890,0.092198,0.034346,-0.078645,0.064896,0.031776,-0.079386,0.072128,0.028524,-0.078543,0.062952,0.028913,-0.080046,0.081927,0.027416,-0.075580,0.063210,0.056619,-0.074673,0.041622,0.049598,-0.074153,0.052299,0.058944,-0.075230,0.039075,0.035679,-0.073420,0.030746,0.040277,-0.077844,0.054772,0.035215,-0.076065,0.044025,0.031607,-0.074713,0.083120,0.064016,-0.076977,0.091352,0.054121,-0.078388,0.070649,0.045813,-0.076876,0.076617,0.056075,-0.078744,0.067286,0.036706,-0.074249,0.112010,0.059883,-0.077264,0.106553,0.050575,-0.073566,0.135719,-0.059831,-0.068237,0.118291,-0.069644,-0.077092,0.105589,-0.053415,-0.075968,0.121792,-0.056494,-0.058384,0.129687,-0.080671,-0.049016,0.113019,-0.089073,-0.059019,0.099567,-0.078719,-0.059021,0.115399,-0.080610,-0.040265,0.127540,-0.094646,-0.028746,0.110070,-0.101503,-0.038679,0.094171,-0.094815,-0.039165,0.111281,-0.095870,-0.017597,0.182396,-0.073956,-0.031921,0.188839,-0.060005,-0.017059,0.197804,-0.050509,-0.017495,0.191181,-0.062899,-0.028852,0.200478,-0.034620,-0.015555,0.206846,-0.022582,-0.016222,0.202913,-0.037349,-0.026276,0.207209,-0.005247,-0.015451,0.209721,-0.005312,-0.036156,0.201689,-0.018050,-0.035153,0.204270,-0.004473,-0.042909,0.192757,-0.041663,-0.039216,0.197888,-0.029588,-0.049729,0.141710,-0.085247,-0.041868,0.155356,-0.084780,-0.030938,0.143181,-0.095864,-0.041063,0.142290,-0.090754,-0.052302,0.163623,-0.073046,-0.043982,0.176575,-0.067222,-0.031561,0.169487,-0.080679,-0.042895,0.166578,-0.076886,-0.064581,0.142925,-0.071629,-0.057930,0.151460,-0.075472,-0.057612,0.141656,-0.078990,-0.062539,0.167471,-0.058692,-0.071935,0.167608,-0.040621,-0.055179,0.181289,-0.049526,-0.064000,0.174880,-0.044835,-0.075155,0.152216,-0.050714,-0.078369,0.158933,-0.035701,-0.065926,0.154503,-0.064986,-0.070344,0.146601,-0.062440,-0.059998,0.159772,-0.068784,-0.044301,0.185515,-0.055176,-0.017966,0.159204,-0.092643,-0.017657,0.171728,-0.083616,-0.017367,0.126907,-0.103590,-0.018055,0.143965,-0.099993,-0.016737,0.063292,-0.092900,-0.028153,0.076130,-0.095939,-0.016486,0.091484,-0.102569,-0.017012,0.075439,-0.098727,-0.016451,0.109225,-0.104502,-0.037418,0.064872,-0.086283,-0.048310,0.080696,-0.084728,-0.038463,0.077837,-0.091536,-0.056695,0.070070,-0.071534,-0.067846,0.087052,-0.064541,-0.058420,0.083968,-0.075770,-0.075994,0.089163,-0.051774,-0.045544,0.057068,-0.075265,-0.052383,0.051289,-0.063446,-0.054498,0.059529,-0.067155,-0.225236,-0.158441,-0.036974,-0.226645,-0.151900,-0.029543,-0.225608,-0.150934,-0.042645,-0.226126,-0.153727,-0.036069,-0.175924,-0.111782,-0.022841,-0.180194,-0.110828,-0.030282,-0.195015,-0.120515,-0.021354,-0.181221,-0.118674,-0.015102,-0.184539,-0.115215,-0.022263,-0.157568,-0.118789,-0.009886,-0.167611,-0.113886,-0.017499,-0.175020,-0.126765,-0.004673,-0.171296,-0.119307,-0.011728,-0.131776,-0.130883,0.009871,-0.120604,-0.139191,0.021433,-0.103757,-0.130845,0.021047,-0.114454,-0.124878,0.007685,-0.117712,-0.130680,0.015180,-0.146440,-0.141740,0.011756,-0.144591,-0.124518,-0.000809,-0.160770,-0.134476,0.003283,-0.146157,-0.132208,0.005851,-0.212805,-0.182903,-0.016745,-0.220062,-0.174783,-0.041689,-0.211035,-0.183396,-0.071570,-0.204189,-0.192673,-0.046498,-0.213809,-0.184574,-0.044270,-0.212006,-0.168114,-0.084047,-0.200982,-0.173160,-0.105962,-0.201270,-0.189174,-0.098331,-0.207302,-0.179221,-0.092213,-0.220615,-0.163381,-0.058218,-0.220767,-0.149748,-0.061475,-0.208200,-0.149973,-0.083838,-0.216753,-0.157940,-0.073611,-0.223233,-0.165105,-0.020316,-0.223396,-0.165591,-0.039034,-0.202558,-0.173983,0.014587,-0.186274,-0.176823,0.023957,-0.181451,-0.163534,0.017977,-0.198498,-0.158179,0.011989,-0.192648,-0.168096,0.018586,-0.127887,-0.159288,0.030979,-0.142391,-0.160458,0.025505,-0.145849,-0.174142,0.033907,-0.124413,-0.172637,0.041743,-0.135543,-0.167416,0.033660,-0.164101,-0.169367,0.024691,-0.169835,-0.182071,0.029790,-0.152077,-0.190017,0.032114,-0.158077,-0.178746,0.032038,-0.157139,-0.155435,0.016697,-0.173380,-0.148543,0.009587,-0.169432,-0.159422,0.016875,-0.187791,-0.189008,0.019938,-0.174966,-0.193228,0.023126,-0.180145,-0.185322,0.027154,-0.200621,-0.186781,0.005066,-0.193800,-0.196395,-0.016512,-0.182623,-0.196877,0.007410,-0.191799,-0.192718,0.006330,-0.215498,-0.170675,-0.001202,-0.208866,-0.179404,0.002792,-0.224399,-0.152907,-0.014363,-0.214255,-0.154675,0.001400,-0.220743,-0.161442,-0.006796,-0.189912,-0.140616,0.003575,-0.206329,-0.136195,-0.006702,-0.203080,-0.147001,0.003949,-0.175529,-0.137017,0.002810,-0.134402,-0.149385,0.021108,-0.145429,-0.151728,0.017983,-0.111072,-0.150568,0.032752,-0.123336,-0.149595,0.026359,-0.102218,-0.163293,0.044247,-0.113058,-0.189137,0.043937,-0.090518,-0.175944,0.053511,-0.108634,-0.175284,0.048625,-0.092919,-0.139526,0.032708,-0.081241,-0.150532,0.041824,-0.096927,-0.150951,0.038446,-0.074932,-0.131440,0.027794,-0.086385,-0.124954,0.018436,-0.089385,-0.131284,0.025574,-0.067003,-0.081622,-0.003365,-0.067206,-0.065818,-0.011146,-0.074004,-0.074932,-0.017306,-0.074605,-0.092697,-0.007591,-0.070621,-0.079334,-0.009824,-0.061197,-0.121780,0.023792,-0.062191,-0.138254,0.035419,-0.048778,-0.124454,0.028001,-0.061068,-0.129197,0.029013,-0.065130,0.078465,0.081097,-0.063570,0.085767,0.080992,-0.066500,0.087399,0.078307,-0.065937,0.082157,0.079280,-0.062950,0.091487,0.083199,-0.064378,0.100163,0.086452,-0.065647,0.095309,0.081984,-0.064055,0.095541,0.084539,-0.060760,0.085359,0.083375,-0.061848,0.088088,0.082806,-0.021151,0.082726,0.098906,-0.023355,0.079522,0.100037,-0.020269,0.079589,0.103051,-0.018178,0.083106,0.101912,-0.020562,0.081294,0.100874,-0.017895,0.079295,0.106621,-0.016045,0.078701,0.110488,-0.015975,0.083403,0.105762,-0.015932,0.081242,0.108261,-0.018161,0.074082,0.110618,-0.016543,0.073302,0.114100,-0.014679,0.077916,0.114524,-0.016270,0.075958,0.112397,-0.018550,0.069021,0.113774,-0.017145,0.068849,0.117103,-0.015310,0.072792,0.117896,-0.016932,0.070979,0.115702,-0.024331,0.055511,0.114161,-0.023921,0.051755,0.116035,-0.024319,0.053892,0.115744,-0.022632,0.048960,0.116192,-0.022542,0.049340,0.117454,-0.023176,0.049970,0.112493,-0.022169,0.048226,0.114730,-0.024368,0.054722,0.111968,-0.025624,0.054048,0.108460,-0.023447,0.051807,0.110049,-0.022698,0.060151,0.113569,-0.023262,0.059687,0.111045,-0.023885,0.057448,0.112637,-0.023771,0.065201,0.108527,-0.022083,0.070263,0.107957,-0.024734,0.071173,0.105194,-0.026975,0.065983,0.106526,-0.024340,0.068232,0.107094,-0.021567,0.064744,0.110855,-0.025050,0.059667,0.108273,-0.023172,0.062316,0.109581,-0.021878,0.058085,0.119982,-0.019705,0.061091,0.119528,-0.021233,0.060795,0.116383,-0.021606,0.059480,0.118166,-0.018929,0.060954,0.123537,-0.020785,0.057447,0.123519,-0.019333,0.058743,0.125655,-0.021874,0.056192,0.121726,-0.018760,0.064691,0.116368,-0.017681,0.064901,0.119863,-0.016152,0.068757,0.120866,-0.017367,0.066856,0.118443,-0.014079,0.072251,0.121913,-0.014916,0.068397,0.124942,-0.014479,0.070311,0.123407,-0.016902,0.064774,0.123997,-0.015409,0.066419,0.126581,-0.018350,0.063021,0.121601,-0.020039,0.064572,0.113402,-0.020537,0.062441,0.114799,-0.020157,0.069493,0.110815,-0.020021,0.066948,0.112153,-0.020114,0.074981,0.107290,-0.020110,0.072202,0.109153,-0.022573,0.075725,0.104111,-0.020098,0.077479,0.105192,-0.027200,0.079499,0.098274,-0.029680,0.076251,0.098972,-0.025786,0.076034,0.101190,-0.026390,0.077777,0.099482,-0.028337,0.071906,0.102572,-0.025184,0.073869,0.103163,-0.028969,0.060054,0.107588,-0.030369,0.053539,0.108181,-0.027476,0.056808,0.107909,-0.031254,0.066839,0.104558,-0.033991,0.060586,0.106495,-0.030207,0.063508,0.106450,-0.036097,0.053058,0.107764,-0.037334,0.044778,0.108364,-0.033670,0.049612,0.108421,-0.043450,0.031791,0.106385,-0.048121,0.024595,0.102713,-0.044436,0.023970,0.105348,-0.051804,0.036848,0.100006,-0.052254,0.025528,0.098818,-0.044485,0.041813,0.105787,-0.040870,0.038833,0.107565,-0.043198,0.052328,0.105341,-0.050872,0.051601,0.099749,-0.048131,0.045826,0.102899,-0.039914,0.061226,0.104001,-0.038319,0.057016,0.106328,-0.036072,0.067673,0.101968,-0.041201,0.069295,0.099261,-0.046069,0.062751,0.100422,-0.040769,0.065444,0.101519,-0.051537,0.066446,0.096210,-0.051716,0.059302,0.097839,-0.046272,0.072048,0.096338,-0.050186,0.075419,0.092900,-0.055133,0.071904,0.091784,-0.050907,0.071739,0.094305,-0.037239,0.073584,0.098276,-0.042010,0.075368,0.096552,-0.041628,0.072675,0.097670,-0.032617,0.072511,0.100256,-0.031970,0.069833,0.102258,-0.034026,0.077005,0.097945,-0.033287,0.074893,0.098701,-0.031204,0.079775,0.097892,-0.038555,0.077801,0.097001,-0.034725,0.078686,0.097527,-0.056820,0.077014,0.088232,-0.061509,0.073936,0.086149,-0.058812,0.072693,0.089161,-0.061220,0.080292,0.083856,-0.063668,0.075831,0.083433,-0.057630,0.081320,0.086262,-0.059420,0.083162,0.084558,-0.052484,0.078612,0.090226,-0.055203,0.079742,0.088159,-0.046063,0.077537,0.094210,-0.042374,0.077430,0.095889,-0.049451,0.077911,0.092240,-0.025199,0.082704,0.097792,-0.028077,0.081079,0.097923,-0.020149,0.085815,0.098097,-0.022405,0.084284,0.097841,-0.079513,-0.082663,-0.089755,-0.076253,-0.099619,-0.106308,-0.096850,-0.122182,-0.118014,-0.105650,-0.102152,-0.098279,-0.089438,-0.100133,-0.102510,-0.036618,-0.035138,-0.073425,-0.039405,-0.052594,-0.083853,-0.053447,-0.058665,-0.081028,-0.047209,-0.038740,-0.066242,-0.043639,-0.046200,-0.075588,-0.058929,-0.046901,-0.059356,-0.054950,-0.033666,-0.049289,-0.047208,-0.020981,-0.056973,-0.051349,-0.034369,-0.057820,-0.061025,-0.038829,-0.033650,-0.067604,-0.055501,-0.025775,-0.064741,-0.047980,-0.019378,-0.063271,-0.043220,-0.026345,-0.095354,-0.079882,-0.040968,-0.078799,-0.065648,-0.045956,-0.081430,-0.067326,-0.060017,-0.105169,-0.082169,-0.058263,-0.089809,-0.073546,-0.051773,-0.206499,-0.125447,-0.036956,-0.218804,-0.138276,-0.021383,-0.207844,-0.128652,-0.020655,-0.225324,-0.143436,-0.035762,-0.225747,-0.146503,-0.024197,-0.215595,-0.136342,-0.052111,-0.223672,-0.144692,-0.048531,-0.188000,-0.117161,-0.056679,-0.200391,-0.131946,-0.072615,-0.203765,-0.126806,-0.054558,-0.131784,-0.128614,-0.114533,-0.146777,-0.116643,-0.096051,-0.122914,-0.095199,-0.077945,-0.126104,-0.108728,-0.096745,-0.193192,-0.153657,-0.104598,-0.182158,-0.132540,-0.092912,-0.196564,-0.141191,-0.089809,-0.191234,-0.183658,-0.116882,-0.179269,-0.163748,-0.119970,-0.191158,-0.168112,-0.114807,-0.168074,-0.180890,-0.126337,-0.165327,-0.140174,-0.111206,-0.152277,-0.155592,-0.125960,-0.166381,-0.159534,-0.123335,-0.167048,-0.113705,-0.076895,-0.165543,-0.124461,-0.094871,-0.170397,-0.106488,-0.044823,-0.148507,-0.099990,-0.061369,-0.169348,-0.108332,-0.059516,-0.121186,-0.107483,-0.017515,-0.107903,-0.114292,-0.006922,-0.088951,-0.106065,-0.009893,-0.100835,-0.098532,-0.022582,-0.104008,-0.107767,-0.014989,-0.126564,-0.118966,-0.004116,-0.096867,-0.119905,0.005881,-0.111248,-0.119987,0.000290,-0.139936,-0.113025,-0.013713,-0.142276,-0.118522,-0.007477,-0.153344,-0.108443,-0.021941,-0.166203,-0.106948,-0.028435,-0.166049,-0.109688,-0.022817,-0.152255,-0.101510,-0.036702,-0.168376,-0.105963,-0.035037,-0.136313,-0.102587,-0.027326,-0.138042,-0.107725,-0.020049,-0.115867,-0.093385,-0.034057,-0.130940,-0.093258,-0.047424,-0.134238,-0.097472,-0.036214,-0.126120,-0.091255,-0.061290,-0.084690,-0.079703,-0.027362,-0.098753,-0.088188,-0.030854,-0.072972,-0.061004,-0.034487,-0.074773,-0.067878,-0.025724,-0.055932,-0.024366,-0.040802,-0.063072,-0.046285,-0.041764,-0.058254,-0.035371,-0.041247,-0.068751,-0.055136,-0.051482,-0.070294,-0.056342,-0.042972,-0.070768,-0.063498,-0.072496,-0.069925,-0.058033,-0.061148,-0.062132,-0.080246,-0.096153,-0.066285,-0.070053,-0.084376,-0.054285,-0.097892,-0.109690,-0.068126,-0.120393,-0.120585,-0.064214,-0.097596,-0.107922,-0.026958,-0.202801,-0.039721,-0.016661,-0.202010,-0.085290,-0.014924,-0.199896,0.004728,-0.015918,-0.202695,-0.040613,-0.059133,-0.146316,-0.132642,-0.072693,-0.172283,-0.137200,-0.085069,-0.146587,-0.132364,-0.070693,-0.146191,-0.132609,-0.043536,-0.097225,-0.110669,-0.049812,-0.121981,-0.122415,-0.048986,-0.103817,-0.113487,-0.035449,-0.120390,-0.122248,-0.026464,-0.147215,-0.132207,-0.034006,-0.173007,-0.133374,-0.042384,-0.146894,-0.132316,-0.034713,-0.147008,-0.132195,-0.062333,-0.194169,-0.124561,-0.050228,-0.172454,-0.135263,-0.043050,-0.193765,-0.119096,-0.056799,-0.203712,-0.092290,-0.051955,-0.193943,-0.121650,-0.025855,-0.193570,-0.116757,-0.036298,-0.202304,-0.086019,-0.034552,-0.193603,-0.117539,-0.050095,-0.146737,-0.132555,-0.078426,-0.205665,-0.102511,-0.090342,-0.195399,-0.126148,-0.075056,-0.194527,-0.126591,-0.132177,-0.198998,0.022730,-0.111820,-0.205005,-0.007930,-0.092729,-0.199034,0.027129,-0.112979,-0.199207,0.024960,-0.055798,-0.196826,0.036518,-0.073851,-0.188972,0.051623,-0.070001,-0.202984,-0.001524,-0.073472,-0.198115,0.032265,-0.140455,-0.177006,-0.132438,-0.119835,-0.149419,-0.130185,-0.136778,-0.152119,-0.128301,-0.109885,-0.206776,-0.095530,-0.126425,-0.197491,-0.121802,-0.105546,-0.173845,-0.136550,-0.108164,-0.196518,-0.124325,-0.102006,-0.147610,-0.131563,-0.156935,-0.198613,-0.116031,-0.144442,-0.207573,-0.090436,-0.142737,-0.198163,-0.118998,-0.172417,-0.203589,-0.014623,-0.161691,-0.199584,0.013790,-0.172818,-0.198965,0.010066,-0.146881,-0.205252,-0.008854,-0.148415,-0.199351,0.018401,-0.181105,-0.197949,-0.108953,-0.171058,-0.206439,-0.086605,-0.169534,-0.198715,-0.112790,-0.193505,-0.199889,-0.080661,-0.192010,-0.195381,-0.104069,-0.183470,-0.204129,-0.049986,-0.194284,-0.199417,-0.048552,-0.159698,-0.208159,-0.050323,-0.172044,-0.206873,-0.050558,-0.129655,-0.208318,-0.049965,-0.145824,-0.208498,-0.049658,-0.093545,-0.207580,-0.060906,-0.111157,-0.207859,-0.052881,-0.075287,-0.206423,-0.059326,-0.080302,-0.206573,-0.074086,-0.050417,-0.204049,-0.041900,-0.063447,-0.205118,-0.048064,-0.039771,-0.200805,0.007081,-0.038287,-0.203259,-0.039610,-0.017022,-0.173505,-0.132750,-0.017940,-0.120673,-0.122863,-0.017598,-0.147560,-0.132213,-0.026763,-0.093960,-0.111198,-0.017466,-0.070713,-0.100679,-0.017762,-0.093998,-0.111693,-0.034974,-0.071690,-0.098478,-0.035582,-0.094491,-0.110369,-0.030466,-0.040425,-0.080295,-0.025062,-0.053174,-0.089716,-0.032666,-0.053906,-0.087915,-0.009854,-0.097032,0.029825,-0.017046,-0.106730,0.026366,-0.009353,-0.119993,0.023903,-0.009249,-0.108390,0.025558,-0.023927,-0.095394,0.028395,-0.029102,-0.103881,0.025454,-0.024829,-0.115303,0.025171,-0.023639,-0.105408,0.026454,-0.019813,-0.127096,0.029329,-0.035624,-0.122564,0.026951,-0.032752,-0.135435,0.035927,-0.028403,-0.125088,0.029331,-0.035223,-0.093932,0.025629,-0.035505,-0.107455,0.021946,-0.033062,-0.101845,0.024410,-0.044145,-0.109352,0.018604,-0.040216,-0.117187,0.022085,-0.064409,-0.037819,0.004051,-0.060082,-0.054757,0.009993,-0.058384,-0.044760,0.016678,-0.061924,-0.041225,0.010548,-0.065351,-0.039764,-0.014389,-0.064988,-0.056674,-0.006479,-0.065260,-0.052525,-0.012742,-0.066643,-0.031092,-0.009061,-0.065516,-0.027773,-0.015580,-0.065064,-0.047492,-0.001643,-0.066281,-0.034455,-0.002429,-0.063605,-0.072348,0.000595,-0.061744,-0.063909,0.004868,-0.063933,-0.060353,-0.000579,-0.057861,-0.079552,0.010190,-0.054700,-0.071835,0.014788,-0.058684,-0.067691,0.009967,-0.051926,-0.062481,0.020471,-0.048124,-0.089744,0.018076,-0.043752,-0.080195,0.023446,-0.049696,-0.076324,0.019357,-0.064448,-0.092711,0.003897,-0.061275,-0.085521,0.006358,-0.064066,-0.083243,0.001987,-0.069260,-0.103622,0.002251,-0.080441,-0.114273,0.002881,-0.077438,-0.104797,-0.003574,-0.061646,-0.109745,0.010154,-0.071602,-0.118969,0.015018,-0.053233,-0.111285,0.015920,-0.061010,-0.116679,0.016249,-0.083737,-0.119414,0.011399,-0.059947,-0.097139,0.009451,-0.063556,-0.101417,0.006731,-0.054081,-0.095346,0.013707,-0.058128,-0.089697,0.010277,-0.049103,-0.101928,0.016393,-0.031247,-0.083451,0.029317,-0.039734,-0.068985,0.028546,-0.037520,-0.082110,0.026857,-0.020724,-0.043341,0.059066,-0.021980,-0.041017,0.062907,-0.032579,-0.035555,0.059294,-0.030005,-0.040232,0.052746,-0.027517,-0.039670,0.058419,-0.012714,-0.043877,0.063360,-0.014873,-0.041699,0.068110,-0.013673,-0.042685,0.065857,-0.013104,-0.048163,0.057098,-0.012774,-0.045611,0.060307,-0.026022,-0.073624,0.033690,-0.020092,-0.066200,0.040779,-0.027874,-0.051965,0.041030,-0.033867,-0.058858,0.033690,-0.027061,-0.062484,0.037018,-0.047881,-0.052022,0.026431,-0.054037,-0.033988,0.023360,-0.053744,-0.048443,0.022003,-0.049434,-0.025377,0.031846,-0.054716,-0.019912,0.026170,-0.041403,-0.042230,0.032683,-0.040953,-0.055418,0.030155,-0.036666,-0.037864,0.043027,-0.043452,-0.031419,0.037684,-0.021521,-0.049327,0.050000,-0.029345,-0.044101,0.046752,-0.012522,-0.060874,0.048780,-0.012885,-0.053145,0.052820,-0.011208,-0.077709,0.038768,-0.012072,-0.069358,0.044336,-0.018100,-0.085968,0.032448,-0.024862,-0.084719,0.030848,-0.010488,-0.086918,0.034204,-0.010941,-0.139111,0.032908,-0.010123,-0.130087,0.027475,-0.023504,-0.146644,0.043413,-0.012097,-0.158908,0.046344,-0.011571,-0.148268,0.039603,-0.049413,-0.147767,0.043318,-0.037939,-0.159445,0.050130,-0.035984,-0.146625,0.044435,-0.068575,-0.162035,0.050107,-0.054618,-0.173819,0.055168,-0.071847,-0.175035,0.055744,-0.065004,-0.149361,0.042920,-0.026674,-0.194574,0.035841,-0.013407,-0.184550,0.048986,-0.014143,-0.194288,0.034334,-0.039927,-0.185546,0.052388,-0.040294,-0.195509,0.037204,-0.025561,-0.171892,0.052501,-0.039359,-0.172791,0.053741,-0.012743,-0.171537,0.050767,-0.009108,0.079685,0.123105,-0.011728,0.075854,0.122778,-0.009118,0.076979,0.124875,-0.013282,0.076942,0.118634,-0.013589,0.074388,0.120292,-0.011533,0.081637,0.119339,-0.013107,0.079837,0.116885,-0.009359,0.086171,0.119073,-0.009232,0.082889,0.121249,-0.009511,0.092548,0.114304,-0.009402,0.089341,0.116601,-0.013219,0.101028,0.110478,-0.009592,0.098502,0.112254,-0.010352,0.103745,0.113270,-0.009858,0.101176,0.112534,-0.012025,0.095324,0.109935,-0.009441,0.095591,0.112682,-0.019118,0.097544,0.100067,-0.018705,0.101047,0.104747,-0.024743,0.103509,0.105337,-0.021227,0.100498,0.102334,-0.014781,0.090186,0.101255,-0.014639,0.086990,0.103996,-0.013239,0.092389,0.105981,-0.013577,0.089413,0.105016,-0.016962,0.086172,0.100293,-0.016233,0.084973,0.102995,-0.017408,0.088860,0.098418,-0.018541,0.087353,0.098373,-0.016807,0.092551,0.098491,-0.016753,0.090554,0.098382,-0.015412,0.095458,0.101902,-0.017708,0.094865,0.098828,-0.014592,0.098326,0.106461,-0.013658,0.095449,0.106104,-0.018148,0.103606,0.109752,-0.016059,0.101093,0.107706,-0.016264,0.106466,0.113295,-0.024082,0.110807,0.113958,-0.025686,0.106098,0.110898,-0.021146,0.106124,0.112335,-0.015070,0.124841,0.114837,-0.016741,0.144615,0.110638,-0.024158,0.133491,0.111882,-0.015962,0.133474,0.111548,-0.012549,0.110691,0.115780,-0.020899,0.117010,0.116644,-0.014014,0.116930,0.116812,-0.029463,0.125287,0.114202,-0.033610,0.143351,0.109182,-0.037502,0.133496,0.109302,-0.031328,0.133541,0.111206,-0.032984,0.117361,0.113372,-0.040945,0.125327,0.109344,-0.044024,0.117557,0.107761,-0.034756,0.110576,0.110789,-0.038467,0.117525,0.110864,-0.029868,0.105808,0.109376,-0.051236,0.124088,0.101848,-0.054640,0.115264,0.099988,-0.049664,0.117125,0.104073,-0.057781,0.128397,0.093576,-0.048076,0.132739,0.102807,-0.055728,0.139234,0.093744,-0.053048,0.131284,0.098428,-0.064470,0.129513,0.082499,-0.063754,0.143672,0.080288,-0.070950,0.125556,0.069497,-0.068214,0.136061,0.073742,-0.061633,0.108535,0.091967,-0.059926,0.118022,0.092741,-0.058759,0.112198,0.095875,-0.064758,0.107563,0.085580,-0.063476,0.104583,0.088780,-0.072186,0.100591,0.068893,-0.068518,0.112265,0.075629,-0.071392,0.113246,0.068498,-0.067281,0.102193,0.079487,-0.069371,0.092065,0.074517,-0.067271,0.094273,0.078573,-0.071950,0.088413,0.069806,-0.064497,0.117589,0.084275,-0.066252,0.110260,0.081252,-0.061590,0.123722,0.088529,-0.026437,0.155640,0.105734,-0.016770,0.166714,0.100919,-0.016718,0.156695,0.106667,-0.041416,0.153843,0.101264,-0.034998,0.164280,0.096837,-0.034585,0.154651,0.103960,-0.026796,0.173604,0.091998,-0.016701,0.174817,0.093875,-0.042323,0.170332,0.085703,-0.035161,0.178637,0.081188,-0.035235,0.172075,0.089193,-0.059976,0.155967,0.078843,-0.054677,0.165825,0.076680,-0.060584,0.168615,0.062920,-0.060431,0.162435,0.070713,-0.054422,0.177330,0.061116,-0.060305,0.174381,0.055509,-0.041810,0.191956,0.051298,-0.034666,0.189680,0.063831,-0.034724,0.194597,0.053748,-0.042055,0.182303,0.069561,-0.034871,0.184413,0.072881,-0.047989,0.184846,0.057438,-0.047909,0.189097,0.048343,-0.048711,0.174366,0.073577,-0.048457,0.179989,0.065729,-0.048402,0.161561,0.089831,-0.048679,0.168320,0.081601,-0.052945,0.151240,0.092544,-0.058425,0.148428,0.086758,-0.045643,0.142363,0.103289,-0.047488,0.152920,0.097497,-0.042964,0.133317,0.106467,-0.027133,0.117202,0.115258,-0.011199,0.106638,0.114263,-0.021381,-0.034162,0.083641,-0.014422,-0.037589,0.082119,-0.011019,-0.035497,0.088141,-0.016212,-0.035080,0.085984,-0.007635,-0.034938,0.090100,-0.015837,-0.039870,0.073993,-0.026794,-0.037017,0.067488,-0.015776,-0.040779,0.070627,-0.037804,-0.028924,0.066160,-0.035775,-0.031939,0.062070,-0.032021,-0.030662,0.076006,-0.039222,-0.026049,0.071027,-0.022475,-0.036036,0.078012,-0.026202,-0.032947,0.080306,-0.014722,-0.039018,0.077996,-0.023299,0.022559,-0.070218,-0.030997,0.010690,-0.067481,-0.038605,0.018485,-0.061754,-0.031245,0.027930,-0.067184,-0.031086,0.020515,-0.067015,-0.041943,0.044054,-0.067332,-0.048438,0.038894,-0.058140,-0.057982,0.045954,-0.051722,-0.050315,0.044716,-0.060457,-0.061693,0.039660,-0.039777,-0.064056,0.046846,-0.041937,-0.053458,0.032655,-0.047409,-0.057749,0.024099,-0.036324,-0.059585,0.032242,-0.037981,-0.039388,0.033276,-0.063236,-0.046076,0.025524,-0.055295,-0.046935,0.032772,-0.056454,-0.055584,-0.006564,-0.036158,-0.056735,0.005216,-0.032804,-0.058508,-0.004003,-0.030405,-0.050914,-0.009705,-0.046819,-0.054954,-0.014142,-0.039460,-0.045365,0.005565,-0.053984,-0.038486,-0.005533,-0.063051,-0.045573,-0.007259,-0.055491,-0.051222,0.015475,-0.044216,-0.056498,0.015001,-0.034562,-0.045648,0.016587,-0.054278,-0.026695,0.054550,-0.085443,-0.035125,0.048535,-0.076722,-0.036488,0.055336,-0.081339,-0.025138,0.042878,-0.077224,-0.032429,0.038908,-0.069897,-0.033650,0.043513,-0.072772,-0.016265,0.047541,-0.083596,-0.016467,0.054404,-0.087712,-0.015491,0.030585,-0.071808,-0.023927,0.034124,-0.072005,-0.015924,0.038533,-0.076430,-0.015652,0.034981,-0.073514,-0.016106,0.042488,-0.079864,-0.031767,0.033790,-0.068303,-0.030765,-0.016440,-0.071502,-0.023310,-0.026401,-0.077280,-0.030045,-0.029028,-0.075114,-0.016506,-0.011138,-0.074792,-0.023177,0.001242,-0.071688,-0.015770,0.016159,-0.071241,-0.016141,0.003558,-0.072247,-0.030811,-0.002175,-0.068694,-0.016992,-0.038254,-0.083329,-0.017404,-0.052522,-0.091032,-0.016678,-0.025249,-0.078208,-0.015553,0.024766,-0.070952,-0.010750,0.060437,0.116351,-0.010103,0.058530,0.116777,-0.009144,0.060489,0.116962,-0.009966,0.061666,0.116522,-0.009952,0.060427,0.116577,-0.010930,0.060888,0.122180,-0.011688,0.062393,0.120290,-0.010618,0.063197,0.119571,-0.009432,0.062062,0.120785,-0.010583,0.062305,0.120722,-0.013186,0.062238,0.118931,-0.014773,0.060466,0.118559,-0.013226,0.061730,0.117583,-0.012118,0.062980,0.118222,-0.013380,0.062019,0.118246,-0.013555,0.060989,0.120349,-0.011811,0.063186,0.119114,-0.012568,0.062374,0.119632,-0.012257,0.058667,0.116432,-0.010709,0.061848,0.116394,-0.012122,0.060978,0.116629,-0.011476,0.060634,0.116357,-0.014045,0.059458,0.117107,-0.011389,0.062655,0.117268,-0.012751,0.061357,0.117024,-0.008341,0.058844,0.117978,-0.008004,0.060626,0.118175,-0.008660,0.061718,0.117263,-0.008466,0.060540,0.117530,-0.007500,0.059208,0.119851,-0.008021,0.061246,0.119650,-0.008316,0.062001,0.118065,-0.007852,0.060878,0.118880,-0.008048,0.060078,0.122111,-0.009181,0.062741,0.118991,-0.008515,0.061677,0.120367,-0.010672,0.063339,0.118333,-0.011243,0.063449,0.118726,-0.009536,0.062886,0.117580,-0.010129,0.063126,0.117953,-0.009684,0.062315,0.116872,-0.008995,0.062500,0.117350,-0.010081,0.062216,0.116479,-0.013740,0.054221,0.117167,-0.011825,0.056061,0.116660,-0.014152,0.056652,0.116994,-0.013048,0.056249,0.116736,-0.013071,0.052759,0.117534,-0.015387,0.053487,0.118280,-0.014246,0.053002,0.117705,-0.011139,0.054122,0.117396,-0.009304,0.056558,0.117728,-0.010486,0.056187,0.117016,-0.010779,0.053519,0.118926,-0.011841,0.052917,0.117977,-0.009182,0.055325,0.119382,-0.007880,0.057081,0.119683,-0.008435,0.056888,0.118607,-0.009808,0.054681,0.121479,-0.010185,0.054249,0.120093,-0.008270,0.055809,0.122194,-0.007311,0.057560,0.122550,-0.007475,0.057264,0.121004,-0.008131,0.054085,0.124996,-0.009089,0.054568,0.123095,-0.007643,0.055785,0.125725,-0.009244,0.058680,0.124574,-0.007826,0.058043,0.123979,-0.009058,0.054909,0.127182,-0.007938,0.054198,0.126607,-0.011159,0.057206,0.125566,-0.013213,0.059375,0.122676,-0.011322,0.059231,0.123981,-0.013153,0.055575,0.125498,-0.011132,0.055568,0.126694,-0.014943,0.057237,0.122687,-0.015600,0.058994,0.120253,-0.014557,0.059228,0.121358,-0.015842,0.055115,0.122934,-0.014696,0.055343,0.124187,-0.016463,0.056481,0.120348,-0.015797,0.057859,0.118313,-0.016040,0.058502,0.119213,-0.016648,0.054435,0.120370,-0.016548,0.054838,0.121694,-0.015804,0.055293,0.118326,-0.015087,0.057210,0.117558,-0.016407,0.054008,0.119156,-0.075034,0.038889,0.019097,-0.076453,0.036788,0.020041,-0.076546,0.037189,0.018808,-0.077609,0.036203,0.020651,-0.073585,0.038075,0.019879,-0.074350,0.039738,0.022481,-0.074409,0.038143,0.013747,-0.073547,0.037751,0.017115,-0.075645,0.039489,0.011399,-0.086327,0.114136,-0.004574,-0.084130,0.107621,0.007829,-0.085185,0.118631,0.006864,-0.083985,0.098414,0.002164,-0.083232,0.100690,0.008813,-0.084672,0.099190,-0.008017,-0.083736,0.094219,-0.003071,-0.085810,0.107063,-0.014846,-0.083094,0.092196,0.006047,-0.016853,-0.193716,-0.116418,-0.010054,0.014056,0.107017,-0.006839,0.014041,0.107330,-0.016388,0.013474,0.105452,-0.013230,0.013869,0.106415,-0.022156,0.013107,0.102747,-0.019431,0.013121,0.104100,-0.025981,0.014499,0.100827,-0.024386,0.013547,0.101663,-0.027410,0.017281,0.099985,-0.026898,0.015794,0.100249,-0.027751,0.020393,0.100222,-0.027723,0.018878,0.100004,-0.026657,0.022684,0.101094,-0.027416,0.021686,0.100563,-0.023775,0.023857,0.103029,-0.025428,0.023380,0.101911,-0.019742,0.024460,0.105724,-0.021864,0.024163,0.104379,-0.015315,0.024928,0.107638,-0.017578,0.024722,0.106815,-0.010184,0.024963,0.108661,-0.012868,0.025008,0.108257,-0.007257,0.024842,0.108880,-0.083141,0.093491,0.015046,-0.083682,0.094239,0.014178,-0.082669,0.093939,0.014033,-0.082625,0.093370,0.015418,-0.082832,0.094020,0.012599], diff --git a/examples/obj/lightmap/lightmap.js b/examples/obj/lightmap/lightmap.js index e3a59d1151d2cf..7626ae9f415991 100644 --- a/examples/obj/lightmap/lightmap.js +++ b/examples/obj/lightmap/lightmap.js @@ -39,7 +39,7 @@ "mapLightAnisotropy": 4, "shading" : "Phong", "specularCoef" : 100, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }, @@ -67,7 +67,7 @@ "mapLightAnisotropy": 4, "shading" : "Phong", "specularCoef" : 100, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }, @@ -95,7 +95,7 @@ "mapLightAnisotropy": 4, "shading" : "Phong", "specularCoef" : 100, - "transparency" : 1.0, + "opacity" : 1.0, "transparent" : false, "vertexColors" : false }], diff --git a/examples/obj/male02/Male02_bin.js b/examples/obj/male02/Male02_bin.js index 45c6deb1b4c439..c8520f334c3b48 100644 --- a/examples/obj/male02/Male02_bin.js +++ b/examples/obj/male02/Male02_bin.js @@ -23,7 +23,7 @@ "mapDiffuse" : "male-02-1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -37,7 +37,7 @@ "mapDiffuse" : "orig_02_-_Defaul1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -51,7 +51,7 @@ "mapDiffuse" : "orig_02_-_Defaul1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -65,7 +65,7 @@ "mapDiffuse" : "01_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -79,7 +79,7 @@ "mapDiffuse" : "male-02-1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }], "buffers": "Male02_bin.bin" diff --git a/examples/obj/male02/Male02_dds.js b/examples/obj/male02/Male02_dds.js index 21d68fc5caf19a..0a1faac9f4f5c5 100644 --- a/examples/obj/male02/Male02_dds.js +++ b/examples/obj/male02/Male02_dds.js @@ -26,7 +26,7 @@ "mapDiffuse" : "male-02-1noCulling.dds", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -40,7 +40,7 @@ "mapDiffuse" : "orig_02_-_Defaul1noCulling.dds", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -54,7 +54,7 @@ "mapDiffuse" : "orig_02_-_Defaul1noCulling.dds", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -68,7 +68,7 @@ "mapDiffuse" : "01_-_Default1noCulling.dds", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -82,7 +82,7 @@ "mapDiffuse" : "male-02-1noCulling.dds", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }], "vertices": [464,15985,579,166,15790,583,160,15767,622,436,15989,532,660,16185,304,346,16107,578,564,16375,504,690,16282,-18,723,16468,173,558,16341,-309,578,16366,-309,326,16350,-459,339,16384,-494,682,16062,-444,707,16308,-10,694,16199,305,652,15719,623,403,15306,1015,-73,15603,661,-48,15646,591,-39,15796,561,-210,15786,446,-122,15926,496,-224,15997,334,-388,15981,232,-376,16113,96,-388,16097,236,-339,16037,397,-308,16009,497,-227,15980,575,67,15995,528,-131,16006,635,-26,16032,641,142,16089,651,17,16114,849,313,16209,682,158,16226,872,423,16339,701,541,16555,670,594,16609,569,769,16687,257,773,16731,16,900,17155,-257,967,17093,154,919,17536,-238,682,17186,-566,663,17590,-533,313,17545,-711,329,17163,-703,366,16780,-512,554,16779,-409,699,16775,-252,660,16522,-187,530,16535,-384,307,16528,-462,53,16336,-493,37,16361,-506,-233,16274,-355,-253,16298,-359,50,16056,-674,390,16052,-625,718,16097,-498,411,16088,-684,887,15729,-660,1190,15788,-267,897,16076,-186,848,16049,-168,783,15987,195,813,16010,229,1061,15584,807,1144,15836,310,1163,15775,319,1682,15576,457,1835,15502,-43,1196,15725,-305,1555,15210,-546,1775,15185,-439,2215,15322,91,2025,15047,-279,2500,15128,230,2132,15370,565,1495,15461,889,1035,15169,1200,989,14613,1495,328,14576,1438,-275,14609,1243,-150,15277,880,-661,15295,627,-230,15763,480,-607,15707,165,-440,15976,249,-443,16188,-108,-437,15975,-248,-482,15997,-242,-254,16038,-569,-280,16064,-615,56,16091,-739,-452,15776,-858,37,15721,-969,474,15725,-848,896,15688,-674,974,15240,-812,1636,14559,-596,1800,14565,-497,1902,14549,-392,1981,14504,-227,2211,14891,-81,2566,14802,220,2590,14853,631,2508,15147,649,1951,15289,943,1264,15143,1230,1201,14640,1456,1146,14107,1524,958,14029,1655,295,13993,1644,-342,14007,1442,-863,14565,1005,-1319,14629,582,-1246,15134,402,-1033,15557,62,-791,15809,-379,-810,15748,-383,-432,15713,-891,-1000,15586,-945,-569,15181,-1273,39,15680,-985,482,15671,-870,526,15236,-978,1082,14524,-849,1605,14032,-443,1746,14073,-284,1823,14202,-137,1951,14213,-3,1999,14661,-127,2286,14756,-64,2577,14566,214,2635,14570,612,2419,14525,935,2336,14840,972,2244,15088,985,1875,14945,1170,1661,15088,1229,1434,14667,1377,1345,14142,1409,1334,14011,1431,1153,13952,1554,956,13917,1662,289,13867,1664,-353,13864,1475,-960,13981,1187,-1475,14005,772,-930,13981,1105,-1561,14042,553,-1559,13925,569,-1642,13957,357,-1624,13532,466,-1700,13559,274,-1680,12759,541,-1569,13590,-329,-1605,12756,4,-1281,13567,-887,-1331,12753,-542,-1146,12753,-668,-1085,13550,-957,-1062,13974,-1136,-854,13946,-1179,-852,14054,-1214,-642,14016,-1247,-628,14555,-1362,8,14516,-1230,62,15232,-1138,557,14521,-1045,1043,13988,-786,1604,13941,-401,1730,13967,-248,1859,13994,-91,1986,14016,56,1817,14093,656,1998,14288,61,1955,14424,-200,1590,14310,-82,2043,14156,-229,2382,14261,-137,2334,14514,-101,2626,14324,180,2638,14496,603,2446,14239,895,2104,14127,1041,2064,14402,1086,1997,14704,1145,1697,14517,1070,1578,14636,1299,1563,14154,1312,1540,14030,1330,1489,13589,1369,1316,13560,1469,1144,13530,1568,980,13501,1663,341,13434,1715,-319,13417,1593,-946,13425,1316,-967,13855,1207,-1476,13894,783,-1547,13505,659,-1586,12761,705,-1599,11836,783,-1615,11834,249,-1429,11831,-318,-1263,11829,-480,-1096,11828,-642,-960,12754,-795,-929,11826,-804,-775,12754,-922,-123,12759,-881,-259,11823,-843,366,12762,-811,239,11821,-824,719,11819,-692,825,12767,-626,1347,11817,-454,1425,12774,-312,1518,12776,-108,1650,13558,-153,1554,13539,-305,975,13497,-710,431,13492,-882,-45,13487,-1050,-669,13518,-1110,21,13885,-1136,530,13885,-952,536,13972,-972,1037,13895,-767,1772,13578,52,1879,13596,227,1833,13998,698,1648,14290,994,1515,14384,427,1393,14227,287,1379,14218,721,1517,13954,279,1500,13939,676,1676,13520,261,1664,13495,628,1869,12866,211,1880,12847,580,2061,12427,-2,2031,12396,489,2136,12067,42,2355,12220,-314,2416,12022,-317,2455,11810,-279,2793,11758,-317,2754,12020,-386,2682,12264,-413,3043,12067,-235,2979,12319,-283,3172,12145,78,3133,12363,25,2893,12554,-293,3068,12600,5,2688,13088,-251,2376,13020,-336,2587,12492,-401,2268,12438,-276,2070,12937,-184,1849,13584,-115,1699,14031,-98,2195,13676,-283,2529,13750,-191,2744,13781,129,2732,13754,550,2559,13693,873,2222,13603,1043,1888,13529,951,1754,14026,976,1667,14299,994,2077,12876,871,2221,12433,784,2034,12201,265,2139,12295,587,2065,11783,404,2171,11674,68,2465,11578,-194,2798,11551,-230,3070,11589,-62,3074,11800,-154,3176,11679,244,3191,11921,147,3097,12243,462,3024,12603,418,2885,13118,39,2876,13089,487,2695,13027,804,2388,12945,956,2531,12499,879,2420,12335,761,2171,11872,711,2089,11315,574,2208,11200,221,2252,10614,451,2510,10532,226,2487,11111,-22,2823,10503,181,2810,11085,-52,3075,11123,111,3181,11209,406,3067,11321,752,3050,11798,611,2776,11883,844,2768,12305,719,2443,11910,879,2195,11400,870,2147,10718,771,2264,10113,630,2524,10028,396,2548,9563,516,2847,9478,500,2831,9996,342,3069,10030,489,3071,10537,334,3146,10116,781,3158,10623,626,3053,10727,946,2795,10809,1172,2783,11413,1004,2482,10839,1217,2460,11438,1034,2235,10804,1064,2151,10218,955,2274,9702,716,2600,9682,628,2400,9783,775,2576,9499,667,2809,9429,644,2817,9619,614,2968,9619,739,2968,9429,775,2990,9499,1008,2996,9682,955,3058,9478,673,3099,9564,970,2956,9703,1277,3033,10221,1106,2774,10306,1339,2466,10338,1393,2229,10305,1246,2130,9841,1023,2294,9885,999,2357,9612,834,2601,9625,1027,2235,9725,1081,2258,9795,1314,2416,9795,1444,2649,9725,1422,2691,9885,1326,2473,9948,1340,2322,9948,1215,2382,9927,1494,2682,9841,1477,2172,9926,1320,2890,9784,1179,2869,9612,1255,2844,12570,737,1752,13622,846,1446,12787,1408,1281,12787,1500,1116,12787,1593,950,12786,1685,310,12783,1761,-304,12778,1691,-871,12772,1444,-1468,13478,858,-1397,12765,1034,-836,12771,1312,-1492,12763,869,-1498,11837,925,-1480,11360,1049,-1598,11362,911,-1674,11363,377,-1499,11359,-222,-1351,11355,-387,-1410,11093,-334,-1273,11088,-512,-1524,10441,-334,-1391,10414,-501,-1136,11084,-690,-1254,10388,-670,-420,11061,-789,-355,11336,-790,152,11326,-803,650,11317,-702,1326,11305,-509,1457,11818,-249,1612,12778,95,1706,12780,299,1659,12785,910,1508,11824,1262,1369,11825,1366,1230,11826,1471,1091,11827,1575,427,11831,1766,-161,11834,1779,-720,11836,1590,-1295,11837,1208,-696,11835,1434,-1396,11837,1066,-1361,11358,1188,-1468,11095,1129,-1597,11099,995,-1711,11103,462,-1547,11097,-155,-1659,10469,-168,-1691,10137,-180,-1562,10086,-343,-1702,9762,-250,-1547,9664,-403,-1436,10036,-509,-1396,9565,-556,-1305,9989,-678,-1243,9468,-711,-1423,9137,-632,-1273,9057,-754,-544,9278,-872,-571,9814,-880,-22,9789,-916,1,10254,-886,525,9763,-880,547,10228,-850,91,11044,-824,598,11028,-744,1303,11005,-584,1444,11303,-320,1568,11818,-44,1678,11819,160,1684,11821,757,1579,11303,1189,1438,11306,1305,1298,11308,1420,1157,11311,1536,518,11324,1759,-75,11335,1808,-653,11346,1656,-1243,11356,1326,-1339,11091,1264,-1524,10447,1200,-1673,10474,1060,-1794,10490,476,-1827,10189,413,-1907,9852,275,-2055,9345,182,-1756,9302,-401,-2189,8795,148,-1887,8757,-440,-2102,7840,-494,-2403,7877,95,-2413,7851,674,-2197,8769,730,-2286,7815,860,-2059,8728,922,-2160,7778,1046,-1930,8693,1106,-2034,7742,1231,-1797,8657,1291,-1129,8520,1695,-1311,7593,1652,241,8353,1782,329,7423,1734,1176,7450,1562,992,8375,1641,208,8710,1804,-1053,8902,1715,-1679,9110,1322,-1808,9177,1139,-1472,9533,1391,-961,9275,1739,-46,9268,1803,829,9136,1716,917,8756,1676,1695,8522,1289,1955,7614,1189,1844,8570,1118,1569,8972,1338,1714,9050,1170,1989,8618,949,1871,9139,994,2145,8673,773,2003,9220,829,2045,9283,252,1877,9764,348,1679,9653,-225,1676,9988,-173,1543,9945,-340,1536,10302,-331,1399,10287,-499,1424,11002,-394,1561,11301,-132,1678,11299,56,1746,11299,676,1616,10996,1135,1475,11000,1258,1335,11005,1381,1195,11009,1503,572,11030,1748,-23,11049,1822,-611,11068,1696,-1210,11087,1399,-1372,10417,1343,-1578,10097,1176,-1720,10147,1032,-1878,9820,870,-2066,9320,762,-1949,9252,944,-1618,9629,1216,-1268,9990,1478,-626,9817,1746,-22,9789,1814,580,9760,1746,1229,9871,1481,1215,10273,1489,611,10225,1750,-2,10254,1817,-616,10281,1749,-1215,10387,1486,-1424,10042,1329,-1759,9729,1035,1370,10288,1350,1387,9910,1336,1524,9498,1251,1368,9400,1413,1675,9604,1087,1541,9955,1190,1523,10307,1210,1675,10323,1070,1690,9995,1048,1807,9700,934,1802,10055,450,1672,10318,-163,1545,10998,-205,1666,10994,-15,1775,10991,614,1798,10336,493,1259,10274,-669,1272,9870,-678,1410,9906,-508,1524,9565,-387,1796,9270,-359,2190,8738,195,2381,7764,678,2239,7714,849,2097,7664,1019,2424,7827,104,2179,7826,-512,1943,8734,-420,2001,7797,-658,1754,8691,-554,1824,7769,-803,1574,8659,-696,1646,7740,-949,1392,8624,-837,560,8479,-957,713,7554,-1030,-80,8504,-971,-64,8866,-960,506,8863,-925,-45,9268,-936,496,9236,-894,1216,9387,-712,1370,9474,-549,1623,9181,-493,1450,9095,-630,1277,9005,-765,-578,8904,-899,-588,8508,-897,-717,7572,-926,-123,7559,-983,-1529,7734,-873,-1329,8642,-806,-1512,8678,-681,-1720,7769,-747,-1911,7805,-620,-1698,8714,-556,-1586,9217,-514,-542,10278,-852,-436,11314,1545,-916,11335,1368,-451,10981,1552,-964,11004,1373,-1263,11351,1068,-1311,11020,1073,-1401,11357,507,-1449,11027,507,-1263,11351,-49,-1311,11020,-87,-1606,10410,420,-1421,10403,-151,-1653,10137,384,-1480,10072,-163,-1711,9856,308,-1518,9727,-215,-1770,9679,201,-1587,9469,-334,-1858,9319,173,-1627,9171,-352,-1994,8751,145,-1687,8708,-375,-2190,7847,105,-1854,7804,-504,-2331,6931,51,-2009,6891,-563,-2433,6185,-26,-2130,6150,-647,-2481,5798,-97,-2183,5763,-707,-2531,5435,-167,-2226,5398,-771,-2568,5023,-272,-2264,5062,-837,-2705,4188,-409,-2425,4154,-972,-2779,3259,-487,-2515,3228,-1022,-2913,2546,-554,-2600,2679,-1083,-3070,1969,-615,-2770,2053,-1123,-3090,1373,-705,-2813,1236,-1223,-3194,802,-799,-2754,587,-1378,-3204,678,-795,-2746,478,-1380,-2524,1122,-641,-3391,768,-143,-3183,830,394,-2878,828,576,-2468,762,448,-2865,929,559,-3171,931,376,-3381,887,-152,-3209,1479,-106,-2966,1546,326,-2650,1403,462,-2459,881,437,-2020,670,-88,-2014,794,-94,-2329,1264,281,-1998,1145,-226,-2098,1495,292,-1849,1445,-257,-2039,2054,282,-1766,2026,-243,-1766,1514,-764,-1717,2038,-843,-1482,2962,-139,-1458,2985,-739,-1911,2169,-1168,-1731,3062,-1098,-2203,2299,-1247,-1939,1683,-1155,-1961,1124,-1160,-2344,1171,-1323,-2189,494,-1400,-1797,492,-1166,-1858,1061,-829,-1686,580,-739,-1690,471,-750,-1816,369,-1157,-2199,371,-1385,-2139,3155,-1207,-1596,3978,-1030,-1262,3888,-660,-1126,4801,-532,-1449,4888,-881,-1990,4068,-1136,-1860,4982,-991,-1366,5214,-811,-1071,5133,-462,-1017,5496,-394,-1273,5569,-743,-1801,5313,-927,-1727,5672,-865,-1209,5952,-682,-948,5879,-331,-787,6611,-235,-1085,6694,-606,-1669,6058,-805,-1563,6803,-734,-908,7603,-572,-571,7517,-169,-352,8477,-120,-678,8514,-480,-1398,7715,-702,-1233,8605,-577,-627,8753,-524,-305,8662,-110,-278,8781,-105,-598,8907,-552,-67,8791,-131,-71,8706,375,161,8760,-128,49,8636,401,190,8638,-144,100,8528,418,247,8448,-172,184,8368,438,604,7469,-339,593,7385,345,865,6569,-456,830,6496,233,1046,5847,-583,1018,5775,106,1129,5470,-665,1128,5233,-1,1196,5113,-751,1147,4926,-80,1263,4787,-837,1255,4649,-210,1426,3886,-1011,1405,3822,-385,1643,2992,-1130,1613,2929,-533,1927,2057,-1270,1921,2005,-671,2012,1511,-1293,2015,1427,-715,2156,1132,-717,2112,1069,-1342,1977,567,-1315,2180,486,-1709,2200,363,-1696,2623,378,-1836,2613,501,-1852,3153,499,-1712,3158,608,-1707,3468,705,-1041,3455,828,-1046,3121,1272,-1574,2670,1205,-1750,2265,1146,-1651,2220,1710,-1618,2148,2210,-1567,1946,3095,-1456,1790,4003,-1342,2361,3200,-1521,2191,4105,-1405,2718,3264,-1298,2607,4184,-1196,2930,3263,-740,2834,4184,-609,2420,5079,-1018,2033,5005,-1214,1615,4900,-1149,1520,5219,-1065,1962,5331,-1134,2370,5410,-935,2671,5007,-431,2617,5410,-304,2315,5770,-851,1877,5684,-1056,1416,5568,-984,1340,5946,-904,1196,6679,-792,1807,6064,-977,1682,6802,-868,2250,6150,-772,2109,6883,-651,2494,6148,-124,2372,6886,-7,1934,7788,-548,1500,7707,-792,987,7581,-710,623,8469,-530,1253,8566,-613,1737,8678,-376,2212,7795,92,1997,8692,172,1671,9140,-329,1157,8816,-605,558,8707,-559,530,8862,-582,1099,8970,-597,1625,9435,-296,1850,9255,223,1751,9608,264,1498,9633,-194,1028,9318,-699,509,9159,-751,-55,9056,-488,-556,9202,-725,-43,9315,-754,497,9698,-760,1022,9770,-651,1467,9948,-150,1010,10220,-579,495,10176,-716,-22,9781,-760,-549,9747,-760,-1050,9384,-689,-1126,9033,-580,-1160,8866,-579,-1065,9867,-651,-491,10221,-720,0,10199,-718,30,10959,-478,417,10942,-478,45,11292,-427,432,11274,-427,929,10919,-489,912,11252,-427,1373,10898,-87,1354,11232,-49,1511,10892,507,1492,11226,507,1373,10898,1073,1354,11232,1068,1025,10914,1373,1007,11248,1368,512,10937,1552,528,11270,1545,30,10959,1552,45,11292,1545,-128,11833,1562,451,11831,1610,346,12782,1629,372,13434,1624,324,13993,1562,357,14576,1356,-256,14608,1189,-833,14564,923,-316,14007,1371,-282,13416,1480,-915,13425,1229,-257,12777,1518,-5,10199,1534,-499,10221,1533,-1065,10326,1393,-1471,10397,1009,-1517,10115,991,-1625,9843,902,-1711,9632,815,-1834,9285,764,-1979,8719,734,-2164,7815,660,-2306,6902,554,-2423,6160,453,-2468,5880,436,-2508,5670,425,-2597,5153,400,-2609,4796,219,-2725,4165,157,-2810,3238,87,-2915,2673,13,-3081,2068,-25,-2660,2319,396,-2624,1805,488,-2357,2186,477,-2168,3077,544,-2576,3171,435,-2434,4084,533,-2040,3994,639,-1753,2996,370,-1563,3899,469,-1299,3866,-32,-1175,4705,101,-1083,4991,221,-1074,5303,281,-981,5853,362,-813,6584,458,-597,7482,533,-254,8417,503,-188,8558,455,-172,8655,426,-68,8780,956,-359,8765,985,-55,9056,1394,-936,9116,1411,-32,9571,1489,-692,9616,1502,-1263,9745,1330,-1444,9466,1209,-1544,9142,1184,-1671,8634,1157,-1875,7732,1090,-2023,6819,996,-2119,6074,885,-2191,5635,818,-2240,5342,764,-2336,4925,736,-2365,4647,603,-1953,4553,714,-1470,4535,524,-1441,4889,710,-1371,5267,732,-1301,5602,751,-1242,5890,770,-1084,6622,882,-876,7526,999,-694,8436,1064,-517,8626,1029,-985,8881,1379,-1097,8517,1328,-1345,7613,1230,-1545,6710,1124,-1659,5969,1008,-1731,5574,953,-1807,5141,881,-1901,4826,852,-1119,10044,1378,-542,9941,1513,-17,9902,1513,505,9892,1514,608,9530,1494,823,8980,1370,222,8725,956,416,8536,959,873,8749,1331,619,8310,953,811,7406,845,1045,6509,684,1240,5788,537,1306,5502,505,1383,5170,471,1461,4795,432,1513,4455,226,1621,3825,139,1835,2933,0,2143,2001,-121,2211,1444,-142,2403,1238,-155,2152,782,-614,1986,458,-1325,2160,659,-607,2744,1133,-1047,2478,756,14,2849,832,228,2837,933,209,2468,875,2,2692,1375,80,2654,1774,118,2441,2124,110,2230,3007,217,2079,3914,358,1977,4466,461,1907,4728,611,1806,5039,652,1715,5466,744,1633,5855,818,1496,6586,970,1265,7480,1120,992,8383,1264,1447,9010,1190,1343,9333,1225,1179,9624,1344,1079,9938,1384,1052,10226,1402,486,10177,1536,1466,10265,1018,1487,9981,1001,1560,9720,939,1629,10004,403,1604,10273,433,1434,10282,-133,1675,9743,345,1641,9521,864,1773,9182,807,1928,8621,753,1581,8507,1143,1810,7611,1033,1981,6709,894,2099,5973,745,2185,5541,656,2243,5252,589,2349,4840,542,2395,4572,396,2480,4015,295,2645,3112,152,2747,2265,66,3025,1526,1,3175,945,96,3186,844,116,3507,793,-363,3496,911,-374,3335,1479,-393,3209,2047,-330,3254,1988,-923,3083,2557,-840,2818,2721,-1386,3001,2102,-1450,3312,1394,-1010,2444,2349,-1610,3030,2647,-267,2909,3204,-167,2803,4124,-45,2670,4747,46,2635,5092,248,2555,5768,-215,2536,5605,298,2491,5813,319,2440,6091,350,2302,6823,487,2136,7726,639,-355,10977,-478,-1002,10311,-585,-868,11000,-489,-340,11309,-427,-820,11331,-427,-1054,11349,-717,-1203,11352,-552,28,13978,-1156,-647,13919,-1221,-890,13534,-1027,-792,15129,-1314,-865,14558,-1409,-1062,14093,-1181,-1115,14208,-1132,-1516,13976,-532,-1724,13989,145,-1646,14078,335,-1513,14618,461,-1443,15053,262,-1289,15422,-38,-1181,15588,-454,-1571,15440,-958,-1248,15087,-1316,-1045,14618,-1433,-1144,14316,-1181,-1463,14077,-576,-1732,14114,117,-1607,14560,265,-1592,14977,159,-1599,15277,-149,-1845,15020,-266,-1693,14819,27,-1610,14500,-139,-1879,14675,-340,-1869,15221,-570,-1961,14830,-714,-1900,14432,-462,-2046,14465,-792,-1856,14056,-603,-2042,14234,-888,-1927,13556,-844,-2088,13712,-1122,-2006,12957,-1163,-1712,12851,-1042,-1823,12487,-1329,-2122,12530,-1388,-2174,13108,-1430,-2292,12680,-1694,-2179,12570,-1653,-2375,12410,-1839,-2290,12803,-2061,-2342,12571,-2150,-2391,12332,-2168,-2428,12091,-2075,-2199,12260,-2394,-2243,11919,-2264,-1888,12214,-2471,-1835,12564,-2469,-1533,12494,-2360,-1483,12753,-2276,-1295,12618,-1960,-1188,13068,-1698,-1372,13253,-2031,-1783,12838,-2394,-2144,12593,-2389,-2091,12857,-2311,-1971,13371,-2069,-2170,13286,-1814,-2090,13883,-1490,-2005,14395,-1276,-1992,14624,-1185,-1910,14915,-1103,-1818,15270,-977,-1602,15441,-540,-1527,15026,-1351,-1172,14601,-1478,-1228,14559,-1480,-1145,14496,-1226,-1179,14341,-797,-1447,14326,-189,-1539,14409,-49,-1550,14508,103,-1162,14127,-362,-844,14155,-646,-911,13907,-828,-1175,13863,-534,-1528,14163,-313,-1524,13914,-469,-1603,13437,-705,-1407,12839,-1125,-1515,12467,-1411,-1547,12555,-1633,-1860,12618,-1560,-1879,12487,-1284,-2193,12396,-1362,-2401,12165,-1562,-2432,11860,-1827,-2254,11644,-2014,-1933,11857,-2337,-1577,12211,-2369,-1370,12261,-2088,-1317,12497,-1607,-1208,12924,-1380,-1052,13520,-1083,-1055,13670,-1403,-1214,13847,-1728,-1666,13358,-2152,-1547,13966,-1866,-1076,14275,-1516,-911,14069,-1205,-838,14318,-1065,-977,14530,-1311,-1412,14423,-1631,-1874,13980,-1777,-1751,14469,-1538,-1660,14751,-1479,-1633,14861,-1429,-1330,14675,-1435,-1277,13424,-793,-1360,12405,-1845,-1395,12195,-1540,-1574,12410,-1352,-1621,12086,-977,-1919,12161,-910,-2225,12076,-983,-2437,11828,-1197,-2463,11541,-1446,-2287,11335,-1626,-1949,11567,-2082,-1989,11260,-1692,-1634,11658,-2004,-1684,11345,-1619,-1415,11916,-1781,-1474,11585,-1412,-1445,11879,-1156,-1532,11463,-690,-1690,11671,-510,-1967,11741,-448,-2259,11647,-528,-2454,11424,-721,-2477,11159,-951,-2319,10951,-1132,-2041,10881,-1194,-1750,10975,-1113,-1555,11197,-921,-1595,10860,-511,-1566,11131,-276,-1713,11340,-94,-1980,11407,-35,-2265,11307,-121,-2458,11078,-319,-2487,10807,-553,-2340,10598,-735,-2073,10531,-795,-1789,10631,-709,-1761,10281,-164,-1598,10603,-99,-1596,10953,6,-1755,11199,113,-2016,11246,179,-2278,11077,180,-2441,10756,114,-2443,10405,8,-2284,10159,-98,-2023,10112,-164,-2238,10325,-150,-2352,10505,-73,-2349,10761,4,-2345,10714,187,-2352,10428,101,-2235,10230,18,-2051,10291,-198,-2040,10195,-31,-2012,10657,88,-2217,10977,241,-2231,10997,52,-2017,11118,244,-2042,11122,53,-1821,11082,195,-1855,11088,5,-1705,10884,111,-1712,10599,26,-1840,10336,-28,-1862,10416,-197,-1743,10651,-149,-1741,10908,-72,-1617,11928,-2265,-417,16175,-87,-343,16389,-204,-58,16479,-437,86,16741,-519,-147,16701,-458,-408,16624,-213,-495,16570,-138,-500,16353,-19,-458,16221,80,-549,16123,406,-548,16023,595,-534,15953,751,-439,15943,846,-323,15950,915,-167,16018,892,-116,16129,960,-286,16052,989,-235,16208,1032,-328,16153,1023,-282,16298,1047,-375,16258,1023,-380,16333,1078,-454,16318,1062,-460,16377,1046,-553,16366,1000,-459,16375,997,-530,16362,970,-549,16371,996,-489,16387,1043,-370,16361,1033,-407,16373,1076,-337,16367,1066,-328,16390,1085,-390,16411,1093,-513,16432,1078,-586,16401,1043,-597,16455,1059,-637,16434,981,-610,16389,949,-573,16377,909,-629,16365,831,-661,16377,877,-682,16415,865,-689,16395,803,-670,16372,807,-696,16365,731,-681,16362,753,-666,16303,747,-664,16214,698,-634,16158,785,-612,16057,734,-624,16137,563,-603,16237,277,-589,16547,-57,-582,16562,-153,-615,16783,-108,-738,16743,159,-647,16430,194,-739,16409,438,-678,16263,450,-718,16339,616,-712,16366,693,-726,16443,742,-671,16500,865,-616,16528,986,-642,16477,991,-572,16510,1027,-521,16526,1060,-588,16564,1049,-626,16585,983,-660,16616,885,-670,16673,875,-678,16621,952,-668,16610,973,-653,16617,1033,-644,16589,1080,-627,16585,1099,-604,16588,1111,-515,16583,1070,-556,16616,1109,-605,16623,1186,-495,16607,1109,-471,16618,1114,-576,16649,1185,-649,16666,1207,-636,16614,1166,-697,16661,1191,-689,16725,1181,-725,16667,1148,-690,16615,1124,-668,16605,1153,-715,16625,1100,-722,16652,1072,-687,16696,942,-650,16754,974,-721,16709,1054,-725,16723,1125,-652,16784,1135,-678,16774,1082,-637,16872,1036,-641,16801,934,-649,16767,875,-757,16745,641,-779,16574,621,-751,16422,616,-792,16609,433,-768,16924,248,-806,16776,439,-784,16904,513,-726,16860,670,-622,16913,766,-580,16977,874,-595,16962,984,-568,16975,1032,-609,16886,1082,-558,16871,1098,-594,16773,1148,-625,16721,1203,-559,16707,1181,-457,16692,1121,-398,16669,1087,-411,16612,1079,-391,16496,1084,-520,16475,1086,-259,16436,1106,-257,16359,1073,-283,16356,1064,-294,16357,1057,-297,16364,1041,-310,16360,1045,-385,16363,1050,-304,16349,1062,-216,16358,1080,-141,16330,1066,8,16252,986,37,16397,1045,-132,16413,1099,-126,16564,1130,-148,16736,1116,-401,16763,1068,-459,16798,1076,-497,16752,1093,-516,16961,1045,-554,17042,1014,-594,17039,967,-607,17035,888,-587,17040,831,-587,16987,790,-629,16989,737,-740,16916,682,-745,16960,668,-737,16967,657,-606,16997,721,-741,17053,663,-793,16993,533,-801,16976,527,-806,16953,524,-800,16986,394,-742,17129,104,-658,17132,-38,-613,17039,-139,-565,16811,-286,-576,16629,-259,-569,16751,-375,-481,16762,-381,-490,16630,-250,-460,16977,-316,-545,17161,-289,-557,17111,-204,-614,17114,-240,-613,17148,-356,-543,17154,-341,-587,17084,-473,-518,17084,-462,-568,16901,-493,-495,16898,-474,-728,17527,239,-850,17207,434,-847,17124,456,-811,17056,368,-812,17048,448,-810,17033,499,-799,17061,574,-756,17063,682,-675,17056,738,-658,17076,745,-744,17097,668,-798,17099,572,-819,17167,621,-741,17156,735,-644,17093,799,-590,16988,767,-662,17117,880,-636,17144,983,-578,17148,1047,-498,17037,1042,-418,17032,1035,-412,16974,1005,-299,16908,1018,-182,16852,1095,-14,16892,1114,-19,16941,1138,-188,16908,1113,-23,16964,1134,-173,16951,1115,-164,16958,1104,-30,16982,1129,-168,17044,1111,-258,16991,993,-268,16983,1019,-306,16984,989,-256,17050,1065,-330,16983,991,-266,17070,1050,-182,17054,1130,-67,17050,1146,-171,17089,1116,-322,17088,1051,-235,17148,1130,-395,17113,1088,-276,17197,1159,-494,17225,1079,-501,17142,1088,-568,17233,1035,-627,17227,975,-758,17204,782,-833,17244,643,-796,17370,585,-746,17566,518,-606,17338,942,-541,17339,1004,-503,17538,959,-578,17545,884,-541,17791,733,-407,17790,840,-412,17542,1014,-466,17336,1052,-73,17359,1150,-15,17555,1088,-270,17787,945,-104,18038,724,-241,18058,634,209,18159,58,-363,18041,523,-39,18108,-96,235,17921,-502,-158,17815,-496,524,17968,-349,742,17914,-106,418,18101,261,184,17983,737,34,17792,959,248,17512,1002,83,17193,1163,-122,17234,1198,-105,17157,1178,-65,17088,1145,7,17021,1137,57,17035,1127,60,17111,1164,375,17112,977,135,17042,1107,106,16972,1101,238,16909,1034,59,16763,1115,59,16596,1098,252,16416,896,484,16531,781,314,16728,981,494,17115,861,630,17093,722,387,17710,838,494,17829,677,744,17610,497,864,17395,409,1025,17507,112,829,17801,275,557,17962,479,899,17142,345,713,16959,599,711,17142,690,777,16743,601,760,17134,676,792,17126,740,898,17062,685,871,17063,621,909,16879,660,792,16730,688,706,16792,706,679,17094,769,580,17021,791,545,16765,797,576,16545,751,649,16612,639,679,16610,721,873,16877,594,-53,17523,-729,-87,17109,-669,-255,17160,-556,-304,17413,-503,-356,17626,-361,-466,17844,-72,-599,17725,68,-629,17802,441,-446,17993,245,-287,17975,-179,-368,17037,1002,-608,16007,843,-515,15997,944,-394,16004,1010,-430,16113,1031,-533,16118,970,-617,16116,884,-591,16214,883,-522,16229,958,-433,16212,1006,-451,16249,1029,-542,16248,984,-563,16311,1012,-638,16321,918,-608,16251,906,-620,16262,832,-671,16337,851,-620,16380,921,-643,16367,849,-656,16365,776,-655,16369,762,-672,16363,763,-673,16355,773,3564,421,1379,3084,333,1415,3093,46,1411,3364,537,774,3858,417,610,3209,688,312,3764,531,128,3778,83,122,3590,358,-283,3435,717,-231,3265,765,-700,3148,1240,-682,2911,1239,-1186,2568,1190,-1102,2398,1189,-1459,2688,1227,-1455,2954,762,-1235,3337,295,-766,3598,83,-286,3228,64,305,3868,80,606,2814,43,956,2614,42,509,2600,490,514,2804,381,960,3575,61,1375,3921,362,1120,3929,76,1116,3060,835,-40,2805,1184,-492,2376,1128,-494,2210,1138,-1015,2210,1159,-1361,2340,746,-1508,2663,756,-1528,3019,336,-1257,3027,77,-1260,2691,71,-1587,2571,61,-1109,2856,64,-607,2095,44,-951,2319,45,-429,2849,278,-604,2312,259,-426,3071,64,-112,2483,44,83,2475,319,86,2561,687,58,2374,734,-404,2143,733,-966,2087,303,-948,2068,308,-1415,2076,49,-1418,2337,59,-1569,2329,318,-1566,2683,329,-1584,2119,738,-1376,3344,81,-769,-3814,403,1550,-3814,43,1547,-3352,41,1687,-4104,333,1220,-4105,46,1218,-3935,50,732,-3934,387,735,-3491,522,1001,-3243,675,582,-3742,501,283,-3025,824,268,-3348,695,1,-2670,1191,-108,-2977,1233,-351,-2344,1180,-670,-2668,1220,-808,-2122,1171,-994,-2407,1203,-1037,-2314,750,-1097,-2003,749,-1008,-1952,1148,-868,-2005,1139,-526,-2248,1144,-41,-2556,690,474,-2688,494,913,-2980,382,1305,-3351,328,1689,-2981,44,1302,-2688,47,909,-2469,49,521,-2468,325,524,-2197,267,59,-2274,740,62,-1866,315,-402,-1928,744,-436,-1816,747,-831,-1969,321,-1057,-1746,319,-853,-1747,60,-855,-1969,62,-1060,-2297,59,-661,-1866,56,-404,-2198,53,57,-2683,270,-231,-2683,56,-232,-3125,273,-495,-3125,59,-496,-2709,62,-908,-2709,321,-906,-2311,63,-1154,-2310,322,-1152,-2662,749,-874,-3081,745,-419,-3477,332,-78,-3478,56,-80,-3001,53,203,-3244,50,577,-3491,47,997,-3742,53,280,829,17364,-414,787,17721,-207,923,17380,-256,744,17351,-516,587,17757,-426,636,17359,-599,779,16950,-623,889,16970,-561,992,16947,-405,1029,16950,-297,1027,16898,-101,991,17320,-78,916,17690,66,1036,17325,50,902,17683,260,975,17329,376,751,17730,537,782,17355,623,881,17098,514,817,17034,530,840,16764,493,913,16767,467,854,16654,476,925,16662,457,942,16531,476,892,16516,489,1001,16377,514,1056,16847,292,1071,16875,59,1107,16647,-131,1149,16618,-1,1223,16544,-257,1278,16506,-160,1476,16309,-248,1118,16629,210,1128,16624,37,1265,16514,35,1195,16511,-10,1446,16368,-3,966,16612,423,1090,16619,277,1062,16499,382,1111,16528,281,1306,16416,151,1131,16632,-130,1124,16689,-335,1056,16727,-464,984,16717,-603,860,16682,-680,855,16538,-816,991,16533,-746,991,16552,-745,1006,16364,-989,1099,16593,-599,1158,16588,-520,1321,16396,-608,1189,16535,-403,652,16955,-729,806,16713,-708,621,16730,-834,726,16568,-876,634,16522,-871,576,16399,-1115,495,16755,-911,435,16562,-997,364,16580,-1070,255,16580,-1029,201,16439,-1251,344,16764,-857,480,16978,-816,417,17386,-668,326,17728,-567,339,17370,-717,382,16956,-810,198,16934,-884,169,16766,-886,-14,16486,-1035,-89,16517,-1041,-267,16301,-1201,-206,16477,-995,8,16731,-854,-27,16920,-818,120,17321,-741,28,17703,-626,-30,17312,-759,-242,16938,-703,-201,16727,-796,-336,16531,-952,-236,16546,-992,-510,16410,-1045,-286,17344,-609,-156,17699,-566,-387,17748,-350,-484,17374,-365,-396,17133,-547,-365,16931,-596,-334,16652,-702,-241,16650,-788,-421,16526,-765,-376,16554,-792,-604,16285,-858,-478,16521,-675,-317,16631,-634,-392,16888,-545,-402,17109,-507,891,16985,-473,903,17340,-271,953,16993,-284,785,16988,-588,674,17356,-545,693,16989,-660,683,16576,-627,857,16527,-512,923,16530,-396,930,16583,-290,1003,16546,-92,1015,17000,-36,1006,17324,56,1022,17011,119,945,17330,352,1019,17027,321,919,17056,466,782,17355,623,851,17063,514,728,16607,512,840,16597,477,690,16437,494,793,16429,486,810,16341,441,730,16306,470,810,16138,562,958,16579,334,889,16420,448,989,16477,247,993,16379,349,1029,16374,272,1192,16212,291,1015,16558,100,1040,16457,-200,1089,16462,-71,1099,16329,-173,1131,16335,-93,1220,16138,-112,1040,16473,181,1073,16466,15,1114,16370,147,1112,16372,51,1264,16217,97,1008,16455,-272,966,16450,-407,856,16448,-506,1017,16187,-442,1061,16188,-394,1076,16192,-301,1116,16027,-307,813,16443,-668,694,16442,-747,757,16179,-774,844,16179,-734,864,16181,-658,822,15995,-760,549,16536,-680,646,16442,-779,424,16446,-825,633,16178,-878,509,16181,-890,572,16032,-948,270,16447,-884,315,16184,-938,239,16185,-955,225,16077,-988,164,16187,-945,104,16455,-819,335,16583,-788,433,16999,-741,353,17348,-700,365,17002,-781,228,16590,-754,102,16590,-851,125,17019,-808,9,17339,-721,19,17028,-780,30,16565,-782,-72,16458,-861,-14,16194,-906,-97,16196,-908,-95,15971,-975,-180,16200,-876,-191,16464,-794,-187,16614,-637,-396,16472,-734,-443,16279,-849,-358,16275,-888,-479,16155,-947,-181,17053,-673,-262,17348,-589,-484,17374,-365,-346,17070,-600,-293,16599,-619,-458,16478,-598,-352,16473,-664,-469,16283,-694,-402,16281,-715,-426,16081,-783,-408,16286,-600,-423,16481,-500,-308,16605,-553,-390,17080,-521,-374,16610,-538,-384,16459,-505,-379,16439,-543,-528,16306,-458,-375,16617,-445,-375,16448,-415,-382,16443,-489,-491,16264,-244,-52,17311,-642,81,16923,-752,-153,16899,-674,389,16943,-680,285,17370,-614,566,16971,-627,605,17396,-453,753,16966,-488,607,16415,-532,867,16936,-307,836,17361,-184,603,17396,-455,944,17296,135,1011,16909,-26,992,16881,219,886,17233,425,725,17178,692,929,16878,429,875,16845,437,803,16285,273,931,16311,205,1005,16098,140,935,16038,143,1196,15871,-11,1044,16105,58,901,16333,73,883,16364,-105,904,16384,-200,817,16399,-332,771,16405,-388,835,16185,-467,927,16171,-357,1001,16154,-240,969,16133,-121,983,16106,11,1243,15893,-166,1102,15999,-233,1100,16011,-294,1039,16021,-385,1302,15893,-407,976,16022,-424,897,16036,-540,822,16053,-673,648,16193,-601,405,16413,-629,431,16194,-727,640,16058,-802,507,16055,-858,674,15831,-1008,259,16186,-789,438,16053,-888,286,16037,-882,390,15860,-1117,146,16024,-888,205,15840,-1108,117,16172,-810,229,16406,-691,158,16401,-700,0,16386,-705,-20,16156,-811,79,16023,-921,-29,16013,-925,-43,15897,-1158,-89,16000,-891,-104,16135,-721,-69,16366,-637,-230,16335,-559,-224,16109,-663,-216,15897,-980,-358,16314,-515,-331,16100,-606,-296,16108,-691,-322,15875,-858,-311,16046,-585,-357,16296,-422,-341,16897,-562,-541,17197,-296,-320,17251,-517,-336,16863,-508,1038,15859,-755,1128,15838,-592,851,17921,-204,761,17907,-328,614,18156,-82,945,17680,-302,997,17678,-242,1056,17625,4,947,17902,53,670,18152,117,394,18242,183,354,18255,75,574,18155,-144,585,17897,-475,676,17680,-599,853,17703,-442,970,17368,-416,1106,17396,-307,1060,17337,-68,1059,17606,174,919,17876,207,678,18137,239,358,18226,307,244,18193,247,279,18197,138,284,18245,21,434,18161,-244,536,17905,-500,561,17688,-659,726,17320,-661,894,17359,-559,950,17087,-586,934,17120,-666,826,17092,-705,1050,16897,-803,585,17334,-749,710,17125,-705,626,17122,-799,749,16901,-913,381,17396,-866,534,17120,-897,436,17134,-947,475,16945,-1051,335,17136,-902,237,17369,-821,344,17712,-779,328,17929,-603,311,18176,-275,270,17916,-588,244,17693,-732,-28,17682,-748,28,17385,-855,225,17154,-881,78,17167,-913,178,16945,-1096,12,17133,-856,-103,17372,-758,-98,17655,-700,14,17952,-574,104,18170,-278,-29,17939,-543,-275,17667,-624,-252,17376,-706,-198,17063,-750,-114,17075,-795,-132,16864,-901,-399,17382,-650,-346,17234,-730,-262,17247,-759,-296,17106,-863,-365,17193,-704,-418,17362,-610,-422,17661,-538,-425,17618,-468,-351,17971,-338,-393,17951,-284,-489,17626,-424,-545,17380,-499,-567,17370,-441,-730,17134,-502,-487,17597,-341,-604,17346,-370,-594,17372,-435,-719,17132,-370,-436,17957,-219,-574,17602,-300,-679,17202,-273,-712,17224,-179,-738,16941,-133,-760,16976,-67,-799,16747,63,-826,16781,118,-887,16571,334,-813,16806,170,-765,17012,30,-743,17231,-79,-661,17542,-141,-740,17528,-21,-788,17218,33,-801,17045,107,-799,17021,39,-846,16823,198,-601,17922,0,-786,17564,197,-826,17267,264,-797,17237,39,-885,17005,297,-862,16968,164,-925,16770,351,-829,17588,247,-887,17273,275,-869,17033,330,-865,17267,357,-812,17576,316,-854,17623,434,-909,17295,451,-903,16927,560,-883,17269,566,-830,17565,583,-719,17782,623,-742,17900,465,-538,17992,657,-556,18002,804,-714,17788,797,-833,17542,614,-844,17503,719,-879,17261,628,-525,17884,926,-681,17673,925,-836,17533,766,-795,17461,871,-875,17334,717,-829,17309,775,-877,17069,678,-513,17883,995,-652,17638,1019,-756,17431,897,-754,17398,970,-839,17143,807,-503,17883,1079,-654,17623,1107,-743,17393,980,-727,17383,1062,-835,17081,883,-639,17369,1086,-481,17602,1109,-392,17793,1082,-309,18055,913,-340,18048,841,-109,18118,696,-142,18149,660,-80,18118,635,-141,18144,607,-91,18206,535,-18,18140,571,43,18141,503,-37,18240,462,27,18269,372,119,18201,422,115,18267,258,203,18192,313,175,18259,186,236,18251,99,192,18272,-7,72,18291,47,-70,18190,-190,-194,17983,-465,-224,18178,-87,-236,18191,-37,-330,18145,77,-534,17913,-105,-392,18097,179,-696,17911,202,-723,17907,257,-705,17867,322,-559,18093,504,-489,18114,346,-288,18190,437,-199,18225,331,-136,18261,244,-32,18288,125,-339,18184,557,-368,18110,624,-376,18132,756,313,18212,394,537,18133,507,632,18126,369,844,17850,386,794,17829,549,748,17832,571,615,17829,694,454,18116,603,233,18206,492,145,18173,575,83,18176,651,7,18131,692,-65,18106,708,-81,18115,738,-52,18137,695,-96,18100,954,-15,18133,923,-36,18025,1110,19,18052,1092,42,17917,1229,-28,18144,685,41,18094,924,128,18116,886,151,17932,1088,206,17958,1057,197,17755,1201,-88,18001,950,-185,18023,980,-239,17994,921,-361,17800,1124,-455,17602,1173,-534,17414,1104,-540,17407,1163,-599,17196,1069,-418,17628,1242,-495,17393,1243,-582,17135,1132,-341,17368,1217,-264,17585,1193,-197,17759,1126,-312,17812,1191,-100,17770,1116,-136,17557,1200,-211,17345,1238,-364,17194,1210,69,17836,1126,29,18076,930,118,18013,896,177,18047,832,253,18092,802,317,18059,699,490,17836,827,410,17898,933,323,17846,988,196,17812,1049,59,17596,1219,-73,17341,1231,45,17334,1262,0,17141,1210,95,17324,1194,159,17544,1135,348,17543,1060,328,17230,1122,181,17300,1157,172,16992,1213,478,17549,1013,516,17506,908,415,17168,1102,296,17001,1150,430,17123,990,711,17525,785,824,17499,690,798,17264,784,647,17290,820,662,16988,902,570,17008,922,487,16740,1045,864,17493,614,863,17269,731,809,17285,761,855,17071,937,915,17496,572,937,17311,677,889,17302,704,967,17114,865,998,17550,353,1061,17317,316,1121,17350,123,1113,17151,-61,1160,17192,56,1113,17126,167,1254,16955,-61,975,17341,534,1034,17349,339,1040,17214,440,1033,17259,324,1135,17073,278,586,17097,955,421,16810,1097,1146,17149,-241,1138,17168,-368,1077,17143,-460,1236,16913,-559,895,17086,-566,818,17364,-481,937,17091,-442,687,17347,-590,783,17061,-625,966,16880,-678,987,16885,-584,1012,16734,-788,892,16859,-709,588,17757,-426,922,17367,-343,807,17718,-232,1014,17371,-229,955,17686,55,1073,17330,20,930,17682,282,1038,17314,271,970,17315,435,877,17341,595,769,17730,552,780,17357,655,548,17431,877,547,17796,771,481,17154,935,608,16994,810,530,16859,943,456,16910,971,362,16629,1034,606,16868,866,521,16642,910,469,16676,969,375,16471,1008,771,17046,656,867,17041,540,1066,17106,291,1084,16859,254,1016,16860,393,1184,16626,268,1086,17066,-30,1117,17015,116,1175,16878,-46,1178,16854,55,1289,16726,-76,1053,17127,-232,1004,17101,-358,1145,16915,-315,1052,17030,-109,1164,16917,-229,1298,16767,-360,1133,16891,-377,563,17364,-707,404,17371,-775,428,17100,-846,574,17088,-845,659,17060,-750,661,16888,-959,569,16894,-953,749,16676,-993,709,16866,-894,272,17134,-883,258,16979,-988,356,16951,-954,247,16839,-1165,187,16975,-957,125,17142,-872,23,17346,-793,242,17376,-798,340,17726,-585,65,17697,-673,-183,17699,-588,-206,17333,-701,68,17081,-826,-126,17039,-779,60,16895,-917,-54,16875,-876,43,16744,-1050,-348,17335,-594,-214,17125,-716,-427,17064,-530,-231,16880,-748,-330,16879,-673,-279,16648,-875,-480,17362,-465,-403,17748,-364,-529,17377,-368,-544,17058,-331,-650,17028,-213,-731,17153,31,-739,16882,11,-690,16841,-117,-717,16665,2,-744,16699,80,-770,16493,172,-775,16921,82,-807,16651,179,-672,17449,-76,-559,17813,-92,2216,8858,1665,2119,8931,1730,2140,8884,1642,2180,8913,1769,2287,8901,1680,2248,8947,1758,2400,9094,1580,2311,9160,1699,2320,9185,1694,2419,9114,1571,2295,9074,1528,2178,9106,1520,2307,9094,1514,2185,9125,1503,2238,9254,1364,2175,9477,1466,2130,9203,1606,2128,9179,1617,2220,9175,1678,2224,9200,1670,2283,9492,1563,2354,9684,1370,2216,9638,1261,2495,9799,1268,2360,9781,1180,2544,9887,1209,2426,9873,1126,2435,10110,1016,2436,10058,869,2406,9817,980,2473,9766,876,2517,10017,773,2555,9963,627,2489,9704,727,2618,9657,650,2694,9928,565,2617,10234,555,2765,10212,507,2832,9923,593,2903,10219,552,2936,9935,660,3009,10234,617,2975,9980,828,3013,10290,800,2901,10347,968,2902,10041,986,2687,10397,1094,2694,10126,1145,2535,10389,1044,2565,10139,1114,2440,10360,934,2463,10313,786,2558,10281,698,2698,9869,1224,2661,9779,1309,2563,9677,1450,2439,9456,1639,2545,9260,1561,2349,9205,1471,2409,9012,1610,2332,9024,1529,2425,9324,1149,2500,8973,1380,2483,9240,1024,2589,8885,1216,2536,9193,887,2665,8837,1038,2705,9100,766,2752,8809,890,2820,9087,805,2602,9545,672,2754,9532,687,2757,9639,662,2863,9649,731,2873,9545,759,2933,9682,882,2463,9597,756,2439,9609,924,2359,9717,1021,2258,9468,1133,2873,9763,1066,2887,9662,1103,2684,9328,1471,2673,8927,1499,2525,9016,1637,2412,8716,1662,2347,8713,1605,2425,8663,1487,2347,8687,1610,2420,8638,1494,2516,8656,1520,2558,8907,1449,2423,8639,1405,2487,8584,1287,2416,8613,1408,2479,8560,1293,2570,8565,1326,2656,8840,1274,2532,8632,1234,2593,8599,1127,2523,8607,1235,2583,8575,1133,2678,8562,1155,2750,8811,1094,2638,8706,1053,2686,8650,952,2626,8682,1053,2671,8628,956,2746,8610,979,2827,8768,917,2921,9099,897,2890,8758,994,2902,9185,1095,2945,9581,920,2830,9257,1267,2778,8852,1327,2585,8610,1511,2487,8636,1478,2603,8657,1585,2505,8706,1686,2501,8680,1689,2411,8690,1666,2333,8444,1654,2391,8416,1546,2326,8419,1654,2383,8392,1548,2458,8396,1568,2511,8630,1526,2595,8632,1591,2442,8413,1714,2375,8434,1701,2367,8409,1700,2221,8225,1618,2242,8185,1661,2304,8156,1541,2353,8155,1586,2309,8174,1670,2504,8359,1622,2448,8372,1569,2516,8382,1622,2268,8204,1529,2433,8389,1713,2480,8611,1480,2352,8378,1445,2411,8345,1342,2339,8357,1444,2397,8324,1342,2467,8308,1366,2561,8540,1330,2649,8556,1395,2637,8532,1399,2576,8584,1511,2391,8356,1502,2377,8335,1499,2179,8210,1385,2189,8165,1419,2254,8135,1311,2291,8112,1359,2251,8133,1430,2497,8262,1421,2442,8293,1516,2457,8312,1520,2513,8281,1423,2452,8288,1365,2232,8189,1300,2597,8620,1300,2587,8595,1301,2444,8430,1240,2497,8401,1156,2429,8409,1236,2480,8382,1154,2335,8287,1111,2348,8222,1111,2535,8330,1168,2552,8348,1171,2668,8538,1158,2749,8546,1216,2860,8820,1148,2689,8584,1337,2762,8624,1135,2695,8672,1099,2681,8650,1097,2517,8559,1027,2569,8528,950,2603,8482,978,2730,8590,983,2789,8588,1043,2772,8568,1045,2746,8604,1132,2544,8519,1069,2524,8504,1063,2498,8542,1022,2548,8513,946,2581,8467,974,2629,8442,1031,2587,8470,1099,2566,8456,1091,2354,8408,990,2373,8461,967,2412,8436,909,2400,8377,920,2607,8428,1026,2403,8378,1018,2429,8354,968,2677,8560,1337,2480,8400,1298,2464,8381,1293,2300,8305,1164,2295,8260,1208,2388,8196,1156,2349,8220,1221,2577,8295,1222,2521,8329,1316,2538,8347,1322,2596,8312,1226,2736,8523,1219,-1737,10726,1062,-1751,10612,1019,-1667,10719,1037,-1819,10645,983,-1797,10736,1015,-1886,10699,777,-1773,10662,780,-1780,10665,754,-1900,10706,753,-1824,10839,834,-1730,10846,831,-1829,10852,812,-1729,10858,807,-1908,11004,567,-1742,10997,509,-1623,10827,783,-1612,10936,479,-1801,10971,262,-1640,10900,220,-1652,10669,290,-1696,10708,564,-1657,10694,752,-1655,10693,779,-1626,10818,808,-1669,10623,1004,-1817,10725,665,-2026,10789,680,-2017,10969,321,-2135,10736,570,-2021,10941,122,-2231,10692,92,-2228,10513,472,-2278,10496,42,-2258,10328,404,-2200,10353,-35,-2228,10124,336,-2110,10070,296,-2096,9930,599,-2177,9963,648,-2043,9873,762,-2104,9894,810,-2090,9884,830,-2030,9864,783,-1941,9813,885,-1978,9816,943,-1957,9808,953,-1920,9805,896,-1735,9755,928,-1771,9762,977,-1711,9834,962,-1730,9852,908,-1890,9902,942,-1856,9907,893,-1752,9788,880,-1883,9824,853,-1903,9833,841,-1964,9882,752,-1976,9892,731,-2016,9953,567,-1990,10073,273,-1965,10097,656,-1856,10255,302,-1795,10412,-98,-1776,10551,-1,-1830,10456,-197,-1822,10612,-151,-1902,10613,-476,-1888,10750,-400,-1923,10873,-704,-1902,10994,-598,-1831,11079,-525,-1822,10851,-351,-1844,10984,-275,-1845,11197,-422,-1979,11038,-254,-1965,11264,-364,-2120,11048,-202,-2124,11273,-355,-2299,10849,-271,-2301,11135,-475,-2347,10705,-359,-2368,10985,-605,-2318,10846,-726,-2283,10570,-454,-2199,10816,-752,-2171,10530,-490,-2055,10808,-760,-2029,10532,-508,-1952,10357,-203,-1928,10306,-104,-2079,10298,-76,-2197,10398,-134,-2273,10531,-59,-2224,10728,-9,-2063,10929,1,-1856,10934,72,-1910,10940,-30,-1718,10864,24,-1790,10875,-77,-1708,10701,-27,-1811,10552,389,-1788,10648,847,-1867,10673,923,-1983,10666,950,-2102,10483,905,-2148,10295,822,-2180,10126,716,-2103,9988,853,-2087,9974,869,-1957,9890,978,-1935,9880,986,-1760,9818,999,-1911,9913,932,-1875,9918,882,-1945,9995,790,-2012,9993,829,-2025,10008,811,-1955,10010,771,-2060,10102,701,-1993,9993,909,-1910,10019,868,-1980,9981,929,-1898,10008,888,-1858,9896,1043,-2055,9996,981,-1907,9897,1107,-1885,9887,1117,-1837,9886,1055,-1649,9828,1104,-1696,9832,1149,-1625,9934,1149,-1676,9902,1181,-1853,9987,1164,-1875,10000,1155,-2021,10113,1044,-2070,10008,963,-2035,10128,1028,-1933,10133,998,-1945,10148,980,-1860,10111,944,-1872,10126,926,-1942,10275,741,-2017,10272,807,-1951,10136,1053,-1870,10146,1010,-1939,10124,1073,-1858,10135,1030,-1773,10014,1226,-2020,10144,1130,-1825,10023,1289,-1804,10012,1301,-1753,10003,1240,-1553,9911,1354,-1600,9925,1396,-1518,10024,1407,-1580,10000,1429,-1774,10113,1346,-1794,10126,1335,-1989,10272,1175,-2035,10155,1111,-2002,10286,1158,-1898,10294,1132,-1910,10309,1114,-1827,10265,1077,-1838,10279,1058,-1920,10471,789,-1978,10459,884,-1899,10345,1090,-1979,10357,1159,-1962,10345,1176,-1884,10332,1108,-1734,10227,1215,-1780,10230,1282,-1759,10217,1292,-1714,10214,1227,-1511,10095,1319,-1560,10110,1362,-1471,10213,1378,-1531,10192,1404,-1709,10320,1328,-1729,10334,1318,-1898,10470,1206,-1911,10485,1190,-1831,10508,1145,-1770,10493,1088,-1819,10360,1040,-1805,10348,1058,-1760,10478,1107,-1820,10493,1163,-1678,10365,1276,-1642,10358,1222,-1682,10252,1167,-1663,10238,1181,-1625,10343,1234,-1659,10350,1288,-1462,10218,1318,-1493,10130,1273,-1837,10394,363,-1763,10728,-128,-2090,10346,-175,-1719,10037,1181,-1688,10146,1229,-1734,10160,1288,-1715,10147,1301,-1670,10134,1244,-1701,10026,1196,-1530,9941,1309,-1500,10029,1352,-1808,9937,997,-1778,10026,1040,-1821,10035,1102,-1801,10022,1112,-1759,10012,1052,-1789,9926,1010,-1642,9877,1059,-1624,9934,1086], diff --git a/examples/obj/male02/Male02_slim.js b/examples/obj/male02/Male02_slim.js index 5cfe7b802601f0..cc67ac46595ad3 100644 --- a/examples/obj/male02/Male02_slim.js +++ b/examples/obj/male02/Male02_slim.js @@ -26,7 +26,7 @@ "mapDiffuse" : "male-02-1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -40,7 +40,7 @@ "mapDiffuse" : "orig_02_-_Defaul1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -54,7 +54,7 @@ "mapDiffuse" : "orig_02_-_Defaul1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -68,7 +68,7 @@ "mapDiffuse" : "01_-_Default1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }, { @@ -82,7 +82,7 @@ "mapDiffuse" : "male-02-1noCulling.JPG", "opticalDensity" : 1.0, "specularCoef" : 154.901961, - "transparency" : 1.0 + "opacity" : 1.0 }], "vertices": [464,15985,579,166,15790,583,160,15767,622,436,15989,532,660,16185,304,346,16107,578,564,16375,504,690,16282,-18,723,16468,173,558,16341,-309,578,16366,-309,326,16350,-459,339,16384,-494,682,16062,-444,707,16308,-10,694,16199,305,652,15719,623,403,15306,1015,-73,15603,661,-48,15646,591,-39,15796,561,-210,15786,446,-122,15926,496,-224,15997,334,-388,15981,232,-376,16113,96,-388,16097,236,-339,16037,397,-308,16009,497,-227,15980,575,67,15995,528,-131,16006,635,-26,16032,641,142,16089,651,17,16114,849,313,16209,682,158,16226,872,423,16339,701,541,16555,670,594,16609,569,769,16687,257,773,16731,16,900,17155,-257,967,17093,154,919,17536,-238,682,17186,-566,663,17590,-533,313,17545,-711,329,17163,-703,366,16780,-512,554,16779,-409,699,16775,-252,660,16522,-187,530,16535,-384,307,16528,-462,53,16336,-493,37,16361,-506,-233,16274,-355,-253,16298,-359,50,16056,-674,390,16052,-625,718,16097,-498,411,16088,-684,887,15729,-660,1190,15788,-267,897,16076,-186,848,16049,-168,783,15987,195,813,16010,229,1061,15584,807,1144,15836,310,1163,15775,319,1682,15576,457,1835,15502,-43,1196,15725,-305,1555,15210,-546,1775,15185,-439,2215,15322,91,2025,15047,-279,2500,15128,230,2132,15370,565,1495,15461,889,1035,15169,1200,989,14613,1495,328,14576,1438,-275,14609,1243,-150,15277,880,-661,15295,627,-230,15763,480,-607,15707,165,-440,15976,249,-443,16188,-108,-437,15975,-248,-482,15997,-242,-254,16038,-569,-280,16064,-615,56,16091,-739,-452,15776,-858,37,15721,-969,474,15725,-848,896,15688,-674,974,15240,-812,1636,14559,-596,1800,14565,-497,1902,14549,-392,1981,14504,-227,2211,14891,-81,2566,14802,220,2590,14853,631,2508,15147,649,1951,15289,943,1264,15143,1230,1201,14640,1456,1146,14107,1524,958,14029,1655,295,13993,1644,-342,14007,1442,-863,14565,1005,-1319,14629,582,-1246,15134,402,-1033,15557,62,-791,15809,-379,-810,15748,-383,-432,15713,-891,-1000,15586,-945,-569,15181,-1273,39,15680,-985,482,15671,-870,526,15236,-978,1082,14524,-849,1605,14032,-443,1746,14073,-284,1823,14202,-137,1951,14213,-3,1999,14661,-127,2286,14756,-64,2577,14566,214,2635,14570,612,2419,14525,935,2336,14840,972,2244,15088,985,1875,14945,1170,1661,15088,1229,1434,14667,1377,1345,14142,1409,1334,14011,1431,1153,13952,1554,956,13917,1662,289,13867,1664,-353,13864,1475,-960,13981,1187,-1475,14005,772,-930,13981,1105,-1561,14042,553,-1559,13925,569,-1642,13957,357,-1624,13532,466,-1700,13559,274,-1680,12759,541,-1569,13590,-329,-1605,12756,4,-1281,13567,-887,-1331,12753,-542,-1146,12753,-668,-1085,13550,-957,-1062,13974,-1136,-854,13946,-1179,-852,14054,-1214,-642,14016,-1247,-628,14555,-1362,8,14516,-1230,62,15232,-1138,557,14521,-1045,1043,13988,-786,1604,13941,-401,1730,13967,-248,1859,13994,-91,1986,14016,56,1817,14093,656,1998,14288,61,1955,14424,-200,1590,14310,-82,2043,14156,-229,2382,14261,-137,2334,14514,-101,2626,14324,180,2638,14496,603,2446,14239,895,2104,14127,1041,2064,14402,1086,1997,14704,1145,1697,14517,1070,1578,14636,1299,1563,14154,1312,1540,14030,1330,1489,13589,1369,1316,13560,1469,1144,13530,1568,980,13501,1663,341,13434,1715,-319,13417,1593,-946,13425,1316,-967,13855,1207,-1476,13894,783,-1547,13505,659,-1586,12761,705,-1599,11836,783,-1615,11834,249,-1429,11831,-318,-1263,11829,-480,-1096,11828,-642,-960,12754,-795,-929,11826,-804,-775,12754,-922,-123,12759,-881,-259,11823,-843,366,12762,-811,239,11821,-824,719,11819,-692,825,12767,-626,1347,11817,-454,1425,12774,-312,1518,12776,-108,1650,13558,-153,1554,13539,-305,975,13497,-710,431,13492,-882,-45,13487,-1050,-669,13518,-1110,21,13885,-1136,530,13885,-952,536,13972,-972,1037,13895,-767,1772,13578,52,1879,13596,227,1833,13998,698,1648,14290,994,1515,14384,427,1393,14227,287,1379,14218,721,1517,13954,279,1500,13939,676,1676,13520,261,1664,13495,628,1869,12866,211,1880,12847,580,2061,12427,-2,2031,12396,489,2136,12067,42,2355,12220,-314,2416,12022,-317,2455,11810,-279,2793,11758,-317,2754,12020,-386,2682,12264,-413,3043,12067,-235,2979,12319,-283,3172,12145,78,3133,12363,25,2893,12554,-293,3068,12600,5,2688,13088,-251,2376,13020,-336,2587,12492,-401,2268,12438,-276,2070,12937,-184,1849,13584,-115,1699,14031,-98,2195,13676,-283,2529,13750,-191,2744,13781,129,2732,13754,550,2559,13693,873,2222,13603,1043,1888,13529,951,1754,14026,976,1667,14299,994,2077,12876,871,2221,12433,784,2034,12201,265,2139,12295,587,2065,11783,404,2171,11674,68,2465,11578,-194,2798,11551,-230,3070,11589,-62,3074,11800,-154,3176,11679,244,3191,11921,147,3097,12243,462,3024,12603,418,2885,13118,39,2876,13089,487,2695,13027,804,2388,12945,956,2531,12499,879,2420,12335,761,2171,11872,711,2089,11315,574,2208,11200,221,2252,10614,451,2510,10532,226,2487,11111,-22,2823,10503,181,2810,11085,-52,3075,11123,111,3181,11209,406,3067,11321,752,3050,11798,611,2776,11883,844,2768,12305,719,2443,11910,879,2195,11400,870,2147,10718,771,2264,10113,630,2524,10028,396,2548,9563,516,2847,9478,500,2831,9996,342,3069,10030,489,3071,10537,334,3146,10116,781,3158,10623,626,3053,10727,946,2795,10809,1172,2783,11413,1004,2482,10839,1217,2460,11438,1034,2235,10804,1064,2151,10218,955,2274,9702,716,2600,9682,628,2400,9783,775,2576,9499,667,2809,9429,644,2817,9619,614,2968,9619,739,2968,9429,775,2990,9499,1008,2996,9682,955,3058,9478,673,3099,9564,970,2956,9703,1277,3033,10221,1106,2774,10306,1339,2466,10338,1393,2229,10305,1246,2130,9841,1023,2294,9885,999,2357,9612,834,2601,9625,1027,2235,9725,1081,2258,9795,1314,2416,9795,1444,2649,9725,1422,2691,9885,1326,2473,9948,1340,2322,9948,1215,2382,9927,1494,2682,9841,1477,2172,9926,1320,2890,9784,1179,2869,9612,1255,2844,12570,737,1752,13622,846,1446,12787,1408,1281,12787,1500,1116,12787,1593,950,12786,1685,310,12783,1761,-304,12778,1691,-871,12772,1444,-1468,13478,858,-1397,12765,1034,-836,12771,1312,-1492,12763,869,-1498,11837,925,-1480,11360,1049,-1598,11362,911,-1674,11363,377,-1499,11359,-222,-1351,11355,-387,-1410,11093,-334,-1273,11088,-512,-1524,10441,-334,-1391,10414,-501,-1136,11084,-690,-1254,10388,-670,-420,11061,-789,-355,11336,-790,152,11326,-803,650,11317,-702,1326,11305,-509,1457,11818,-249,1612,12778,95,1706,12780,299,1659,12785,910,1508,11824,1262,1369,11825,1366,1230,11826,1471,1091,11827,1575,427,11831,1766,-161,11834,1779,-720,11836,1590,-1295,11837,1208,-696,11835,1434,-1396,11837,1066,-1361,11358,1188,-1468,11095,1129,-1597,11099,995,-1711,11103,462,-1547,11097,-155,-1659,10469,-168,-1691,10137,-180,-1562,10086,-343,-1702,9762,-250,-1547,9664,-403,-1436,10036,-509,-1396,9565,-556,-1305,9989,-678,-1243,9468,-711,-1423,9137,-632,-1273,9057,-754,-544,9278,-872,-571,9814,-880,-22,9789,-916,1,10254,-886,525,9763,-880,547,10228,-850,91,11044,-824,598,11028,-744,1303,11005,-584,1444,11303,-320,1568,11818,-44,1678,11819,160,1684,11821,757,1579,11303,1189,1438,11306,1305,1298,11308,1420,1157,11311,1536,518,11324,1759,-75,11335,1808,-653,11346,1656,-1243,11356,1326,-1339,11091,1264,-1524,10447,1200,-1673,10474,1060,-1794,10490,476,-1827,10189,413,-1907,9852,275,-2055,9345,182,-1756,9302,-401,-2189,8795,148,-1887,8757,-440,-2102,7840,-494,-2403,7877,95,-2413,7851,674,-2197,8769,730,-2286,7815,860,-2059,8728,922,-2160,7778,1046,-1930,8693,1106,-2034,7742,1231,-1797,8657,1291,-1129,8520,1695,-1311,7593,1652,241,8353,1782,329,7423,1734,1176,7450,1562,992,8375,1641,208,8710,1804,-1053,8902,1715,-1679,9110,1322,-1808,9177,1139,-1472,9533,1391,-961,9275,1739,-46,9268,1803,829,9136,1716,917,8756,1676,1695,8522,1289,1955,7614,1189,1844,8570,1118,1569,8972,1338,1714,9050,1170,1989,8618,949,1871,9139,994,2145,8673,773,2003,9220,829,2045,9283,252,1877,9764,348,1679,9653,-225,1676,9988,-173,1543,9945,-340,1536,10302,-331,1399,10287,-499,1424,11002,-394,1561,11301,-132,1678,11299,56,1746,11299,676,1616,10996,1135,1475,11000,1258,1335,11005,1381,1195,11009,1503,572,11030,1748,-23,11049,1822,-611,11068,1696,-1210,11087,1399,-1372,10417,1343,-1578,10097,1176,-1720,10147,1032,-1878,9820,870,-2066,9320,762,-1949,9252,944,-1618,9629,1216,-1268,9990,1478,-626,9817,1746,-22,9789,1814,580,9760,1746,1229,9871,1481,1215,10273,1489,611,10225,1750,-2,10254,1817,-616,10281,1749,-1215,10387,1486,-1424,10042,1329,-1759,9729,1035,1370,10288,1350,1387,9910,1336,1524,9498,1251,1368,9400,1413,1675,9604,1087,1541,9955,1190,1523,10307,1210,1675,10323,1070,1690,9995,1048,1807,9700,934,1802,10055,450,1672,10318,-163,1545,10998,-205,1666,10994,-15,1775,10991,614,1798,10336,493,1259,10274,-669,1272,9870,-678,1410,9906,-508,1524,9565,-387,1796,9270,-359,2190,8738,195,2381,7764,678,2239,7714,849,2097,7664,1019,2424,7827,104,2179,7826,-512,1943,8734,-420,2001,7797,-658,1754,8691,-554,1824,7769,-803,1574,8659,-696,1646,7740,-949,1392,8624,-837,560,8479,-957,713,7554,-1030,-80,8504,-971,-64,8866,-960,506,8863,-925,-45,9268,-936,496,9236,-894,1216,9387,-712,1370,9474,-549,1623,9181,-493,1450,9095,-630,1277,9005,-765,-578,8904,-899,-588,8508,-897,-717,7572,-926,-123,7559,-983,-1529,7734,-873,-1329,8642,-806,-1512,8678,-681,-1720,7769,-747,-1911,7805,-620,-1698,8714,-556,-1586,9217,-514,-542,10278,-852,-436,11314,1545,-916,11335,1368,-451,10981,1552,-964,11004,1373,-1263,11351,1068,-1311,11020,1073,-1401,11357,507,-1449,11027,507,-1263,11351,-49,-1311,11020,-87,-1606,10410,420,-1421,10403,-151,-1653,10137,384,-1480,10072,-163,-1711,9856,308,-1518,9727,-215,-1770,9679,201,-1587,9469,-334,-1858,9319,173,-1627,9171,-352,-1994,8751,145,-1687,8708,-375,-2190,7847,105,-1854,7804,-504,-2331,6931,51,-2009,6891,-563,-2433,6185,-26,-2130,6150,-647,-2481,5798,-97,-2183,5763,-707,-2531,5435,-167,-2226,5398,-771,-2568,5023,-272,-2264,5062,-837,-2705,4188,-409,-2425,4154,-972,-2779,3259,-487,-2515,3228,-1022,-2913,2546,-554,-2600,2679,-1083,-3070,1969,-615,-2770,2053,-1123,-3090,1373,-705,-2813,1236,-1223,-3194,802,-799,-2754,587,-1378,-3204,678,-795,-2746,478,-1380,-2524,1122,-641,-3391,768,-143,-3183,830,394,-2878,828,576,-2468,762,448,-2865,929,559,-3171,931,376,-3381,887,-152,-3209,1479,-106,-2966,1546,326,-2650,1403,462,-2459,881,437,-2020,670,-88,-2014,794,-94,-2329,1264,281,-1998,1145,-226,-2098,1495,292,-1849,1445,-257,-2039,2054,282,-1766,2026,-243,-1766,1514,-764,-1717,2038,-843,-1482,2962,-139,-1458,2985,-739,-1911,2169,-1168,-1731,3062,-1098,-2203,2299,-1247,-1939,1683,-1155,-1961,1124,-1160,-2344,1171,-1323,-2189,494,-1400,-1797,492,-1166,-1858,1061,-829,-1686,580,-739,-1690,471,-750,-1816,369,-1157,-2199,371,-1385,-2139,3155,-1207,-1596,3978,-1030,-1262,3888,-660,-1126,4801,-532,-1449,4888,-881,-1990,4068,-1136,-1860,4982,-991,-1366,5214,-811,-1071,5133,-462,-1017,5496,-394,-1273,5569,-743,-1801,5313,-927,-1727,5672,-865,-1209,5952,-682,-948,5879,-331,-787,6611,-235,-1085,6694,-606,-1669,6058,-805,-1563,6803,-734,-908,7603,-572,-571,7517,-169,-352,8477,-120,-678,8514,-480,-1398,7715,-702,-1233,8605,-577,-627,8753,-524,-305,8662,-110,-278,8781,-105,-598,8907,-552,-67,8791,-131,-71,8706,375,161,8760,-128,49,8636,401,190,8638,-144,100,8528,418,247,8448,-172,184,8368,438,604,7469,-339,593,7385,345,865,6569,-456,830,6496,233,1046,5847,-583,1018,5775,106,1129,5470,-665,1128,5233,-1,1196,5113,-751,1147,4926,-80,1263,4787,-837,1255,4649,-210,1426,3886,-1011,1405,3822,-385,1643,2992,-1130,1613,2929,-533,1927,2057,-1270,1921,2005,-671,2012,1511,-1293,2015,1427,-715,2156,1132,-717,2112,1069,-1342,1977,567,-1315,2180,486,-1709,2200,363,-1696,2623,378,-1836,2613,501,-1852,3153,499,-1712,3158,608,-1707,3468,705,-1041,3455,828,-1046,3121,1272,-1574,2670,1205,-1750,2265,1146,-1651,2220,1710,-1618,2148,2210,-1567,1946,3095,-1456,1790,4003,-1342,2361,3200,-1521,2191,4105,-1405,2718,3264,-1298,2607,4184,-1196,2930,3263,-740,2834,4184,-609,2420,5079,-1018,2033,5005,-1214,1615,4900,-1149,1520,5219,-1065,1962,5331,-1134,2370,5410,-935,2671,5007,-431,2617,5410,-304,2315,5770,-851,1877,5684,-1056,1416,5568,-984,1340,5946,-904,1196,6679,-792,1807,6064,-977,1682,6802,-868,2250,6150,-772,2109,6883,-651,2494,6148,-124,2372,6886,-7,1934,7788,-548,1500,7707,-792,987,7581,-710,623,8469,-530,1253,8566,-613,1737,8678,-376,2212,7795,92,1997,8692,172,1671,9140,-329,1157,8816,-605,558,8707,-559,530,8862,-582,1099,8970,-597,1625,9435,-296,1850,9255,223,1751,9608,264,1498,9633,-194,1028,9318,-699,509,9159,-751,-55,9056,-488,-556,9202,-725,-43,9315,-754,497,9698,-760,1022,9770,-651,1467,9948,-150,1010,10220,-579,495,10176,-716,-22,9781,-760,-549,9747,-760,-1050,9384,-689,-1126,9033,-580,-1160,8866,-579,-1065,9867,-651,-491,10221,-720,0,10199,-718,30,10959,-478,417,10942,-478,45,11292,-427,432,11274,-427,929,10919,-489,912,11252,-427,1373,10898,-87,1354,11232,-49,1511,10892,507,1492,11226,507,1373,10898,1073,1354,11232,1068,1025,10914,1373,1007,11248,1368,512,10937,1552,528,11270,1545,30,10959,1552,45,11292,1545,-128,11833,1562,451,11831,1610,346,12782,1629,372,13434,1624,324,13993,1562,357,14576,1356,-256,14608,1189,-833,14564,923,-316,14007,1371,-282,13416,1480,-915,13425,1229,-257,12777,1518,-5,10199,1534,-499,10221,1533,-1065,10326,1393,-1471,10397,1009,-1517,10115,991,-1625,9843,902,-1711,9632,815,-1834,9285,764,-1979,8719,734,-2164,7815,660,-2306,6902,554,-2423,6160,453,-2468,5880,436,-2508,5670,425,-2597,5153,400,-2609,4796,219,-2725,4165,157,-2810,3238,87,-2915,2673,13,-3081,2068,-25,-2660,2319,396,-2624,1805,488,-2357,2186,477,-2168,3077,544,-2576,3171,435,-2434,4084,533,-2040,3994,639,-1753,2996,370,-1563,3899,469,-1299,3866,-32,-1175,4705,101,-1083,4991,221,-1074,5303,281,-981,5853,362,-813,6584,458,-597,7482,533,-254,8417,503,-188,8558,455,-172,8655,426,-68,8780,956,-359,8765,985,-55,9056,1394,-936,9116,1411,-32,9571,1489,-692,9616,1502,-1263,9745,1330,-1444,9466,1209,-1544,9142,1184,-1671,8634,1157,-1875,7732,1090,-2023,6819,996,-2119,6074,885,-2191,5635,818,-2240,5342,764,-2336,4925,736,-2365,4647,603,-1953,4553,714,-1470,4535,524,-1441,4889,710,-1371,5267,732,-1301,5602,751,-1242,5890,770,-1084,6622,882,-876,7526,999,-694,8436,1064,-517,8626,1029,-985,8881,1379,-1097,8517,1328,-1345,7613,1230,-1545,6710,1124,-1659,5969,1008,-1731,5574,953,-1807,5141,881,-1901,4826,852,-1119,10044,1378,-542,9941,1513,-17,9902,1513,505,9892,1514,608,9530,1494,823,8980,1370,222,8725,956,416,8536,959,873,8749,1331,619,8310,953,811,7406,845,1045,6509,684,1240,5788,537,1306,5502,505,1383,5170,471,1461,4795,432,1513,4455,226,1621,3825,139,1835,2933,0,2143,2001,-121,2211,1444,-142,2403,1238,-155,2152,782,-614,1986,458,-1325,2160,659,-607,2744,1133,-1047,2478,756,14,2849,832,228,2837,933,209,2468,875,2,2692,1375,80,2654,1774,118,2441,2124,110,2230,3007,217,2079,3914,358,1977,4466,461,1907,4728,611,1806,5039,652,1715,5466,744,1633,5855,818,1496,6586,970,1265,7480,1120,992,8383,1264,1447,9010,1190,1343,9333,1225,1179,9624,1344,1079,9938,1384,1052,10226,1402,486,10177,1536,1466,10265,1018,1487,9981,1001,1560,9720,939,1629,10004,403,1604,10273,433,1434,10282,-133,1675,9743,345,1641,9521,864,1773,9182,807,1928,8621,753,1581,8507,1143,1810,7611,1033,1981,6709,894,2099,5973,745,2185,5541,656,2243,5252,589,2349,4840,542,2395,4572,396,2480,4015,295,2645,3112,152,2747,2265,66,3025,1526,1,3175,945,96,3186,844,116,3507,793,-363,3496,911,-374,3335,1479,-393,3209,2047,-330,3254,1988,-923,3083,2557,-840,2818,2721,-1386,3001,2102,-1450,3312,1394,-1010,2444,2349,-1610,3030,2647,-267,2909,3204,-167,2803,4124,-45,2670,4747,46,2635,5092,248,2555,5768,-215,2536,5605,298,2491,5813,319,2440,6091,350,2302,6823,487,2136,7726,639,-355,10977,-478,-1002,10311,-585,-868,11000,-489,-340,11309,-427,-820,11331,-427,-1054,11349,-717,-1203,11352,-552,28,13978,-1156,-647,13919,-1221,-890,13534,-1027,-792,15129,-1314,-865,14558,-1409,-1062,14093,-1181,-1115,14208,-1132,-1516,13976,-532,-1724,13989,145,-1646,14078,335,-1513,14618,461,-1443,15053,262,-1289,15422,-38,-1181,15588,-454,-1571,15440,-958,-1248,15087,-1316,-1045,14618,-1433,-1144,14316,-1181,-1463,14077,-576,-1732,14114,117,-1607,14560,265,-1592,14977,159,-1599,15277,-149,-1845,15020,-266,-1693,14819,27,-1610,14500,-139,-1879,14675,-340,-1869,15221,-570,-1961,14830,-714,-1900,14432,-462,-2046,14465,-792,-1856,14056,-603,-2042,14234,-888,-1927,13556,-844,-2088,13712,-1122,-2006,12957,-1163,-1712,12851,-1042,-1823,12487,-1329,-2122,12530,-1388,-2174,13108,-1430,-2292,12680,-1694,-2179,12570,-1653,-2375,12410,-1839,-2290,12803,-2061,-2342,12571,-2150,-2391,12332,-2168,-2428,12091,-2075,-2199,12260,-2394,-2243,11919,-2264,-1888,12214,-2471,-1835,12564,-2469,-1533,12494,-2360,-1483,12753,-2276,-1295,12618,-1960,-1188,13068,-1698,-1372,13253,-2031,-1783,12838,-2394,-2144,12593,-2389,-2091,12857,-2311,-1971,13371,-2069,-2170,13286,-1814,-2090,13883,-1490,-2005,14395,-1276,-1992,14624,-1185,-1910,14915,-1103,-1818,15270,-977,-1602,15441,-540,-1527,15026,-1351,-1172,14601,-1478,-1228,14559,-1480,-1145,14496,-1226,-1179,14341,-797,-1447,14326,-189,-1539,14409,-49,-1550,14508,103,-1162,14127,-362,-844,14155,-646,-911,13907,-828,-1175,13863,-534,-1528,14163,-313,-1524,13914,-469,-1603,13437,-705,-1407,12839,-1125,-1515,12467,-1411,-1547,12555,-1633,-1860,12618,-1560,-1879,12487,-1284,-2193,12396,-1362,-2401,12165,-1562,-2432,11860,-1827,-2254,11644,-2014,-1933,11857,-2337,-1577,12211,-2369,-1370,12261,-2088,-1317,12497,-1607,-1208,12924,-1380,-1052,13520,-1083,-1055,13670,-1403,-1214,13847,-1728,-1666,13358,-2152,-1547,13966,-1866,-1076,14275,-1516,-911,14069,-1205,-838,14318,-1065,-977,14530,-1311,-1412,14423,-1631,-1874,13980,-1777,-1751,14469,-1538,-1660,14751,-1479,-1633,14861,-1429,-1330,14675,-1435,-1277,13424,-793,-1360,12405,-1845,-1395,12195,-1540,-1574,12410,-1352,-1621,12086,-977,-1919,12161,-910,-2225,12076,-983,-2437,11828,-1197,-2463,11541,-1446,-2287,11335,-1626,-1949,11567,-2082,-1989,11260,-1692,-1634,11658,-2004,-1684,11345,-1619,-1415,11916,-1781,-1474,11585,-1412,-1445,11879,-1156,-1532,11463,-690,-1690,11671,-510,-1967,11741,-448,-2259,11647,-528,-2454,11424,-721,-2477,11159,-951,-2319,10951,-1132,-2041,10881,-1194,-1750,10975,-1113,-1555,11197,-921,-1595,10860,-511,-1566,11131,-276,-1713,11340,-94,-1980,11407,-35,-2265,11307,-121,-2458,11078,-319,-2487,10807,-553,-2340,10598,-735,-2073,10531,-795,-1789,10631,-709,-1761,10281,-164,-1598,10603,-99,-1596,10953,6,-1755,11199,113,-2016,11246,179,-2278,11077,180,-2441,10756,114,-2443,10405,8,-2284,10159,-98,-2023,10112,-164,-2238,10325,-150,-2352,10505,-73,-2349,10761,4,-2345,10714,187,-2352,10428,101,-2235,10230,18,-2051,10291,-198,-2040,10195,-31,-2012,10657,88,-2217,10977,241,-2231,10997,52,-2017,11118,244,-2042,11122,53,-1821,11082,195,-1855,11088,5,-1705,10884,111,-1712,10599,26,-1840,10336,-28,-1862,10416,-197,-1743,10651,-149,-1741,10908,-72,-1617,11928,-2265,-417,16175,-87,-343,16389,-204,-58,16479,-437,86,16741,-519,-147,16701,-458,-408,16624,-213,-495,16570,-138,-500,16353,-19,-458,16221,80,-549,16123,406,-548,16023,595,-534,15953,751,-439,15943,846,-323,15950,915,-167,16018,892,-116,16129,960,-286,16052,989,-235,16208,1032,-328,16153,1023,-282,16298,1047,-375,16258,1023,-380,16333,1078,-454,16318,1062,-460,16377,1046,-553,16366,1000,-459,16375,997,-530,16362,970,-549,16371,996,-489,16387,1043,-370,16361,1033,-407,16373,1076,-337,16367,1066,-328,16390,1085,-390,16411,1093,-513,16432,1078,-586,16401,1043,-597,16455,1059,-637,16434,981,-610,16389,949,-573,16377,909,-629,16365,831,-661,16377,877,-682,16415,865,-689,16395,803,-670,16372,807,-696,16365,731,-681,16362,753,-666,16303,747,-664,16214,698,-634,16158,785,-612,16057,734,-624,16137,563,-603,16237,277,-589,16547,-57,-582,16562,-153,-615,16783,-108,-738,16743,159,-647,16430,194,-739,16409,438,-678,16263,450,-718,16339,616,-712,16366,693,-726,16443,742,-671,16500,865,-616,16528,986,-642,16477,991,-572,16510,1027,-521,16526,1060,-588,16564,1049,-626,16585,983,-660,16616,885,-670,16673,875,-678,16621,952,-668,16610,973,-653,16617,1033,-644,16589,1080,-627,16585,1099,-604,16588,1111,-515,16583,1070,-556,16616,1109,-605,16623,1186,-495,16607,1109,-471,16618,1114,-576,16649,1185,-649,16666,1207,-636,16614,1166,-697,16661,1191,-689,16725,1181,-725,16667,1148,-690,16615,1124,-668,16605,1153,-715,16625,1100,-722,16652,1072,-687,16696,942,-650,16754,974,-721,16709,1054,-725,16723,1125,-652,16784,1135,-678,16774,1082,-637,16872,1036,-641,16801,934,-649,16767,875,-757,16745,641,-779,16574,621,-751,16422,616,-792,16609,433,-768,16924,248,-806,16776,439,-784,16904,513,-726,16860,670,-622,16913,766,-580,16977,874,-595,16962,984,-568,16975,1032,-609,16886,1082,-558,16871,1098,-594,16773,1148,-625,16721,1203,-559,16707,1181,-457,16692,1121,-398,16669,1087,-411,16612,1079,-391,16496,1084,-520,16475,1086,-259,16436,1106,-257,16359,1073,-283,16356,1064,-294,16357,1057,-297,16364,1041,-310,16360,1045,-385,16363,1050,-304,16349,1062,-216,16358,1080,-141,16330,1066,8,16252,986,37,16397,1045,-132,16413,1099,-126,16564,1130,-148,16736,1116,-401,16763,1068,-459,16798,1076,-497,16752,1093,-516,16961,1045,-554,17042,1014,-594,17039,967,-607,17035,888,-587,17040,831,-587,16987,790,-629,16989,737,-740,16916,682,-745,16960,668,-737,16967,657,-606,16997,721,-741,17053,663,-793,16993,533,-801,16976,527,-806,16953,524,-800,16986,394,-742,17129,104,-658,17132,-38,-613,17039,-139,-565,16811,-286,-576,16629,-259,-569,16751,-375,-481,16762,-381,-490,16630,-250,-460,16977,-316,-545,17161,-289,-557,17111,-204,-614,17114,-240,-613,17148,-356,-543,17154,-341,-587,17084,-473,-518,17084,-462,-568,16901,-493,-495,16898,-474,-728,17527,239,-850,17207,434,-847,17124,456,-811,17056,368,-812,17048,448,-810,17033,499,-799,17061,574,-756,17063,682,-675,17056,738,-658,17076,745,-744,17097,668,-798,17099,572,-819,17167,621,-741,17156,735,-644,17093,799,-590,16988,767,-662,17117,880,-636,17144,983,-578,17148,1047,-498,17037,1042,-418,17032,1035,-412,16974,1005,-299,16908,1018,-182,16852,1095,-14,16892,1114,-19,16941,1138,-188,16908,1113,-23,16964,1134,-173,16951,1115,-164,16958,1104,-30,16982,1129,-168,17044,1111,-258,16991,993,-268,16983,1019,-306,16984,989,-256,17050,1065,-330,16983,991,-266,17070,1050,-182,17054,1130,-67,17050,1146,-171,17089,1116,-322,17088,1051,-235,17148,1130,-395,17113,1088,-276,17197,1159,-494,17225,1079,-501,17142,1088,-568,17233,1035,-627,17227,975,-758,17204,782,-833,17244,643,-796,17370,585,-746,17566,518,-606,17338,942,-541,17339,1004,-503,17538,959,-578,17545,884,-541,17791,733,-407,17790,840,-412,17542,1014,-466,17336,1052,-73,17359,1150,-15,17555,1088,-270,17787,945,-104,18038,724,-241,18058,634,209,18159,58,-363,18041,523,-39,18108,-96,235,17921,-502,-158,17815,-496,524,17968,-349,742,17914,-106,418,18101,261,184,17983,737,34,17792,959,248,17512,1002,83,17193,1163,-122,17234,1198,-105,17157,1178,-65,17088,1145,7,17021,1137,57,17035,1127,60,17111,1164,375,17112,977,135,17042,1107,106,16972,1101,238,16909,1034,59,16763,1115,59,16596,1098,252,16416,896,484,16531,781,314,16728,981,494,17115,861,630,17093,722,387,17710,838,494,17829,677,744,17610,497,864,17395,409,1025,17507,112,829,17801,275,557,17962,479,899,17142,345,713,16959,599,711,17142,690,777,16743,601,760,17134,676,792,17126,740,898,17062,685,871,17063,621,909,16879,660,792,16730,688,706,16792,706,679,17094,769,580,17021,791,545,16765,797,576,16545,751,649,16612,639,679,16610,721,873,16877,594,-53,17523,-729,-87,17109,-669,-255,17160,-556,-304,17413,-503,-356,17626,-361,-466,17844,-72,-599,17725,68,-629,17802,441,-446,17993,245,-287,17975,-179,-368,17037,1002,-608,16007,843,-515,15997,944,-394,16004,1010,-430,16113,1031,-533,16118,970,-617,16116,884,-591,16214,883,-522,16229,958,-433,16212,1006,-451,16249,1029,-542,16248,984,-563,16311,1012,-638,16321,918,-608,16251,906,-620,16262,832,-671,16337,851,-620,16380,921,-643,16367,849,-656,16365,776,-655,16369,762,-672,16363,763,-673,16355,773,3564,421,1379,3084,333,1415,3093,46,1411,3364,537,774,3858,417,610,3209,688,312,3764,531,128,3778,83,122,3590,358,-283,3435,717,-231,3265,765,-700,3148,1240,-682,2911,1239,-1186,2568,1190,-1102,2398,1189,-1459,2688,1227,-1455,2954,762,-1235,3337,295,-766,3598,83,-286,3228,64,305,3868,80,606,2814,43,956,2614,42,509,2600,490,514,2804,381,960,3575,61,1375,3921,362,1120,3929,76,1116,3060,835,-40,2805,1184,-492,2376,1128,-494,2210,1138,-1015,2210,1159,-1361,2340,746,-1508,2663,756,-1528,3019,336,-1257,3027,77,-1260,2691,71,-1587,2571,61,-1109,2856,64,-607,2095,44,-951,2319,45,-429,2849,278,-604,2312,259,-426,3071,64,-112,2483,44,83,2475,319,86,2561,687,58,2374,734,-404,2143,733,-966,2087,303,-948,2068,308,-1415,2076,49,-1418,2337,59,-1569,2329,318,-1566,2683,329,-1584,2119,738,-1376,3344,81,-769,-3814,403,1550,-3814,43,1547,-3352,41,1687,-4104,333,1220,-4105,46,1218,-3935,50,732,-3934,387,735,-3491,522,1001,-3243,675,582,-3742,501,283,-3025,824,268,-3348,695,1,-2670,1191,-108,-2977,1233,-351,-2344,1180,-670,-2668,1220,-808,-2122,1171,-994,-2407,1203,-1037,-2314,750,-1097,-2003,749,-1008,-1952,1148,-868,-2005,1139,-526,-2248,1144,-41,-2556,690,474,-2688,494,913,-2980,382,1305,-3351,328,1689,-2981,44,1302,-2688,47,909,-2469,49,521,-2468,325,524,-2197,267,59,-2274,740,62,-1866,315,-402,-1928,744,-436,-1816,747,-831,-1969,321,-1057,-1746,319,-853,-1747,60,-855,-1969,62,-1060,-2297,59,-661,-1866,56,-404,-2198,53,57,-2683,270,-231,-2683,56,-232,-3125,273,-495,-3125,59,-496,-2709,62,-908,-2709,321,-906,-2311,63,-1154,-2310,322,-1152,-2662,749,-874,-3081,745,-419,-3477,332,-78,-3478,56,-80,-3001,53,203,-3244,50,577,-3491,47,997,-3742,53,280,829,17364,-414,787,17721,-207,923,17380,-256,744,17351,-516,587,17757,-426,636,17359,-599,779,16950,-623,889,16970,-561,992,16947,-405,1029,16950,-297,1027,16898,-101,991,17320,-78,916,17690,66,1036,17325,50,902,17683,260,975,17329,376,751,17730,537,782,17355,623,881,17098,514,817,17034,530,840,16764,493,913,16767,467,854,16654,476,925,16662,457,942,16531,476,892,16516,489,1001,16377,514,1056,16847,292,1071,16875,59,1107,16647,-131,1149,16618,-1,1223,16544,-257,1278,16506,-160,1476,16309,-248,1118,16629,210,1128,16624,37,1265,16514,35,1195,16511,-10,1446,16368,-3,966,16612,423,1090,16619,277,1062,16499,382,1111,16528,281,1306,16416,151,1131,16632,-130,1124,16689,-335,1056,16727,-464,984,16717,-603,860,16682,-680,855,16538,-816,991,16533,-746,991,16552,-745,1006,16364,-989,1099,16593,-599,1158,16588,-520,1321,16396,-608,1189,16535,-403,652,16955,-729,806,16713,-708,621,16730,-834,726,16568,-876,634,16522,-871,576,16399,-1115,495,16755,-911,435,16562,-997,364,16580,-1070,255,16580,-1029,201,16439,-1251,344,16764,-857,480,16978,-816,417,17386,-668,326,17728,-567,339,17370,-717,382,16956,-810,198,16934,-884,169,16766,-886,-14,16486,-1035,-89,16517,-1041,-267,16301,-1201,-206,16477,-995,8,16731,-854,-27,16920,-818,120,17321,-741,28,17703,-626,-30,17312,-759,-242,16938,-703,-201,16727,-796,-336,16531,-952,-236,16546,-992,-510,16410,-1045,-286,17344,-609,-156,17699,-566,-387,17748,-350,-484,17374,-365,-396,17133,-547,-365,16931,-596,-334,16652,-702,-241,16650,-788,-421,16526,-765,-376,16554,-792,-604,16285,-858,-478,16521,-675,-317,16631,-634,-392,16888,-545,-402,17109,-507,891,16985,-473,903,17340,-271,953,16993,-284,785,16988,-588,674,17356,-545,693,16989,-660,683,16576,-627,857,16527,-512,923,16530,-396,930,16583,-290,1003,16546,-92,1015,17000,-36,1006,17324,56,1022,17011,119,945,17330,352,1019,17027,321,919,17056,466,782,17355,623,851,17063,514,728,16607,512,840,16597,477,690,16437,494,793,16429,486,810,16341,441,730,16306,470,810,16138,562,958,16579,334,889,16420,448,989,16477,247,993,16379,349,1029,16374,272,1192,16212,291,1015,16558,100,1040,16457,-200,1089,16462,-71,1099,16329,-173,1131,16335,-93,1220,16138,-112,1040,16473,181,1073,16466,15,1114,16370,147,1112,16372,51,1264,16217,97,1008,16455,-272,966,16450,-407,856,16448,-506,1017,16187,-442,1061,16188,-394,1076,16192,-301,1116,16027,-307,813,16443,-668,694,16442,-747,757,16179,-774,844,16179,-734,864,16181,-658,822,15995,-760,549,16536,-680,646,16442,-779,424,16446,-825,633,16178,-878,509,16181,-890,572,16032,-948,270,16447,-884,315,16184,-938,239,16185,-955,225,16077,-988,164,16187,-945,104,16455,-819,335,16583,-788,433,16999,-741,353,17348,-700,365,17002,-781,228,16590,-754,102,16590,-851,125,17019,-808,9,17339,-721,19,17028,-780,30,16565,-782,-72,16458,-861,-14,16194,-906,-97,16196,-908,-95,15971,-975,-180,16200,-876,-191,16464,-794,-187,16614,-637,-396,16472,-734,-443,16279,-849,-358,16275,-888,-479,16155,-947,-181,17053,-673,-262,17348,-589,-484,17374,-365,-346,17070,-600,-293,16599,-619,-458,16478,-598,-352,16473,-664,-469,16283,-694,-402,16281,-715,-426,16081,-783,-408,16286,-600,-423,16481,-500,-308,16605,-553,-390,17080,-521,-374,16610,-538,-384,16459,-505,-379,16439,-543,-528,16306,-458,-375,16617,-445,-375,16448,-415,-382,16443,-489,-491,16264,-244,-52,17311,-642,81,16923,-752,-153,16899,-674,389,16943,-680,285,17370,-614,566,16971,-627,605,17396,-453,753,16966,-488,607,16415,-532,867,16936,-307,836,17361,-184,603,17396,-455,944,17296,135,1011,16909,-26,992,16881,219,886,17233,425,725,17178,692,929,16878,429,875,16845,437,803,16285,273,931,16311,205,1005,16098,140,935,16038,143,1196,15871,-11,1044,16105,58,901,16333,73,883,16364,-105,904,16384,-200,817,16399,-332,771,16405,-388,835,16185,-467,927,16171,-357,1001,16154,-240,969,16133,-121,983,16106,11,1243,15893,-166,1102,15999,-233,1100,16011,-294,1039,16021,-385,1302,15893,-407,976,16022,-424,897,16036,-540,822,16053,-673,648,16193,-601,405,16413,-629,431,16194,-727,640,16058,-802,507,16055,-858,674,15831,-1008,259,16186,-789,438,16053,-888,286,16037,-882,390,15860,-1117,146,16024,-888,205,15840,-1108,117,16172,-810,229,16406,-691,158,16401,-700,0,16386,-705,-20,16156,-811,79,16023,-921,-29,16013,-925,-43,15897,-1158,-89,16000,-891,-104,16135,-721,-69,16366,-637,-230,16335,-559,-224,16109,-663,-216,15897,-980,-358,16314,-515,-331,16100,-606,-296,16108,-691,-322,15875,-858,-311,16046,-585,-357,16296,-422,-341,16897,-562,-541,17197,-296,-320,17251,-517,-336,16863,-508,1038,15859,-755,1128,15838,-592,851,17921,-204,761,17907,-328,614,18156,-82,945,17680,-302,997,17678,-242,1056,17625,4,947,17902,53,670,18152,117,394,18242,183,354,18255,75,574,18155,-144,585,17897,-475,676,17680,-599,853,17703,-442,970,17368,-416,1106,17396,-307,1060,17337,-68,1059,17606,174,919,17876,207,678,18137,239,358,18226,307,244,18193,247,279,18197,138,284,18245,21,434,18161,-244,536,17905,-500,561,17688,-659,726,17320,-661,894,17359,-559,950,17087,-586,934,17120,-666,826,17092,-705,1050,16897,-803,585,17334,-749,710,17125,-705,626,17122,-799,749,16901,-913,381,17396,-866,534,17120,-897,436,17134,-947,475,16945,-1051,335,17136,-902,237,17369,-821,344,17712,-779,328,17929,-603,311,18176,-275,270,17916,-588,244,17693,-732,-28,17682,-748,28,17385,-855,225,17154,-881,78,17167,-913,178,16945,-1096,12,17133,-856,-103,17372,-758,-98,17655,-700,14,17952,-574,104,18170,-278,-29,17939,-543,-275,17667,-624,-252,17376,-706,-198,17063,-750,-114,17075,-795,-132,16864,-901,-399,17382,-650,-346,17234,-730,-262,17247,-759,-296,17106,-863,-365,17193,-704,-418,17362,-610,-422,17661,-538,-425,17618,-468,-351,17971,-338,-393,17951,-284,-489,17626,-424,-545,17380,-499,-567,17370,-441,-730,17134,-502,-487,17597,-341,-604,17346,-370,-594,17372,-435,-719,17132,-370,-436,17957,-219,-574,17602,-300,-679,17202,-273,-712,17224,-179,-738,16941,-133,-760,16976,-67,-799,16747,63,-826,16781,118,-887,16571,334,-813,16806,170,-765,17012,30,-743,17231,-79,-661,17542,-141,-740,17528,-21,-788,17218,33,-801,17045,107,-799,17021,39,-846,16823,198,-601,17922,0,-786,17564,197,-826,17267,264,-797,17237,39,-885,17005,297,-862,16968,164,-925,16770,351,-829,17588,247,-887,17273,275,-869,17033,330,-865,17267,357,-812,17576,316,-854,17623,434,-909,17295,451,-903,16927,560,-883,17269,566,-830,17565,583,-719,17782,623,-742,17900,465,-538,17992,657,-556,18002,804,-714,17788,797,-833,17542,614,-844,17503,719,-879,17261,628,-525,17884,926,-681,17673,925,-836,17533,766,-795,17461,871,-875,17334,717,-829,17309,775,-877,17069,678,-513,17883,995,-652,17638,1019,-756,17431,897,-754,17398,970,-839,17143,807,-503,17883,1079,-654,17623,1107,-743,17393,980,-727,17383,1062,-835,17081,883,-639,17369,1086,-481,17602,1109,-392,17793,1082,-309,18055,913,-340,18048,841,-109,18118,696,-142,18149,660,-80,18118,635,-141,18144,607,-91,18206,535,-18,18140,571,43,18141,503,-37,18240,462,27,18269,372,119,18201,422,115,18267,258,203,18192,313,175,18259,186,236,18251,99,192,18272,-7,72,18291,47,-70,18190,-190,-194,17983,-465,-224,18178,-87,-236,18191,-37,-330,18145,77,-534,17913,-105,-392,18097,179,-696,17911,202,-723,17907,257,-705,17867,322,-559,18093,504,-489,18114,346,-288,18190,437,-199,18225,331,-136,18261,244,-32,18288,125,-339,18184,557,-368,18110,624,-376,18132,756,313,18212,394,537,18133,507,632,18126,369,844,17850,386,794,17829,549,748,17832,571,615,17829,694,454,18116,603,233,18206,492,145,18173,575,83,18176,651,7,18131,692,-65,18106,708,-81,18115,738,-52,18137,695,-96,18100,954,-15,18133,923,-36,18025,1110,19,18052,1092,42,17917,1229,-28,18144,685,41,18094,924,128,18116,886,151,17932,1088,206,17958,1057,197,17755,1201,-88,18001,950,-185,18023,980,-239,17994,921,-361,17800,1124,-455,17602,1173,-534,17414,1104,-540,17407,1163,-599,17196,1069,-418,17628,1242,-495,17393,1243,-582,17135,1132,-341,17368,1217,-264,17585,1193,-197,17759,1126,-312,17812,1191,-100,17770,1116,-136,17557,1200,-211,17345,1238,-364,17194,1210,69,17836,1126,29,18076,930,118,18013,896,177,18047,832,253,18092,802,317,18059,699,490,17836,827,410,17898,933,323,17846,988,196,17812,1049,59,17596,1219,-73,17341,1231,45,17334,1262,0,17141,1210,95,17324,1194,159,17544,1135,348,17543,1060,328,17230,1122,181,17300,1157,172,16992,1213,478,17549,1013,516,17506,908,415,17168,1102,296,17001,1150,430,17123,990,711,17525,785,824,17499,690,798,17264,784,647,17290,820,662,16988,902,570,17008,922,487,16740,1045,864,17493,614,863,17269,731,809,17285,761,855,17071,937,915,17496,572,937,17311,677,889,17302,704,967,17114,865,998,17550,353,1061,17317,316,1121,17350,123,1113,17151,-61,1160,17192,56,1113,17126,167,1254,16955,-61,975,17341,534,1034,17349,339,1040,17214,440,1033,17259,324,1135,17073,278,586,17097,955,421,16810,1097,1146,17149,-241,1138,17168,-368,1077,17143,-460,1236,16913,-559,895,17086,-566,818,17364,-481,937,17091,-442,687,17347,-590,783,17061,-625,966,16880,-678,987,16885,-584,1012,16734,-788,892,16859,-709,588,17757,-426,922,17367,-343,807,17718,-232,1014,17371,-229,955,17686,55,1073,17330,20,930,17682,282,1038,17314,271,970,17315,435,877,17341,595,769,17730,552,780,17357,655,548,17431,877,547,17796,771,481,17154,935,608,16994,810,530,16859,943,456,16910,971,362,16629,1034,606,16868,866,521,16642,910,469,16676,969,375,16471,1008,771,17046,656,867,17041,540,1066,17106,291,1084,16859,254,1016,16860,393,1184,16626,268,1086,17066,-30,1117,17015,116,1175,16878,-46,1178,16854,55,1289,16726,-76,1053,17127,-232,1004,17101,-358,1145,16915,-315,1052,17030,-109,1164,16917,-229,1298,16767,-360,1133,16891,-377,563,17364,-707,404,17371,-775,428,17100,-846,574,17088,-845,659,17060,-750,661,16888,-959,569,16894,-953,749,16676,-993,709,16866,-894,272,17134,-883,258,16979,-988,356,16951,-954,247,16839,-1165,187,16975,-957,125,17142,-872,23,17346,-793,242,17376,-798,340,17726,-585,65,17697,-673,-183,17699,-588,-206,17333,-701,68,17081,-826,-126,17039,-779,60,16895,-917,-54,16875,-876,43,16744,-1050,-348,17335,-594,-214,17125,-716,-427,17064,-530,-231,16880,-748,-330,16879,-673,-279,16648,-875,-480,17362,-465,-403,17748,-364,-529,17377,-368,-544,17058,-331,-650,17028,-213,-731,17153,31,-739,16882,11,-690,16841,-117,-717,16665,2,-744,16699,80,-770,16493,172,-775,16921,82,-807,16651,179,-672,17449,-76,-559,17813,-92,2216,8858,1665,2119,8931,1730,2140,8884,1642,2180,8913,1769,2287,8901,1680,2248,8947,1758,2400,9094,1580,2311,9160,1699,2320,9185,1694,2419,9114,1571,2295,9074,1528,2178,9106,1520,2307,9094,1514,2185,9125,1503,2238,9254,1364,2175,9477,1466,2130,9203,1606,2128,9179,1617,2220,9175,1678,2224,9200,1670,2283,9492,1563,2354,9684,1370,2216,9638,1261,2495,9799,1268,2360,9781,1180,2544,9887,1209,2426,9873,1126,2435,10110,1016,2436,10058,869,2406,9817,980,2473,9766,876,2517,10017,773,2555,9963,627,2489,9704,727,2618,9657,650,2694,9928,565,2617,10234,555,2765,10212,507,2832,9923,593,2903,10219,552,2936,9935,660,3009,10234,617,2975,9980,828,3013,10290,800,2901,10347,968,2902,10041,986,2687,10397,1094,2694,10126,1145,2535,10389,1044,2565,10139,1114,2440,10360,934,2463,10313,786,2558,10281,698,2698,9869,1224,2661,9779,1309,2563,9677,1450,2439,9456,1639,2545,9260,1561,2349,9205,1471,2409,9012,1610,2332,9024,1529,2425,9324,1149,2500,8973,1380,2483,9240,1024,2589,8885,1216,2536,9193,887,2665,8837,1038,2705,9100,766,2752,8809,890,2820,9087,805,2602,9545,672,2754,9532,687,2757,9639,662,2863,9649,731,2873,9545,759,2933,9682,882,2463,9597,756,2439,9609,924,2359,9717,1021,2258,9468,1133,2873,9763,1066,2887,9662,1103,2684,9328,1471,2673,8927,1499,2525,9016,1637,2412,8716,1662,2347,8713,1605,2425,8663,1487,2347,8687,1610,2420,8638,1494,2516,8656,1520,2558,8907,1449,2423,8639,1405,2487,8584,1287,2416,8613,1408,2479,8560,1293,2570,8565,1326,2656,8840,1274,2532,8632,1234,2593,8599,1127,2523,8607,1235,2583,8575,1133,2678,8562,1155,2750,8811,1094,2638,8706,1053,2686,8650,952,2626,8682,1053,2671,8628,956,2746,8610,979,2827,8768,917,2921,9099,897,2890,8758,994,2902,9185,1095,2945,9581,920,2830,9257,1267,2778,8852,1327,2585,8610,1511,2487,8636,1478,2603,8657,1585,2505,8706,1686,2501,8680,1689,2411,8690,1666,2333,8444,1654,2391,8416,1546,2326,8419,1654,2383,8392,1548,2458,8396,1568,2511,8630,1526,2595,8632,1591,2442,8413,1714,2375,8434,1701,2367,8409,1700,2221,8225,1618,2242,8185,1661,2304,8156,1541,2353,8155,1586,2309,8174,1670,2504,8359,1622,2448,8372,1569,2516,8382,1622,2268,8204,1529,2433,8389,1713,2480,8611,1480,2352,8378,1445,2411,8345,1342,2339,8357,1444,2397,8324,1342,2467,8308,1366,2561,8540,1330,2649,8556,1395,2637,8532,1399,2576,8584,1511,2391,8356,1502,2377,8335,1499,2179,8210,1385,2189,8165,1419,2254,8135,1311,2291,8112,1359,2251,8133,1430,2497,8262,1421,2442,8293,1516,2457,8312,1520,2513,8281,1423,2452,8288,1365,2232,8189,1300,2597,8620,1300,2587,8595,1301,2444,8430,1240,2497,8401,1156,2429,8409,1236,2480,8382,1154,2335,8287,1111,2348,8222,1111,2535,8330,1168,2552,8348,1171,2668,8538,1158,2749,8546,1216,2860,8820,1148,2689,8584,1337,2762,8624,1135,2695,8672,1099,2681,8650,1097,2517,8559,1027,2569,8528,950,2603,8482,978,2730,8590,983,2789,8588,1043,2772,8568,1045,2746,8604,1132,2544,8519,1069,2524,8504,1063,2498,8542,1022,2548,8513,946,2581,8467,974,2629,8442,1031,2587,8470,1099,2566,8456,1091,2354,8408,990,2373,8461,967,2412,8436,909,2400,8377,920,2607,8428,1026,2403,8378,1018,2429,8354,968,2677,8560,1337,2480,8400,1298,2464,8381,1293,2300,8305,1164,2295,8260,1208,2388,8196,1156,2349,8220,1221,2577,8295,1222,2521,8329,1316,2538,8347,1322,2596,8312,1226,2736,8523,1219,-1737,10726,1062,-1751,10612,1019,-1667,10719,1037,-1819,10645,983,-1797,10736,1015,-1886,10699,777,-1773,10662,780,-1780,10665,754,-1900,10706,753,-1824,10839,834,-1730,10846,831,-1829,10852,812,-1729,10858,807,-1908,11004,567,-1742,10997,509,-1623,10827,783,-1612,10936,479,-1801,10971,262,-1640,10900,220,-1652,10669,290,-1696,10708,564,-1657,10694,752,-1655,10693,779,-1626,10818,808,-1669,10623,1004,-1817,10725,665,-2026,10789,680,-2017,10969,321,-2135,10736,570,-2021,10941,122,-2231,10692,92,-2228,10513,472,-2278,10496,42,-2258,10328,404,-2200,10353,-35,-2228,10124,336,-2110,10070,296,-2096,9930,599,-2177,9963,648,-2043,9873,762,-2104,9894,810,-2090,9884,830,-2030,9864,783,-1941,9813,885,-1978,9816,943,-1957,9808,953,-1920,9805,896,-1735,9755,928,-1771,9762,977,-1711,9834,962,-1730,9852,908,-1890,9902,942,-1856,9907,893,-1752,9788,880,-1883,9824,853,-1903,9833,841,-1964,9882,752,-1976,9892,731,-2016,9953,567,-1990,10073,273,-1965,10097,656,-1856,10255,302,-1795,10412,-98,-1776,10551,-1,-1830,10456,-197,-1822,10612,-151,-1902,10613,-476,-1888,10750,-400,-1923,10873,-704,-1902,10994,-598,-1831,11079,-525,-1822,10851,-351,-1844,10984,-275,-1845,11197,-422,-1979,11038,-254,-1965,11264,-364,-2120,11048,-202,-2124,11273,-355,-2299,10849,-271,-2301,11135,-475,-2347,10705,-359,-2368,10985,-605,-2318,10846,-726,-2283,10570,-454,-2199,10816,-752,-2171,10530,-490,-2055,10808,-760,-2029,10532,-508,-1952,10357,-203,-1928,10306,-104,-2079,10298,-76,-2197,10398,-134,-2273,10531,-59,-2224,10728,-9,-2063,10929,1,-1856,10934,72,-1910,10940,-30,-1718,10864,24,-1790,10875,-77,-1708,10701,-27,-1811,10552,389,-1788,10648,847,-1867,10673,923,-1983,10666,950,-2102,10483,905,-2148,10295,822,-2180,10126,716,-2103,9988,853,-2087,9974,869,-1957,9890,978,-1935,9880,986,-1760,9818,999,-1911,9913,932,-1875,9918,882,-1945,9995,790,-2012,9993,829,-2025,10008,811,-1955,10010,771,-2060,10102,701,-1993,9993,909,-1910,10019,868,-1980,9981,929,-1898,10008,888,-1858,9896,1043,-2055,9996,981,-1907,9897,1107,-1885,9887,1117,-1837,9886,1055,-1649,9828,1104,-1696,9832,1149,-1625,9934,1149,-1676,9902,1181,-1853,9987,1164,-1875,10000,1155,-2021,10113,1044,-2070,10008,963,-2035,10128,1028,-1933,10133,998,-1945,10148,980,-1860,10111,944,-1872,10126,926,-1942,10275,741,-2017,10272,807,-1951,10136,1053,-1870,10146,1010,-1939,10124,1073,-1858,10135,1030,-1773,10014,1226,-2020,10144,1130,-1825,10023,1289,-1804,10012,1301,-1753,10003,1240,-1553,9911,1354,-1600,9925,1396,-1518,10024,1407,-1580,10000,1429,-1774,10113,1346,-1794,10126,1335,-1989,10272,1175,-2035,10155,1111,-2002,10286,1158,-1898,10294,1132,-1910,10309,1114,-1827,10265,1077,-1838,10279,1058,-1920,10471,789,-1978,10459,884,-1899,10345,1090,-1979,10357,1159,-1962,10345,1176,-1884,10332,1108,-1734,10227,1215,-1780,10230,1282,-1759,10217,1292,-1714,10214,1227,-1511,10095,1319,-1560,10110,1362,-1471,10213,1378,-1531,10192,1404,-1709,10320,1328,-1729,10334,1318,-1898,10470,1206,-1911,10485,1190,-1831,10508,1145,-1770,10493,1088,-1819,10360,1040,-1805,10348,1058,-1760,10478,1107,-1820,10493,1163,-1678,10365,1276,-1642,10358,1222,-1682,10252,1167,-1663,10238,1181,-1625,10343,1234,-1659,10350,1288,-1462,10218,1318,-1493,10130,1273,-1837,10394,363,-1763,10728,-128,-2090,10346,-175,-1719,10037,1181,-1688,10146,1229,-1734,10160,1288,-1715,10147,1301,-1670,10134,1244,-1701,10026,1196,-1530,9941,1309,-1500,10029,1352,-1808,9937,997,-1778,10026,1040,-1821,10035,1102,-1801,10022,1112,-1759,10012,1052,-1789,9926,1010,-1642,9877,1059,-1624,9934,1086], diff --git a/examples/obj/veyron/VeyronNoUv_bin.js b/examples/obj/veyron/VeyronNoUv_bin.js index be518f498cc6c0..19728862376bbc 100644 --- a/examples/obj/veyron/VeyronNoUv_bin.js +++ b/examples/obj/veyron/VeyronNoUv_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -35,7 +35,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 37.254902, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -48,7 +48,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 56.862745, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -61,7 +61,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 66.666667, - "transparency" : 0.5 + "opacity" : 0.5 }, { @@ -74,7 +74,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 56.862745, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -87,7 +87,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 17.647059, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -100,7 +100,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 66.666667, - "transparency" : 0.5 + "opacity" : 0.5 }, { @@ -113,7 +113,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 66.666667, - "transparency" : 0.5 + "opacity" : 0.5 }], "buffers": "VeyronNoUv_bin.bin" diff --git a/examples/obj/veyron/parts/veyron_body_bin.js b/examples/obj/veyron/parts/veyron_body_bin.js index 07aa50104cab75..f8b36215ee8eb9 100644 --- a/examples/obj/veyron/parts/veyron_body_bin.js +++ b/examples/obj/veyron/parts/veyron_body_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 52.941176, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -35,7 +35,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 52.941176, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -48,7 +48,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 15.686275, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -61,7 +61,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 35.294118, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -74,7 +74,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 64.705882, - "transparency" : 0.5 + "opacity" : 0.5 }, { @@ -87,7 +87,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 64.705882, - "transparency" : 0.5 + "opacity" : 0.5 }, { @@ -100,7 +100,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 15.686275, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -113,7 +113,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 64.705882, - "transparency" : 0.5 + "opacity" : 0.5 }], "buffers": "veyron_body_bin.bin" diff --git a/examples/obj/veyron/parts/veyron_wheel_bin.js b/examples/obj/veyron/parts/veyron_wheel_bin.js index e62ab2556a9719..758866d1e2927a 100644 --- a/examples/obj/veyron/parts/veyron_wheel_bin.js +++ b/examples/obj/veyron/parts/veyron_wheel_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 35.294118, - "transparency" : 0.0 + "opacity" : 0.0 }, { @@ -35,7 +35,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 15.686275, - "transparency" : 0.0 + "opacity" : 0.0 }], "buffers": "veyron_wheel_bin.bin" diff --git a/examples/obj/walt/WaltHead_bin.js b/examples/obj/walt/WaltHead_bin.js index 712ceacf2f7cd0..c78249d873e89e 100644 --- a/examples/obj/walt/WaltHead_bin.js +++ b/examples/obj/walt/WaltHead_bin.js @@ -22,7 +22,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 92.156863, - "transparency" : 1.0 + "opacity" : 1.0 }], "buffers": "WaltHead_bin.bin" diff --git a/examples/obj/walt/WaltHead_slim.js b/examples/obj/walt/WaltHead_slim.js index 1054e41a3d3b11..19e8c5924d2f0c 100644 --- a/examples/obj/walt/WaltHead_slim.js +++ b/examples/obj/walt/WaltHead_slim.js @@ -25,7 +25,7 @@ "illumination" : 2, "opticalDensity" : 1.0, "specularCoef" : 92.156863, - "transparency" : 1.0 + "opacity" : 1.0 }], "vertices": [825,1266,2059,928,1102,1989,969,1203,2014,1150,2924,1244,1168,2925,1152,1141,3063,1115,-993,-2117,1177,-991,-2047,1421,-1088,-2061,1133,4,3899,-532,90,3932,-591,-27,3922,-759,1927,747,183,1968,693,189,1942,738,126,349,-230,-2401,372,-283,-2348,293,-296,-2376,-1045,-757,1798,-1007,-783,1784,-961,-692,1838,-1119,801,1862,-1170,717,1780,-1068,837,1888,426,-1825,-1726,323,-1935,-1779,380,-1810,-1767,-2066,-286,-791,-1976,-502,-542,-2003,-528,-558,332,-1062,-2034,281,-1056,-2007,348,-972,-2035,179,2382,-2635,249,2448,-2637,227,2367,-2682,2364,420,-926,2380,421,-877,2210,-23,-818,1657,-474,-1406,1602,-813,-1242,1596,-751,-1303,470,-899,2101,388,-921,2139,534,-934,2061,-927,3262,-1887,-852,3347,-1791,-808,3208,-2017,-1046,3669,-793,-1018,3600,-579,-954,3582,-505,2261,839,-566,2198,753,-472,2235,764,-567,-1309,-961,-1542,-1243,-916,-1568,-1239,-1020,-1536,1676,-1178,-847,1716,-1137,-834,1676,-1173,-791,138,234,-2644,128,33,-2610,100,129,-2649,2194,16,-892,-1257,633,1684,-1286,623,1668,-1265,609,1651,-39,-3808,1135,28,-3644,1094,-77,-3648,1094,-1899,-501,-313,-1924,-416,-481,1037,3597,-1229,952,3587,-1312,926,3615,-1145,822,3672,-1171,765,3667,-1275,781,3725,-1114,2017,2069,29,2079,1952,-12,2180,2072,-257,-298,-1861,-1792,-337,-1814,-1792,-304,-1773,-1813,-1325,-865,-1521,-1270,-863,-1595,-740,2860,1678,-687,2848,1724,-701,2885,1742,434,3439,-1760,400,3391,-1871,349,3402,-1836,407,-2164,1903,245,-2206,1963,248,-2244,1839,1389,728,1671,1491,741,1567,1402,756,1662,-726,646,1853,-693,641,1879,-617,680,1777,-1883,-694,-180,-1919,-603,-326,-1840,-649,-169,-256,-284,2712,-176,-303,2806,-232,-159,2713,1136,-37,-2200,1129,-163,-2144,1065,-119,-2215,-1822,-552,-148,773,-2328,1189,909,-2171,1217,708,-2297,1339,396,3510,1091,433,3484,1139,474,3510,1010,123,2294,-2681,95,2248,-2682,18,2295,-2676,842,-954,1833,767,-955,1819,764,-1020,1813,1662,-454,978,1560,-134,1428,1550,-477,1254,386,2916,1832,329,2962,1794,314,2831,1884,-1429,399,1666,-1368,477,1696,-1439,456,1614,1110,3217,1003,1167,3077,1016,1118,3208,943,2271,1668,-1045,2263,1721,-977,2212,1536,-1016,-1896,1494,271,-1880,1419,396,-1852,1508,400,1885,0,-429,1906,61,-455,1893,131,-423,-278,-40,2398,-297,-147,2418,-241,-78,2593,1835,99,258,1838,117,218,1830,175,223,-359,-435,2190,-222,-370,2305,-325,-406,2232,2099,1337,-1589,2051,1426,-1635,2079,1459,-1519,1211,3560,-926,1325,3491,-917,1265,3529,-1016,1328,883,-2522,1301,733,-2471,1173,748,-2532,373,-249,2376,363,-156,2298,323,-102,2300,-2324,-3792,-235,-2114,-3636,-181,-2541,-3712,-480,-1843,2056,-2046,-1851,1964,-2099,-1882,2003,-2010,934,2687,1639,891,2814,1620,820,2780,1679,1623,-1225,486,1582,-1326,530,1590,-1278,211,2430,-3929,-226,2595,-3810,-422,2318,-3807,-220,1794,2345,-1983,1791,2501,-1886,1894,2416,-1910,143,-442,2402,170,-341,2379,176,-379,2439,53,81,-2632,18,90,-2663,32,198,-2660,-320,769,1815,-351,780,1808,-373,733,1766,1692,632,-2047,1775,710,-2036,1697,597,-1978,-1549,-55,-1760,-1527,-140,-1785,-1536,-160,-1699,1507,-21,-1804,1456,-167,-1776,1506,-13,-1932,-1941,1494,-1927,-1914,1375,-1867,-1978,1543,-1854,-1016,444,-2506,-955,305,-2434,-1059,356,-2477,-94,-2058,2160,30,-2068,2167,-11,-2001,2183,-539,-3795,964,-417,-3613,1002,-506,-3621,945,1306,-265,1831,1162,-425,1923,1259,-468,1831,-1687,-930,-211,-1679,-1011,-299,-1633,-1119,-165,-470,737,1755,-466,772,1810,-538,810,1829,-1256,1913,-2600,-1300,2044,-2560,-1220,1991,-2595,268,3519,-1733,166,3520,-1773,250,3627,-1581,1973,1140,78,1989,1023,81,2001,1110,-24,-1745,-460,-1292,-1755,-399,-1352,-1696,-417,-1369,949,-432,-2111,869,-625,-2059,890,-494,-2146,-1736,-56,-1608,-1642,-294,-1557,-1752,-112,-1547,-2388,451,-891,-2315,343,-841,-2405,513,-846,-1127,2720,1407,-1180,2769,1352,-1287,2776,1183,1600,2100,878,1625,2042,872,1641,2052,824,2168,2407,-1033,2117,2187,-1018,2136,2259,-1068,1332,-3772,509,1670,-3772,346,1279,-3661,459,-2173,0,-785,-2195,-19,-814,-1660,-1155,-808,-1673,-1139,-846,-1662,-1167,-847,-877,1480,-2768,-992,1511,-2670,-928,1568,-2725,507,2274,-2654,417,2255,-2704,441,2284,-2658,-1681,-1083,-802,342,973,-2810,232,943,-2829,340,1048,-2846,-1198,-1511,-1438,-1144,-1543,-1465,-1150,-1582,-1435,-1112,-996,-1630,-1126,-1048,-1597,-1127,-902,-1629,637,-640,-2085,724,-517,-2103,726,-643,-2028,1562,136,1443,1500,253,1590,1493,50,1569,-1258,-592,1785,-1162,-583,1850,-1059,-411,1987,9,-3556,1051,93,-3481,1021,-70,-3486,1024,-301,-621,-2177,-348,-650,-2167,-348,-548,-2210,-512,-1477,-1844,-539,-1513,-1780,-529,-1367,-1839,1682,1325,-2318,1618,1171,-2329,1616,1404,-2343,1881,2526,-1830,-2405,854,-767,-2413,605,-876,-1449,11,-1971,-1385,5,-2001,-1381,-69,-1991,1023,2847,-2263,928,2753,-2323,908,2831,-2334,210,-223,2766,130,-235,2832,135,-307,2833,548,-1384,-1820,594,-1267,-1882,658,-1312,-1824,520,2371,2075,828,2394,1941,616,2432,2012,-92,811,-2819,-55,902,-2804,-43,706,-2813,-1964,856,58,-1940,852,178,-1935,913,156,-1768,-555,-22,-1808,-547,-148,-1815,-598,-182,2061,422,-993,2079,456,-1027,2101,627,-994,-1580,-376,-1602,-1664,-199,-1656,-1569,-225,-1652,1826,-598,-873,1872,-592,-917,1892,-517,-975,-404,-746,2163,-359,-808,2192,-284,-801,2233,1851,664,456,1815,557,500,1845,539,439,-192,1318,-2823,-280,1223,-2840,-227,1388,-2807,1885,199,49,1900,216,82,1836,28,86,-2028,692,-779,-1997,461,-904,-2008,549,-788,1972,1994,-1846,1945,2020,-1902,1964,2119,-1830,-1608,630,1330,-1550,562,1468,-1521,594,1476,-1350,-1967,220,-1209,-2165,395,-1219,-2090,401,2016,1913,109,1944,1845,247,2006,1800,70,-1992,97,-1090,-1980,158,-1135,-1944,-89,-1113,1750,2095,668,1710,2081,752,1692,2040,699,-295,3037,-2285,-362,3190,-2158,-259,3114,-2228,1472,445,1586,1556,316,1492,1572,469,1453,2105,622,-386,2158,639,-466,-2364,474,-840,-2376,597,-810,-2380,771,-740,174,-130,2769,-1989,2564,-708,-2002,2442,-671,-2005,2535,-665,-1009,-682,1848,-1142,-775,1770,46,-3285,1001,-19,-3365,996,81,-3396,995,1510,-1415,-1119,1498,-1424,-1203,1487,-1372,-1238,-729,3726,-1146,-754,3748,-1023,-655,3782,-1007,-1422,-1477,-1169,-1478,-1469,-1119,-1469,-1431,-1124,-801,-2158,1514,-969,-1994,1525,-885,-2132,1439,1481,1849,-2483,1438,1923,-2523,1508,1994,-2458,-364,3784,-1235,-438,3709,-1268,-405,3778,-1109,-1794,-835,-910,-1809,-869,-873,-1791,-832,-850,1078,2703,1460,1162,2819,1322,1093,2774,1407,-1789,1781,413,-1860,1774,346,-1822,1718,333,-620,3202,-2110,-641,2938,-2292,-699,3129,-2115,-1580,1408,-2396,-1634,1522,-2344,-1623,1486,-2417,-1847,-47,252,-1810,-57,361,-1825,-8,337,-471,-876,2118,-290,-899,2202,-334,-844,2209,2280,1205,-1228,2261,1143,-1160,2253,1092,-1273,1298,3402,-401,1305,3431,-235,1360,3401,-347,-881,-411,-2072,-841,-510,-2059,-974,-447,-1996,1760,1671,-2184,1728,1204,-2208,1729,1467,-2267,-1831,61,14,-1889,175,24,-1860,130,-12,-246,3534,-1646,-285,3512,-1746,-294,3581,-1595,1944,473,-21,1941,400,37,1904,280,-1,-933,-310,-2132,-821,-320,-2137,1951,351,-624,1959,246,-687,1955,211,-704,1420,1795,1570,1361,1848,1678,1366,1694,1725,1529,1668,-2445,1497,1603,-2503,301,-241,2596,350,-278,2474,246,-57,2523,-136,-2715,1290,-24,-2769,1269,-63,-2653,1420,493,-958,2076,337,-963,2141,366,-991,2089,161,3750,273,102,3800,316,191,3729,365,-2248,330,-857,2037,923,-118,1973,846,17,1990,755,16,-371,491,-2740,-345,337,-2713,-389,361,-2683,-1344,-3435,-1795,-1715,-3649,-1783,-1451,-3301,-1630,-471,-2341,1557,-287,-2275,1762,-435,-2199,1749,196,2320,-2676,141,2338,-2658,1653,-1281,-888,1651,-1224,-883,1665,-1244,-854,915,2477,-2501,987,2557,-2499,960,2479,-2528,170,3764,101,206,3744,215,-919,-975,1815,-987,-1044,1776,-1025,-1351,1730,222,-306,2444,204,-381,2472,181,-329,2438,1970,285,-456,2021,384,-477,2008,391,-423,-1233,2795,1265,-1268,2819,1204,-1715,-3087,-528,-1787,-3238,-910,-1928,-3299,-614,1518,-1579,-176,1495,-1551,-43,1478,-1645,-18,1310,-2420,278,1220,-2482,438,1144,-2689,499,702,-2207,1540,416,-2344,1595,700,-2257,1465,108,3323,-2011,151,3228,-2103,101,3263,-2129,281,1174,-2838,330,1335,-2845,347,1212,-2834,1928,-344,-688,1897,-471,-681,1926,-461,-715,-1007,-1108,-1642,-1052,-1157,-1618,-1080,-1073,-1664,190,-1197,-1993,251,-1135,-1992,238,-1238,-1988,-1383,2767,1028,-1393,2732,1050,417,695,1760,383,679,1772,455,605,1810,1749,1614,676,1735,1701,727,1709,1752,807,-1749,1626,677,-1763,1691,702,-1739,1723,673,1540,3008,-1590,1618,2844,-1755,1545,2900,-1773,-2120,-391,-699,-2053,-482,-632,-2045,-580,-470,1773,-367,195,1773,-632,255,1762,-628,93,539,1058,2028,464,981,1967,663,971,1970,355,3834,-744,352,3808,-853,315,3875,-831,-2083,-366,-750,1549,3206,-476,1556,3201,-370,1568,3087,-383,829,3002,-2161,899,2933,-2204,817,2973,-2237,-1841,1249,458,-1820,1289,482,-1858,1336,480,798,3614,-140,848,3576,-36,875,3608,-125,-978,880,-2672,-1043,1042,-2658,-1006,1065,-2655,-1711,2481,-2061,-1725,2297,-2164,-1738,2210,-2156,716,3627,-61,799,3614,-53,-868,2570,-2490,-831,2478,-2547,-909,2548,-2510,-1954,821,-1807,-2011,850,-1743,-1945,1035,-1783,-446,734,1768,-429,722,1771,-423,735,1771,413,2288,2135,286,2401,2127,232,2302,2177,-835,3730,-1062,-872,3614,-1228,-876,3675,-999,-1251,-1544,-1363,-1198,-1636,-1369,-1326,-1536,-1291,1104,502,1857,1206,546,1770,1118,577,1828,-278,3720,474,-198,3731,317,-289,3725,288,444,3684,-1365,428,3542,-1641,409,3629,-1433,-453,1503,-2788,-419,1582,-2810,-349,1542,-2840,-2126,-413,-634,482,1914,-2741,480,1998,-2740,541,1830,-2790,-1011,751,-2614,-900,663,-2608,-981,661,-2621,1059,-1193,-1692,944,-1255,-1699,969,-1180,-1712,310,-1542,-1901,239,-1567,-1914,250,-1511,-1874,-1333,2676,-2229,-1319,2560,-2363,-1374,2670,-2178,780,-937,1828,-1160,-3552,449,-1442,-3549,264,-1328,-3687,450,237,3588,995,284,3547,1025,303,3623,895,1785,-236,-1379,1849,-202,-1361,1743,-392,-1339,1732,3029,-1316,1753,2907,-1433,1701,2997,-1428,-1958,-390,-936,-1934,-272,-994,-1933,-387,-975,1037,3326,877,957,3367,885,983,3341,950,-1958,1513,52,-1958,1379,168,-224,3714,580,-2080,-514,-455,486,709,1807,456,695,1777,499,620,1803,215,-1740,-1878,290,-1719,-1858,290,-1756,-1840,-1792,-192,-8,-1796,-213,-159,-1754,-410,-54,-938,1953,2048,-665,1948,2154,-721,2145,2085,419,1041,2069,484,-1070,-1961,539,-1185,-1905,429,-1192,-1927,1324,-1480,-1378,1329,-1355,-1385,1357,-1372,-1325,-1813,2419,170,-1868,2385,-72,-1888,2278,95,-2025,-684,-252,-2041,-622,-215,-1375,860,-2419,-1358,944,-2425,-1334,950,-2480,209,3313,1521,278,3328,1443,226,3373,1446,-609,1943,-2713,-578,1887,-2743,-685,1905,-2708,1595,2325,854,1584,2364,839,1542,2313,898,389,1977,-2732,102,2690,1963,169,2734,1929,139,2799,1944,56,622,-2788,103,512,-2773,25,559,-2745,-1474,1083,1728,-1501,929,1635,-1436,1037,1764,-1313,-291,-1877,-1371,-401,-1770,-1382,-296,-1790,-391,-262,2341,-457,-248,2200,-419,-325,2304,819,1337,2106,658,1302,2115,-513,-184,-2358,-610,-99,-2439,-474,-66,-2447,-1770,-3506,-5,-1396,-3448,219,64,-3173,1038,116,-3250,994,-2013,1190,-1647,-1989,1185,-1744,480,3704,-55,492,3678,-174,450,3738,-181,-361,3555,-1627,-323,3447,-1767,-354,2401,-2651,-428,2361,-2662,-408,2435,-2625,944,1355,2114,808,1415,2133,396,-2365,-1789,525,-2370,-1745,366,-2509,-1813,1780,-18,-1523,1747,-203,-1462,1722,-250,-1517,-1853,-8,-1454,-1855,-69,-1408,-1923,70,-1403,1966,1525,179,1971,1566,97,1893,1574,259,-1818,227,262,-1866,99,265,-1822,158,318,-1436,-3015,-1336,-1547,-3164,-1331,-1543,-3041,-1105,762,-376,-2152,879,-401,-2169,1589,-1307,-1062,1578,-1327,-1024,1546,-1372,-1080,-2125,-206,-850,-2164,-240,-784,-2198,44,-881,-1970,200,-1182,-1999,287,-1243,-1980,148,-1229,-505,1483,2204,-348,1501,2258,-613,1620,2193,1203,-1962,1061,1140,-2129,908,1222,-1998,940,641,3688,-247,683,3653,-188,686,3710,-320,2376,556,-817,2339,671,-807,2335,534,-848,1948,-287,-601,1937,-390,-509,1886,-397,-471,-1299,-1416,-1347,-1232,-1483,-1383,-1280,-1479,-1364,-2140,-41,-897,-1840,-329,-1268,-1871,-204,-1325,-1833,-291,-1345,-1572,3126,-92,-1634,3013,-47,-1546,3107,112,553,2646,-2502,520,2599,-2566,429,2598,-2572,-1291,-97,1844,-1147,45,1954,-1254,158,1879,-305,-273,-2431,-382,-189,-2443,-335,-160,-2460,-401,896,1887,-389,814,1812,1935,478,-56,1936,430,-43,1901,340,-70,407,275,-2669,319,167,-2614,353,291,-2672,50,328,-2745,74,209,-2694,-1637,-1158,1,-1576,-1296,225,-1709,-963,127,-522,2788,-2442,-415,2741,-2457,-425,2681,-2528,1456,-2199,-196,1520,-1981,-507,1484,-1939,-138,-275,461,-2759,-256,598,-2738,-213,386,-2691,-864,-1653,-1529,-812,-1656,-1573,-795,-1692,-1546,1718,228,1040,1731,303,871,1713,421,1070,-773,-1032,1807,-831,-933,1832,-818,-1106,1795,52,110,2718,105,-156,2825,102,80,2703,-1599,2725,-1910,-1640,2646,-1997,-1686,2712,-1812,-366,3856,-626,-415,3872,-745,-408,3816,-581,-1289,-2772,131,-1282,-2995,167,-1155,-2898,339,452,3286,1412,537,3336,1329,458,3333,1347,1492,-1326,-1199,1496,-1329,-1259,1466,-1272,-1259,127,-1237,2161,57,-1293,2188,257,-1317,2136,-694,3807,-886,1514,3320,-449,1479,3298,-266,-464,120,-2544,-417,-71,-2469,-557,63,-2542,-182,2330,-2689,-129,2338,-2646,-138,2282,-2688,2242,1526,-572,2236,1667,-515,2191,1561,-494,51,-1740,-1903,89,-1808,-1862,36,-1791,-1897,1293,1696,-2640,1344,1857,-2590,1353,1709,-2647,1828,-582,-85,1797,-571,-101,1791,-629,-117,-218,-639,-2205,-275,-660,-2207,-256,-554,-2255,1651,-900,-1215,1622,-964,-1186,1580,-970,-1224,1156,2225,-2565,1307,2202,-2492,1206,2068,-2577,1211,-3410,338,962,-3479,553,958,-3629,639,1774,-856,-809,1823,-815,-849,1802,-742,-821,-1209,3405,15,-1243,3329,362,-1140,3414,123,475,8,-2521,390,42,-2556,439,150,-2605,1796,-866,-739,-2,645,-2760,-28,531,-2767,1322,-3028,127,1408,-2997,29,1359,-2837,16,191,716,2085,238,529,2175,243,651,1990,1379,3075,-1786,1300,3146,-1786,1369,3179,-1644,1862,2471,293,1908,2533,125,1837,2698,188,1848,-447,-348,1901,-474,-381,-686,-943,1916,-686,-909,1931,-754,-933,1834,2005,-59,-933,1927,-272,-918,1932,-162,-974,-1115,1328,2060,-948,1370,2126,-1026,1390,2108,-1570,-658,-1417,-1530,-742,-1429,-1537,-733,-1368,1341,3334,-1411,1263,3431,-1297,1354,3315,-1345,-2115,562,-752,-2234,784,-742,-2113,650,-687,2206,1601,-353,2216,1411,-371,2245,1490,-465,-96,-2860,1178,-111,-3022,1103,-1,-3043,1108,-1674,3094,-807,-1737,3044,-788,-1649,3137,-649,924,-1439,-1643,878,-1537,-1645,834,-1509,-1679,-1881,-133,-1279,-1954,148,-1374,-609,455,1901,-605,428,1926,-452,576,1840,-1814,2913,-1247,-1857,2837,-1151,-1752,3014,-1137,1626,-1212,-177,1612,-1179,-115,1588,-1256,-24,-972,2183,-2609,-920,2086,-2643,-999,2082,-2644,2173,2291,-683,2211,2381,-509,2224,2135,-540,-974,-555,-1929,-977,-648,-1916,-1045,-634,-1829,1697,-1018,-651,1722,-997,-738,1729,-995,-711,321,-401,2242,352,-412,2206,406,-404,2164,-2320,837,-823,577,-1564,-1758,651,-1482,-1766,-881,-1109,-1774,-838,-1300,-1726,-856,-1190,-1688,1433,-1723,632,1438,-1700,810,1375,-1759,916,926,-1154,-1793,839,-1086,-1840,904,-1019,-1876,-1276,-203,-1948,-1190,-241,-1951,-1211,-310,-1862,418,-3125,846,550,-3006,818,432,-3041,861,1179,3112,-1934,1181,2908,-2140,1093,2867,-2271,193,3221,-2131,240,3221,-2129,215,3184,-2186,1805,-874,-884,1790,-929,-856,-1877,2227,-1969,-1815,2382,-1902,-1786,2407,-1939,782,-914,1843,-1929,1930,-1957,-1936,1988,-1839,-91,-1911,2176,-167,-1812,2147,-255,-1956,2138,1314,-1070,-1539,1266,-1168,-1479,1231,-1120,-1520,2103,1211,-87,1999,1184,22,-201,520,-2775,-144,373,-2734,1189,634,-2479,-418,802,-2759,-380,886,-2775,-373,697,-2767,362,2206,-2708,365,2378,-2679,859,-1416,1789,827,-1323,1794,734,-1237,1810,2241,1634,-1201,2251,1512,-1148,2221,1495,-1315,-486,-717,2101,-527,-750,2082,-1457,-195,-1785,-1430,-191,-1855,715,-1635,1864,642,-1648,1899,722,-1785,1862,984,-1534,-1594,936,-1627,-1568,882,-1597,-1602,425,-1623,-1831,530,-1648,-1774,478,-1754,-1741,1626,-1262,-376,1652,-1169,-331,2244,2001,-944,2274,1914,-906,2201,1945,-1022,1838,-487,-122,1852,-391,-183,1782,-379,-132,-47,2432,-2635,21,2401,-2656,2049,1538,-1580,2045,1655,-1498,2113,1556,-1514,-2253,957,-490,-2262,939,-414,-2173,920,-378,-18,2781,-2479,-16,2932,-2388,45,2859,-2473,-1617,-1240,-883,-1624,-1279,-883,-1658,-1258,-851,-2639,-3720,-603,-2738,-3840,-554,1752,-779,404,1746,-567,669,1730,-791,578,363,720,1767,353,724,1783,1238,-2033,810,1157,-2153,719,-571,-1751,-1714,-526,-1718,-1772,-511,-1763,-1733,-90,977,-2816,-23,1001,-2795,186,-1774,2138,108,-1716,2141,91,-1928,2177,2167,658,-288,2203,724,-323,2274,814,-372,-534,3676,-1262,-485,3647,-1394,-530,3645,-1409,-2218,889,-328,-2103,858,-305,173,3627,1004,130,3654,912,130,3583,1049,2171,8,-689,2113,-146,-724,2120,-89,-749,-1645,-477,-1376,-966,-2401,-1529,-717,-2161,-1620,-591,-2372,-1719,-1640,-1154,-1023,-1633,-1125,-969,-1673,-1071,-1017,868,830,1785,952,811,1761,944,824,1874,2396,773,-851,2372,697,-895,2343,859,-831,-1859,142,45,-1893,582,-1719,-1812,426,-1763,-1861,409,-1692,-315,2160,-2710,-245,2213,-2708,-261,2119,-2705,-564,-917,-1984,-633,-969,-1990,-607,-852,-1974,-614,857,1902,-1042,-2210,937,-1876,2783,-439,-1925,2560,-380,-1902,2489,-216,-384,2938,-2352,-358,3072,-2271,-298,2948,-2362,199,-2137,2083,92,-2192,2047,385,3315,1452,333,-1172,2071,422,-1204,2041,576,-1098,1922,-954,-1781,1686,-1028,-1741,1574,-954,-1870,1608,-1992,-52,-901,-1975,-210,-839,-1996,212,-841,-1181,2080,1822,-1267,1968,1767,-1129,1870,1937,-1475,2562,899,-1435,2631,955,-1448,2661,923,2148,2145,-1170,2174,2076,-1143,2112,2056,-1222,472,-640,2113,604,-584,2042,474,-542,2115,-2321,952,-510,-2084,1187,-391,-2093,1320,-491,-2100,1225,-525,416,-1753,-1772,382,-1724,-1826,-1296,-2382,333,-1160,-2634,505,-1212,-2411,449,-2294,958,-641,990,-1842,-1473,1166,-1688,-1387,1164,-1792,-1376,1254,493,1760,1319,473,1737,1289,516,1694,2262,625,-669,2286,699,-753,2261,730,-643,-2078,1515,-607,-2083,1492,-497,-2029,1641,-368,-441,1940,-2731,-427,1879,-2769,-487,733,1726,-496,724,1734,-2368,942,-629,-1621,1101,-2299,-1584,1169,-2353,-1556,1039,-2416,86,-1430,-1935,71,-1499,-1912,68,-1387,-1950,-1199,713,1777,-1193,841,1837,-1279,708,1740,-1957,475,-60,-1943,518,-82,-1878,309,-73,522,436,1943,524,520,1871,426,513,1930,-1504,2575,863,-1779,-237,-1377,-1742,-291,-1416,697,2502,-2505,689,2456,-2548,668,2505,-2592,641,-1669,-1684,700,-1575,-1737,681,-1691,-1684,204,-677,2251,309,-749,2216,256,-611,2223,-962,1421,-2700,-1206,297,-2323,-1335,467,-2321,-1223,407,-2416,1199,421,1838,1162,469,1844,-1699,-1089,-842,-1648,-1112,-884,-309,831,-2790,-336,890,-2817,-1743,2873,-1369,-1649,3033,-1319,2068,-157,-463,1989,-208,-345,2046,-232,-495,1170,1378,-2680,1283,1399,-2665,1270,1277,-2640,175,3893,-716,156,3911,-787,117,3928,-731,2037,1592,-40,2021,1501,18,-909,3336,-1834,-970,3328,-1739,-924,3392,-1726,122,755,2269,56,929,2285,56,771,2319,899,604,-2634,763,412,-2602,774,605,-2633,654,-1556,-1714,503,1466,-2819,469,1354,-2790,64,3596,1018,-331,552,-2738,-455,1108,2105,-438,1017,2028,-323,954,2050,-270,2781,-2460,-305,2868,-2439,-247,2844,-2417,-2280,897,-390,-2353,908,-544,-1761,390,554,-1845,793,519,-1863,691,444,1228,286,1895,1311,-34,1822,1303,226,1837,1339,2946,895,1382,2877,940,1433,2889,826,491,358,2024,370,435,2055,416,229,2159,-1955,2394,-1529,-1906,2484,-1436,-1907,2454,-1572,265,2420,-2660,301,2345,-2675,-1048,2168,-2600,-460,925,-2794,-1472,-1640,-1073,-1389,-1742,-1192,-1394,-2033,-1170,-2393,905,-671,1961,2401,-1705,2006,2482,-1591,1994,2227,-1709,0,2103,2237,365,2155,2186,179,2199,2198,2370,442,-840,2291,373,-861,829,488,1936,983,475,1921,990,499,1903,1079,2613,1535,1116,2461,1659,-1500,1352,-2495,-1428,1255,-2512,-1553,1461,-2442,1291,2934,1024,1297,2892,1030,2214,160,-632,2228,222,-665,2247,463,-570,-369,3856,-517,-412,3808,-426,1307,1206,1904,1354,1131,1849,1402,1156,1834,1310,2458,1297,1269,2529,1309,-646,-380,2067,-587,-458,2067,-482,-254,2129,146,979,2239,147,850,2202,189,896,2160,-2235,810,-319,94,3783,-1264,46,3843,-1186,90,3874,-1032,1896,1407,316,1881,1379,383,1886,1237,397,49,2411,2168,-20,2554,2089,-85,2544,2089,1378,-2598,-1163,1437,-2779,-1085,1350,-2736,-1267,-1230,-1335,-1451,-1270,-1394,-1423,-1290,-1302,-1445,798,-890,-1922,754,-992,-1942,725,-769,-2000,-1967,2668,-1067,-1928,2677,-976,-1948,2768,-1030,732,-354,2101,816,-224,2115,542,-195,2144,1877,-90,-350,1930,-52,-432,1260,3452,-1216,1173,3555,-1110,1266,3487,-1137,-1237,502,1775,-1213,438,1819,-1176,477,1830,-880,2740,-2421,-941,2875,-2285,-891,2973,-2250,-175,-774,-2133,-157,-730,-2210,-139,-850,-2130,-432,-1447,-1898,-423,-1664,-1828,-473,-1592,-1801,455,2501,2033,1307,-1972,487,1165,-2155,571,-735,-848,1896,-749,-877,1869,418,-805,2161,324,-831,2216,-14,-380,-2377,28,-338,-2458,8,-440,-2339,437,1239,2170,503,1125,2095,1188,-375,-1954,1086,-386,-1994,1144,-215,-2080,437,-1080,1966,-861,-1814,1779,-837,-1913,1756,-761,-1918,1821,-2280,857,-406,-2224,777,-327,-1275,-2138,-1306,-1231,-1766,-1333,62,673,2375,90,471,2515,143,498,2441,535,3124,-2195,466,3081,-2231,494,3138,-2123,537,3651,-71,623,3618,36,642,3675,-110,14,3806,278,-74,3809,302,-73,3796,384,-689,-913,1713,-635,-914,1718,-688,-926,1767,1822,1277,537,1810,1343,623,1849,1196,587,-1135,705,1814,-1190,662,1757,-1150,678,1764,-586,1124,2064,-663,1289,2107,-795,1182,2032,-222,1506,-2780,-337,1598,-2820,-239,1614,-2750,-554,-799,2067,-601,-775,2026,-694,-800,1950,502,3618,719,559,3556,787,578,3569,683,217,3021,-2313,225,2953,-2395,150,3033,-2311,-1659,-1220,-857,-1954,-363,-872,-1923,-530,-874,-1914,-531,-823,47,-1230,-1979,30,-1462,-1957,2370,734,-755,-1300,-28,-2048,-1270,0,-2086,-1427,3317,-145,-1288,3282,487,-105,2081,-2743,-57,2010,-2730,-142,2007,-2760,2146,1281,-328,2209,1284,-434,707,-931,1777,733,-945,1798,631,-960,1822,815,2404,-2545,870,2459,-2568,895,2408,-2539,1482,647,1572,1529,734,1510,-1280,562,1686,-1205,560,1766,-917,3639,-1101,-984,3654,-1108,-956,3685,-927,2232,700,-789,2104,591,-689,2197,804,-638,-1176,3162,-1780,-1175,3044,-1937,-1218,3107,-1857,-1730,-825,-1173,-1661,-723,-1283,-1634,-828,-1252,808,3287,1170,743,3248,1227,861,3199,1256,-1069,297,1953,-1195,328,1897,638,2550,-2511,574,2535,-2584,616,2586,-2495,1137,409,1886,1180,360,1896,-1682,2203,730,-1679,2035,723,-1621,2146,816,866,-1244,1793,25,-1842,-1862,80,-1889,-1841,-83,-1877,-1860,604,2110,-2694,515,2085,-2738,476,2153,-2699,-1186,-2477,-1392,-1107,-2199,-1429,-599,-667,-2105,-503,-825,-2102,-561,-869,-2035,-1085,1349,-2697,-985,1251,-2660,-1035,1208,-2665,-1342,3465,-735,-1485,3364,-692,-1433,3404,-587,-1626,-672,-1334,-1586,-645,-1367,-1585,-723,-1354,1282,1362,1928,1266,1417,1915,1072,1486,2027,-1230,632,1698,-1168,658,1741,-497,-660,-2140,-406,-700,-2119,-446,-822,-2106,2000,-258,-393,1965,-260,-282,2006,-301,-376,334,837,-2804,406,865,-2787,365,784,-2783,-1097,503,-2495,912,-656,-1989,1000,-503,-2066,-303,2875,1887,-362,2850,1863,-303,2804,1916,-2310,886,-482,1177,3202,940,1244,3127,907,53,1771,-2839,-2,1681,-2855,-49,1695,-2818,-1445,-302,-1777,-241,-813,-2111,-245,-736,-2196,-201,-741,-2153,-205,-2945,1098,-322,-2719,1147,271,-863,-2095,184,-781,-2167,227,-639,-2200,-1475,-1912,-1035,-1523,-1546,-964,-803,116,-2453,-683,102,-2483,-744,6,-2377,-783,3666,-1263,-2162,-160,-734,-2170,-261,-711,-2141,-241,-665,-123,-937,-2125,-172,-994,-2101,1366,601,1649,1336,588,1644,1391,590,1629,1436,1043,-2456,1490,1020,-2417,1379,848,-2454,207,-484,2284,322,-459,2211,176,-340,2350,-1907,-501,-745,-428,765,1786,-361,759,1782,-442,861,1842,1332,2762,1142,1276,2801,1185,1232,2708,1269,-1043,3207,-1914,-943,3237,-1943,-970,3121,-2066,1975,-463,-258,1937,-596,-136,2018,-556,-283,633,3737,-518,647,3739,-383,688,3728,-497,1929,288,-342,1964,354,-291,1904,237,-356,1254,1762,1847,1317,1859,1756,-1637,-1282,-845,-1637,-1240,-806,-1636,-1232,-824,942,2523,1788,713,-539,2015,737,-641,1971,-2103,-105,-740,-1413,1328,-2525,-1351,1361,-2569,-1286,1219,-2640,2040,101,-594,1989,195,-529,1955,90,-508,-5,-2190,-1814,-58,-2468,-1829,-153,-2152,-1818,-89,2606,2079,-802,3563,288,-734,3569,463,-739,3598,337,2042,366,-1088,2086,377,-1039,-339,2075,-2734,-280,2008,-2758,-1126,1084,1920,-1058,982,1935,-951,1061,1984,-1477,3088,-1603,-1571,2969,-1673,-1575,3100,-1437,1083,2876,1322,-299,-1112,1972,-227,-1140,2029,-198,-1148,1995,1016,2896,1392,1069,2819,1428,1180,607,1772,1244,593,1714,1199,636,1717,1626,51,1282,927,1272,-2729,1030,1284,-2682,859,1120,-2702,1942,146,-285,1882,64,-280,1893,162,-276,1828,-189,-205,1848,-13,-181,1800,-206,-163,-1458,-1201,-1225,-1413,-1163,-1263,-1393,-1302,-1269,2213,197,-834,2171,-139,-747,2206,40,-795,-1629,1295,-2286,-1716,1309,-2196,-1673,1420,-2188,358,3810,-502,385,3803,-315,428,3765,-378,-1970,558,-65,-1955,493,-26,-1965,445,6,-1635,-1217,-771,660,386,-2591,577,499,-2644,453,2414,-2664,427,2358,-2655,432,2502,-2637,1874,862,-1877,1892,930,-1958,1940,967,-1923,2003,-622,-237,2065,-548,-505,23,-2134,2130,120,-2089,2142,1345,3360,-73,1350,3375,-243,1281,3422,-87,1721,-1071,-790,1677,-1113,-734,1703,-1125,-779,1309,3427,-595,1284,3505,-593,1256,3449,-528,-168,-574,-2267,-133,-616,-2222,-1503,540,-2247,-1560,508,-2206,-1580,650,-2215,-801,-420,-2127,-723,-340,-2258,-727,-434,-2121,1127,3550,-308,1206,3503,-325,1183,3537,-399,845,-3017,715,667,-3235,762,808,-3192,665,1052,1643,-2697,1010,1537,-2694,901,1507,-2710,879,3669,-1144,862,3601,-1266,1035,-1307,-1619,997,-1416,-1621,983,-1378,-1686,-529,2552,-2603,-566,2529,-2579,-640,2644,-2510,-194,-2902,-1923,-359,-2791,-1883,-177,-2641,-1855,596,-2673,-1784,583,-2846,-1846,2230,819,-465,2299,859,-448,853,2713,-2386,920,2627,-2438,849,2590,-2443,1118,3494,-55,1024,3510,65,1112,3471,3,1731,2502,655,1686,2647,628,1652,2369,807,-2034,1374,-346,-2047,1421,-307,-2065,1400,-408,1749,2425,458,1720,2382,624,1804,2375,436,550,-2378,1418,49,-20,-2609,9,-54,-2566,-204,32,2568,-254,2836,1939,-237,2752,1955,-186,2770,1972,-2074,1350,-253,427,663,-2734,424,557,-2723,323,566,-2741,-1243,580,1725,-1267,587,1682,-328,2215,2165,-550,2306,2089,-299,2138,2199,1371,-1239,-1301,1464,2549,962,1408,2725,1035,1370,2627,1100,-1938,547,-176,-1946,564,-134,-1961,655,-241,-673,-1071,-1899,-718,-1139,-1838,-678,-994,-1902,606,-2892,815,278,-1139,2044,246,-1133,2013,175,-1173,2090,-1614,2540,590,-1617,2707,360,-1659,2439,528,-1554,-1339,-1091,-1511,-1323,-1105,-1486,-1364,-1124,-1816,255,-1679,-1889,207,-1600,-1900,354,-1652,-724,3033,-2226,1644,351,-1854,1608,244,-1903,1655,371,-1936,595,3515,841,588,3506,945,655,3455,938,-1739,-937,-880,-1748,-910,-814,-1778,-904,-844,-1243,813,-2504,-1270,744,-2445,1458,-847,-1386,1434,-940,-1374,1416,-873,-1462,-1136,248,-2402,-1628,-3021,-273,-1471,-2819,-181,-1580,-2901,-342,-2043,1913,-802,-2126,1768,-896,-2046,1870,-689,-1519,2529,778,-1556,2455,808,-1513,2456,891,544,1665,2205,809,1721,2132,368,1655,2256,471,2961,1756,416,2978,1734,434,2882,1820,-14,3148,-2246,-4,3269,-2074,28,3202,-2162,-1954,572,-1661,-1984,711,-1695,-1399,534,1617,-1511,492,1522,-1402,519,1649,1066,3203,-1814,1109,3130,-1863,1016,3237,-1856,-970,3454,330,-883,3534,316,-1046,3437,277,-162,2826,1999,341,2644,1967,211,2519,2081,-577,-2153,1690,-192,-3682,-2170,-261,-3874,-2204,-378,-3701,-2173,-59,55,-2638,-64,233,-2659,-20,57,-2612,-436,-382,2142,-370,-476,2179,-1872,-520,-663,-1772,-812,-706,2048,1510,-1689,2069,1641,-1607,1918,2159,-1910,-1995,701,-419,-2062,923,-652,235,-790,2247,294,-881,2218,-1207,844,-2567,-1157,707,-2519,262,3310,-2049,201,3276,-2061,929,2701,-2401,1004,2710,-2368,1276,3227,599,1315,3262,458,1259,3281,478,1098,854,1904,1208,754,1792,1132,880,1879,1316,1911,-2597,1239,1735,-2659,1227,1864,-2602,1032,3579,-434,971,3579,-357,1037,3544,-323,-270,3790,-1247,-311,3780,-1180,-256,3848,-1044,64,3466,-1818,68,3371,-1972,34,3444,-1897,330,-2149,2004,-902,-1525,1770,-943,-1625,1743,-832,-1607,1811,1006,1405,-2715,1115,1455,-2662,1601,2226,833,1584,2279,848,1587,2185,867,1425,-1091,-1358,1376,-1187,-1369,2117,804,-798,2216,922,-902,2263,1036,-799,-1640,-1199,-349,-1675,-1050,-571,-1606,-1270,-550,-514,1613,-2818,-1975,598,-568,-1950,599,-484,1741,2864,-1534,1801,2841,-1489,1867,2675,-1620,-473,727,1772,800,3539,286,804,3560,175,756,3561,213,3,-1633,-1900,-5,-1519,-1896,45,-1613,-1929,-70,-2219,1999,38,-2245,1944,-16,-2191,2066,-1913,2612,-1574,508,-163,-2426,486,-296,-2336,-459,-798,2138,502,781,-2765,1798,167,417,1797,207,360,1799,368,447,1426,-1976,-1130,1306,-1751,-1274,1433,-1689,-1138,-1745,-198,763,-1784,-42,531,-547,930,1886,-681,924,1918,346,2478,-2625,421,2542,-2590,394,2493,-2594,-3,-3088,-1954,194,-3514,-2115,0,-3631,-2139,-189,-155,2767,-120,-240,2839,-96,-130,2818,-1177,-205,-2040,607,3162,-2134,618,3228,-2038,747,3212,-2040,-1955,-710,-227,-1333,562,1639,-1293,584,1632,-1334,593,1641,-241,-1374,-1937,-215,-1348,-2013,-184,-1380,-1982,-13,-821,-2138,-46,-938,-2131,-56,-788,-2177,319,791,1837,364,785,1799,387,849,1847,1852,1351,490,1856,1288,443,1838,1382,467,73,3901,-445,132,3902,-428,164,3907,-590,0,3643,-1502,61,3667,-1491,41,3639,-1593,1066,993,1930,1048,936,1944,-39,3275,-2097,-4,3326,-1987,1648,-3353,-1487,1846,-3614,-1639,1497,-3315,-1602,1042,3293,-1761,958,3411,-1687,1070,3364,-1654,1351,3381,-459,431,3192,1559,470,3135,1637,517,3204,1511,2179,302,-539,2086,157,-595,2161,30,-638,1049,-2264,681,942,-2331,855,-1171,1197,-2686,-1248,1298,-2652,-1125,1261,-2701,-1903,-245,-1133,-1895,-396,-1157,-1886,-540,-1083,-127,-1376,-1965,-155,-1279,-1973,-97,-1290,-2008,-925,-1004,-1760,-914,-1125,-1689,-997,-1084,-1729,-1469,-1625,240,-1505,-1500,-47,-1469,-1604,-2,-103,-1989,-1827,1789,-213,-32,1825,-67,-122,-1586,1272,-2365,-2142,1788,-1069,-2118,1660,-964,1079,1895,1971,1204,1878,1876,1116,2124,1868,-1158,1382,-2669,-1592,-1294,-184,-1567,-1403,-274,-1526,-1432,-17,-1839,79,-149,-1878,325,-144,-501,-323,-2317,-545,-358,-2277,-556,-279,-2303,-871,1821,-2744,-1027,1863,-2693,-902,1889,-2696,334,2077,-2752,1941,1119,218,1892,998,298,1920,950,285,-517,-3272,840,-439,-3317,884,-420,-3212,861,-253,-2029,2125,-94,-2141,2112,-238,-2199,1982,509,2834,-2441,483,2882,-2391,560,2851,-2368,1833,22,-53,281,2812,-2467,217,2772,-2492,256,2872,-2433,-1932,1776,84,-1928,1670,117,-1852,1758,221,542,-977,2013,-789,-848,1863,-909,-819,1842,-1868,1899,250,-1863,1998,134,-1935,1916,107,535,3746,-650,584,3738,-587,599,3770,-669,-941,2358,-2574,-883,2248,-2610,-1989,1776,-50,-1982,1684,-179,-1939,1691,-36,-2105,-61,-889,-1797,64,-1587,1660,246,1246,-1783,-3166,-441,1526,2975,349,1532,3028,203,1522,3086,290,1837,-475,-1172,1746,-805,-1015,1738,-846,-1050,-432,1699,-2815,-360,1049,-2813,-353,1215,-2852,-291,1038,-2871,1945,173,-472,1158,-165,1960,1703,428,-1921,1722,458,-1847,-2296,399,-958,1841,1867,-2043,1805,1950,-2106,1863,2085,-2051,711,2345,-2592,741,2416,-2577,771,2393,-2614,62,487,-2731,35,418,-2748,1573,566,1446,1521,604,1482,1517,564,1526,827,3623,-1366,768,3601,-1399,-721,-723,-1992,-894,-669,-1946,-859,-603,-1995,-815,3582,165,-856,3560,113,1445,2760,937,1388,2780,1052,1480,3270,27,1490,3209,72,1528,3240,-53,953,3480,365,991,3497,270,915,3501,285,-980,-2411,640,-896,-2525,701,-828,-2521,758,132,-485,2525,35,-516,2538,102,-490,2423,1060,3447,433,1071,3433,320,1013,3462,399,-89,1282,-2847,-32,1361,-2815,-34,1264,-2797,-206,-793,2259,-124,-822,2286,-129,-767,2299,-1020,1365,-2673,-1056,1457,-2708,-1996,1830,-267,1160,3554,-489,1171,3586,-611,1054,3590,-496,-1089,2661,-2383,-987,2627,-2422,-1010,2592,-2474,-112,3372,-1947,-173,3276,-2038,-197,3376,-1914,-1347,2975,-1942,-1274,3007,-1996,-1253,2858,-2170,-1792,1650,620,-1817,1604,533,-1775,1594,602,-1828,1885,431,-1860,1961,348,-1818,1849,341,1722,-863,-519,1683,-1034,-417,-1953,1807,-1885,-1944,1893,-1771,-220,-231,-2481,-149,-171,-2470,-172,-351,-2393,-48,2909,-2438,-104,2989,-2314,-75,3009,-2354,-558,-1627,-1780,79,3521,-1772,35,3563,-1647,1805,121,317,1823,-21,245,1250,-2758,214,-199,620,-2779,-257,703,-2806,-231,861,-2841,2137,2401,-733,2146,2412,-620,68,3320,-2044,70,3214,-2148,-432,3601,-1552,-417,3486,-1697,-873,988,-2713,-806,1010,-2766,-771,939,-2750,-1100,709,1756,-1067,716,1707,-1030,759,1721,-713,3525,-1521,-719,3481,-1657,-785,3417,-1710,-516,3763,-1130,-497,3751,-1269,434,2836,1843,1948,1673,220,-1889,1247,-1915,-1906,1016,-1932,-1956,1124,-1867,877,3552,-1421,953,3472,-1549,873,3530,-1536,2002,162,-911,1999,91,-960,2031,367,-906,-1645,-380,-1520,-1589,-490,-1462,-1631,-414,-1444,912,431,1941,788,2341,-2578,-260,3661,-1527,-221,3751,-1312,-208,3591,-1592,-2352,565,-938,-2254,401,-940,-397,-2033,2048,-508,-1962,1969,-589,-2046,1862,-1257,3439,-1056,-1379,3390,-1116,-1330,3463,-946,536,3676,-1378,596,3704,-1300,575,3644,-1378,202,-877,2258,-9,-883,2289,97,-908,2264,-1188,-1073,-1558,-1156,-1141,-1596,-2,2466,-2610,-45,2506,-2634,145,3827,-218,127,3794,-66,198,3786,-43,-1273,602,1635,818,-844,1862,-145,3787,223,-135,3790,323,-41,351,-2728,-28,254,-2723,1004,3503,-2,614,-920,1729,657,-913,1717,-1033,-1610,1652,-1030,-1509,1695,-1111,-1484,1629,-1049,-521,-1918,-1122,-577,-1800,-1137,-487,-1835,-1904,2711,-592,-1942,2582,-527,-1553,2320,852,-1620,2206,807,-1548,2316,879,1340,2181,1511,1468,1893,1375,1397,2343,1209,-1479,-1502,-1099,887,-1246,-1770,803,-1388,-1779,813,-1275,-1821,130,-2648,1391,69,-2778,1248,247,-2734,1190,-1916,436,93,-1922,436,51,-1890,334,84,-2181,259,-919,1880,-340,-270,1866,-238,-243,-559,3625,413,-508,3624,595,-474,3673,523,-458,-1834,-1735,-666,-1871,-1613,1622,-2971,-755,1716,-3202,-999,1595,-3053,-999,-1559,688,-2285,-1455,550,-2303,1536,-804,-1355,1524,-919,-1337,1617,2818,295,1713,2832,104,1611,2945,109,-354,-1311,-1956,-352,-1435,-1894,699,-2762,779,762,-2953,772,1651,1877,875,1648,1967,842,1532,2088,1008,202,1461,2302,105,1485,2317,87,1242,2307,-1922,938,272,-1906,887,241,-1878,805,273,-476,2291,-2664,-436,2218,-2687,-519,2255,-2693,-444,340,-2685,-481,457,-2712,793,-1537,-1724,1650,1860,-2339,1586,1912,-2395,1667,1987,-2314,-513,1984,-2732,-2364,434,-929,-834,-1345,1794,-880,-1300,1785,-791,837,1797,-911,832,1884,-903,824,1777,-1552,-1483,-360,527,3126,1565,624,3188,1461,550,3188,1456,-1020,-711,-1844,-1038,-716,-1764,425,3360,1305,472,3394,1285,389,3402,1240,39,558,2468,49,393,2568,-1772,2859,-82,-1692,2913,61,-1760,2930,-149,-965,1442,2101,1280,457,1774,1296,399,1793,-470,-510,-2210,-538,-453,-2225,-476,-409,-2222,-8,766,-2774,38,868,-2765,1710,688,1035,1664,989,1083,1620,851,1290,-2382,790,-865,834,2778,-2308,760,2767,-2371,2024,276,-547,1317,3070,839,1260,3177,744,1219,3226,785,-2400,834,-825,-561,1757,2206,-276,1675,2278,-503,1819,2208,-1731,2255,573,-1697,2373,490,-2054,676,-1050,-2057,623,-1145,-2055,523,-1110,1610,2287,810,1629,2177,794,1534,-1675,-473,-1884,462,349,-1877,599,368,-1874,541,275,1775,1821,-2199,1811,1792,-2139,1939,2286,248,1857,2033,409,1998,2097,162,-1996,1855,-199,-2115,1393,-1320,-2104,1195,-1343,-2104,1241,-1278,-134,-472,2376,-63,-507,2437,-112,-487,2458,505,-1282,-1901,-1872,2505,-157,-1831,2745,-291,-692,3193,-2048,-592,3318,-1914,2128,262,-558,2139,395,-481,891,2885,-2269,995,2911,-2237,1276,-3395,-1797,1099,-3474,-1897,874,-3265,-1889,-1697,1933,-2233,-1746,2033,-2197,-1627,1872,-2325,-636,-380,-2248,2170,901,-393,2056,772,-296,2087,802,-273,293,-21,2362,329,-57,2308,1521,2590,-2105,1553,2507,-2183,1473,2518,-2162,178,3125,-2216,1836,817,-2000,1868,915,-2065,622,855,1904,643,920,1910,536,831,1872,-1866,1176,388,-1864,1084,457,-1862,1179,448,-731,2917,-2276,-2024,329,-1304,-2033,476,-1228,-1797,1415,605,-1763,1501,656,-1806,1508,592,205,3583,1059,-1698,-252,-1447,-1800,28,-1524,1639,1996,858,1644,2510,-1980,1600,2642,-1927,1699,2508,-1931,-363,-351,2429,-376,-362,2336,-334,-363,2377,-1069,2755,-2328,-892,2652,-2452,-947,2657,-2451,1686,-787,771,1627,-1146,743,466,734,1760,473,763,1799,424,755,1779,-101,1405,-2814,1596,2554,825,1582,2423,850,403,3690,316,364,3693,411,460,3646,467,36,1915,-2782,86,1856,-2812,-2025,1697,-1802,-2059,1539,-1716,870,2343,-2582,887,2272,-2625,25,-986,-2095,-1,-1067,-2051,707,-960,1833,587,-982,1929,-970,-67,-2217,-1033,-114,-2177,-1062,-77,-2226,-351,-305,2496,1741,1720,658,-1447,-379,1589,-1339,-310,1788,-1485,-181,1594,-269,-64,-2525,-238,38,-2570,-241,-139,-2538,-1843,-539,-373,-1878,-476,-488,-2058,1685,-1686,1326,-1705,1129,1270,-1601,1273,1273,-1710,1233,-2041,791,-296,-1942,587,-279,-1943,579,-389,-2003,664,-464,-1119,785,-2558,-1101,689,-2568,92,2415,-2627,42,2342,-2646,135,3042,1846,168,2944,1876,181,3045,1850,109,1741,-2800,178,1847,-2786,968,-885,-1863,1011,-659,-1950,1025,-883,-1798,576,-3367,822,414,-3364,908,515,-3499,900,1018,787,1852,1061,783,1881,1932,2333,-1887,1885,2324,-1948,-140,-1757,-1891,-52,-1564,-1923,-85,-1751,-1899,2040,546,-1544,2081,721,-1564,2112,589,-1440,636,840,1868,1044,2478,-2456,1088,2620,-2377,1133,2587,-2419,307,3253,1610,256,3191,1644,294,3131,1677,1569,3172,-810,1565,3244,-914,1552,3276,-845,224,2010,-2784,-115,1679,-2820,-183,1720,-2770,-116,1771,-2809,-1187,2327,-2536,-1160,2229,-2563,-1242,2243,-2530,155,-386,2775,251,-327,2702,162,46,2644,1891,220,135,1870,109,156,-1060,-2613,602,-1148,-2291,471,949,-3153,509,1001,-2885,619,-2014,1253,-1519,-2087,1450,-1509,-2070,1509,-1585,1078,-2066,1141,1215,-1929,1145,1277,-772,-1639,1208,-853,-1688,1231,-778,-1720,793,857,-2726,876,827,-2642,734,764,-2715,2410,594,-861,2379,550,-921,1594,-860,-1284,1966,123,-723,2084,240,-789,2025,-101,-728,1745,-870,-918,1723,-934,-900,1760,-914,-964,1759,-969,-844,1762,-917,-794,1762,-947,-759,-1360,644,1653,-1376,606,1639,1665,-1182,-910,1685,-1213,-872,1740,-999,-831,1441,925,1704,1500,913,1633,1421,1040,1773,2116,41,-617,-1476,-880,-1423,-1489,-896,-1361,-1495,-798,-1406,-1149,3261,-1751,-1085,3141,-1945,-1741,-989,-929,-1708,-961,-985,-1704,-1022,-953,-2185,913,-503,-1334,-713,-1599,-1365,-735,-1547,-1364,-649,-1613,-2089,1197,-797,-2104,1072,-787,-2100,1183,-719,-2129,1227,-1085,-2092,1180,-1019,-2053,1342,-1012,1587,-1356,-871,1628,-1287,-827,1604,-1315,-819,1956,-188,-309,2044,-98,-420,1953,-129,-340,-1198,629,-2483,-1168,465,-2485,-1257,624,-2456,1980,537,-163,2239,789,-309,2195,830,-289,1752,-904,-749,1760,-931,-709,413,3311,-1920,425,3283,-2037,366,3230,-2078,-1157,369,1888,-1111,372,1900,629,-953,1777,601,-981,1742,559,-1012,1752,1634,-1190,-598,1588,-1346,-525,1990,638,-74,1943,558,-46,1990,622,-143,-32,-440,-2392,-47,-525,-2282,-62,-328,-2431,831,2038,-2686,864,2165,-2663,910,2111,-2641,1898,-463,-1094,1845,-512,-1014,1822,-701,-1018,2669,-3930,-1066,2649,-3794,-917,2761,-3929,-905,-644,90,2096,-525,151,2120,-596,293,2014,-84,-1060,-2053,-85,-907,-2104,1527,-1314,-1152,1541,-1298,-1122,2094,1567,-1447,2158,1472,-1471,1383,-2524,-33,-1923,938,-1858,1436,2247,-2410,1416,2125,-2490,1349,2282,-2463,1178,2483,-2457,1115,2483,-2407,1183,2572,-2337,1231,-989,-1600,1182,-951,-1635,1262,-931,-1636,-382,657,1789,-449,647,1782,-1709,-991,-813,-1702,-987,-888,-1722,-1036,-859,-310,-182,-2496,-2100,832,-270,1892,-3295,-774,1803,-3180,-527,2121,-3431,-612,1483,-217,-1716,1581,-364,-1606,1497,-430,-1664,-493,1727,-2776,1884,2232,-2038,196,3350,-1972,-1714,267,-1907,-1590,317,-1959,-1536,46,-1876,-1141,-1286,1649,-1207,-1282,1575,1106,1821,1953,-362,-1129,1851,-445,-1084,1811,-370,-1077,1906,1335,3293,195,1281,3289,262,1369,3276,275,-2001,687,-216,945,927,1966,1070,855,1914,958,954,1978,-187,-142,-2490,1482,2117,-2460,1500,2229,-2424,-2057,2261,-1318,-2071,2364,-1204,-2071,2392,-1308,565,3058,-2204,1642,-1290,-861,1649,-1258,-831,639,605,-2682,691,535,-2667,699,657,1793,641,662,1849,737,642,1876,887,448,-2564,957,456,-2515,831,251,-2500,-325,2704,1958,-265,2615,1998,-258,2683,1942,-1614,1732,-2337,-1544,1608,-2423,-1661,1653,-2378,17,306,-2684,357,-1453,-1906,294,-1454,-1937,345,-1373,-1903,723,3576,-1504,802,3446,-1654,698,3472,-1682,1803,2233,-2061,-726,2828,1727,498,362,-2626,563,326,-2600,475,243,-2607,96,2173,-2715,151,2191,-2690,165,2050,-2751,1111,3027,1234,1005,3046,1250,992,2978,1302,1355,-3537,320,1733,-3500,13,170,-462,2607,104,-485,2678,82,-508,2566,-940,-1605,-1514,-901,-1630,-1544,-504,938,1915,545,3694,-240,599,3742,-298,1417,1227,-2512,1546,1266,-2449,207,146,-2617,220,272,-2654,283,263,-2644,-1323,-1264,-1406,-1322,-1352,-1341,-1501,-465,-1561,-1564,-520,-1502,-1570,-428,-1514,-336,-1146,-1990,-388,-1199,-1952,-378,-1076,-2044,-1739,1604,721,1318,507,1689,1357,498,1666,1339,519,1668,-1221,-986,-1600,-287,2715,1935,-1682,-673,-1269,-1651,-616,-1282,385,3006,-2320,376,2894,-2402,319,2894,-2414,1915,-312,-582,1865,1468,357,1823,1477,489,1877,1441,411,-1330,3481,-705,-1242,3460,-616,-1220,3501,-708,1691,-1166,-899,2275,854,-356,-421,-1745,-1784,-451,-1791,-1755,-489,-1711,-1792,-1843,-328,-1191,-1841,-459,-1236,-155,880,-2853,-162,1127,-2827,677,3305,1259,666,3355,1156,608,3274,1311,-1193,1915,-2636,-2068,-461,-409,-1371,-1822,641,-1456,-1632,354,-961,209,-2420,-846,215,-2395,-825,88,-2364,-202,-1223,-1998,-1989,-497,-221,1979,1825,-1878,1951,1685,-1882,1945,1696,-1961,2193,256,-807,1762,712,779,1746,475,721,1774,608,660,1519,-1241,-1172,1571,-1217,-1162,1859,569,389,1872,490,379,1863,516,321,2261,2026,-609,2260,2027,-764,1917,1874,-1927,1193,3287,634,1152,3355,542,2204,2117,-783,2201,2196,-885,1817,1652,462,1838,1748,449,1768,1692,582,-1958,2705,-827,220,3870,-567,227,3901,-689,2326,586,-921,2215,304,-931,2172,424,-833,-1517,748,-2354,-1357,578,-2394,745,-947,1816,-2093,1172,-597,-2061,1049,-597,-2072,1054,-481,4,3842,-1068,27,3904,-928,230,3444,1298,254,3538,1132,178,3497,1216,930,642,1854,1053,641,1853,1098,677,1756,2170,2557,-665,2150,2487,-647,-1147,606,-2543,-313,-707,-2145,1116,-1499,1613,1073,-1447,1682,1018,-1581,1682,279,1030,2155,266,915,2056,2372,821,-701,2324,863,-583,2302,821,-653,1244,-2707,-1383,1305,-2559,-1278,171,2831,-2483,-1334,-581,-1616,-1263,-647,-1615,-1369,-1582,-1227,-1427,-1543,-1161,-1421,-1523,-1191,1322,3225,-1592,2088,1982,-1386,2073,1760,-1503,2089,2018,-1485,-700,187,-2543,-618,169,-2538,508,-1878,-1683,498,-1805,-1697,576,-1775,-1667,-197,3896,-525,-102,3902,-501,-91,3924,-687,1074,3636,-787,1112,3607,-842,1009,3652,-888,1382,2561,-2288,1437,2546,-2233,1378,2458,-2303,82,3768,440,35,3796,401,46,-996,2074,114,-948,2023,216,-994,2034,2224,834,-1055,2153,761,-1025,2251,787,-1171,620,-1007,1881,524,-1060,1931,644,-1043,1876,1682,-1061,515,623,-674,2011,176,1768,-2815,-1996,2111,-522,-2001,2214,-279,-1967,2352,-510,-1641,2001,783,-1681,1957,716,-1698,1935,755,-536,2191,-2679,-537,2046,-2716,-610,2046,-2708,-2101,-287,-535,1139,606,1795,-1631,729,-2254,47,2519,-2611,1473,-1645,734,1508,-1548,434,1505,-1547,675,-55,3865,-972,-86,3801,-1124,-147,3863,-1005,53,-2665,1404,0,-2715,1346,-178,2262,-2666,-254,2271,-2677,-1427,2575,1017,-1407,2622,1022,904,-205,-2228,766,-218,-2263,766,-150,-2304,485,-1031,1851,426,-1056,1922,601,-985,1853,1840,1239,462,1826,1287,492,1846,1200,484,1581,-1146,893,1496,-1377,927,-1072,-1926,1433,1852,-53,-255,1829,-67,-261,-327,-109,-2511,1257,2401,-2452,1183,2399,-2446,1275,2486,-2377,1407,-3368,-1716,1327,-3022,-1491,600,3622,348,664,3582,396,662,3581,230,-2065,2223,-1142,-2097,2036,-1222,-2120,2001,-1114,632,2671,-2483,721,2668,-2419,753,3393,1031,802,3380,1014,793,3391,911,-1447,365,-2224,-1503,443,-2248,1827,1608,532,1825,1621,436,1819,1075,598,1829,1153,613,2162,1351,-323,-1982,446,-1533,-2004,401,-1367,-2034,559,-1547,-2044,-384,-392,-1303,243,-2232,-1203,18,-2189,-1362,120,-2128,-1978,-356,-320,-1130,-951,1727,-1108,-1112,1714,-1067,-954,1750,1092,-79,1995,740,2822,-2304,813,2861,-2332,-456,-995,1921,-693,-960,1827,-553,-962,1803,1053,-1463,-1574,1106,-1402,-1530,1113,-1470,-1534,-1710,125,-1818,-1747,288,-1854,-2131,1786,-1258,-2052,1578,-1332,-2110,1716,-1218,-1774,-573,-1221,-1746,-611,-1258,-1756,-660,-1208,444,3175,-2162,380,3121,-2219,399,3180,-2118,-1201,2193,1741,-1105,2367,1749,-1220,2366,1590,-2003,2574,-1067,-2026,2545,-849,1023,-1769,1567,975,-1753,1668,951,-1873,1606,2030,348,-510,2059,346,-533,-1184,154,-2260,-1234,251,-2256,1461,2055,-2526,-1089,-3599,-1955,-919,-3439,-1935,-984,-3745,-2032,-562,-1013,-1937,-527,-983,-2020,-521,-1057,-1942,2133,-55,-602,2110,-124,-636,2154,-47,-660,-1142,-645,-1737,-1205,-652,-1724,-1207,-565,-1733,-371,-466,-2230,-432,-444,-2263,-435,-347,-2268,306,1462,2268,-16,-235,2863,1112,-3928,-2044,774,-3924,-2130,917,-3746,-2052,-273,-1807,-1833,774,3684,-460,727,3677,-259,655,-3801,911,838,-3927,886,803,-3797,856,-345,2453,-2602,-279,2434,-2618,-1795,-387,-132,-1865,-390,-184,1558,-1281,-1087,1599,-1271,-1082,671,2414,-2602,554,2441,-2613,616,2457,-2560,1446,-1010,-1318,890,-1378,-1722,25,-949,2042,-1870,1209,-2021,-1887,1122,-1981,-1576,-576,-1435,-1526,-646,-1446,1444,2666,-2117,1488,2755,-2022,1506,2676,-2033,1617,1488,-2374,2169,652,-1073,2117,573,-1143,7,-953,2267,-42,-990,2236,74,-973,2246,-381,3731,252,-314,3746,167,-1429,-1394,-1241,-1394,-1372,-1307,-1389,-1424,-1261,1920,-3770,-1742,1979,-3931,-1809,1710,-3787,-1885,15,-1266,-2010,-24,-1158,-2036,55,-441,2792,30,-364,2860,-1885,-340,-270,1367,-300,-1839,1374,-485,-1763,1311,-600,-1751,-1497,-588,-1494,-1512,-675,-1498,2121,1156,-184,2030,1029,-155,2169,1142,-342,1493,-2876,-163,-409,1185,-2816,-466,1301,-2780,-412,1296,-2797,1459,-2667,-956,49,-845,-2133,72,-972,-2062,1963,-176,-786,1953,-372,-761,1969,-264,-817,-234,259,-2697,1963,1460,131,368,-2470,1451,571,-2477,1244,-1836,816,-1997,-1888,976,-2036,-905,312,-2480,434,997,-2798,406,952,-2826,1231,-10,-2104,1189,138,-2257,1317,181,-2132,1548,-532,-1553,1495,-468,-1573,1681,-3298,-79,1453,-3338,115,346,1518,-2839,308,1627,-2789,422,1577,-2826,-1576,2405,711,1205,-2366,-1366,1294,-2209,-1284,616,-2628,966,696,-2619,863,692,-2565,927,-1519,-851,-1329,-202,0,-2556,2195,700,-1212,2251,779,-1331,1336,3197,599,1364,3210,450,-157,-474,2551,-90,-486,2691,-229,-420,2613,-1782,-654,-309,-1811,-630,-410,-1737,-820,-358,-1937,-3929,212,-1552,-3929,413,-1332,-3858,537,1388,-322,1723,1315,-645,1710,1482,-308,1548,-1702,-941,-1148,-1661,-922,-1176,-1618,-1048,-1184,-2150,686,-289,-1415,-2367,-1079,-1399,-2635,-1109,-1455,-2603,-944,2404,605,-812,1074,2242,-2585,973,2235,-2577,1041,2270,-2522,281,1061,-2828,338,1136,-2822,-1809,-634,-232,2006,779,-63,199,3649,799,249,3623,862,726,3651,-1360,673,3608,-1429,647,3671,-1289,1481,-168,1588,73,-104,-2567,115,-119,-2528,110,-220,-2516,1187,-1850,1302,1026,-1925,1494,-1985,156,-1013,-2032,298,-1050,-1979,119,-1049,-2024,399,-1092,-2020,444,-1036,186,3182,1668,169,3158,1741,210,3026,1818,1639,-1228,-797,-331,-1522,-1888,-337,-1726,-1835,1984,-3742,106,2092,-3928,97,-862,2783,1650,-849,2847,1624,-955,2821,1553,1760,2522,547,1678,-1126,-1009,1639,-1157,-1014,1638,-1110,-1037,1785,2700,309,1751,2721,364,2399,867,-769,703,2628,-2489,2273,1975,-344,2152,1783,-153,2147,1752,-295,311,3464,-1813,937,656,1762,845,648,1783,-1785,-678,23,-1773,-512,234,1470,-1596,804,-1482,1155,-2464,-1447,963,-2432,-221,693,2000,-265,659,1945,-281,588,2000,-2180,819,-282,-928,1840,2056,-1720,-3276,-141,-796,2205,-2638,-766,2119,-2670,-854,2174,-2642,-1377,-2543,-30,-1473,-2433,-320,-1446,-2659,-199,1885,-556,-836,1932,-436,-854,1902,-502,-796,-76,-3279,1000,-248,-3261,929,-107,-3371,984,-1996,1861,-118,-1948,1867,-2,-1950,1978,-64,2139,-82,-895,2079,-203,-823,2120,0,-888,-1800,1994,-2161,-1466,2931,-1798,-1392,2923,-1991,-1430,2826,-1937,-986,1659,-2739,-892,1657,-2726,-565,3494,-1632,-547,3329,-1906,141,3534,1154,-774,2538,-2561,1527,277,1515,-105,-2778,1233,-2073,566,-239,254,1285,2260,381,1381,2233,420,1479,2230,918,-2394,759,1234,3319,344,1259,3358,290,1194,3362,286,495,3625,519,593,3576,556,610,3588,445,2095,463,-1085,1069,-935,1753,1052,-805,1780,1016,-796,1776,-1062,-1381,-1541,-1031,-1403,-1593,-1014,-1447,-1560,-642,-11,-2469,1043,3612,-1013,1002,3618,-1109,983,3666,-955,1102,704,1746,1151,678,1762,506,-1731,-1760,563,-1669,-1703,520,-1734,-1704,1271,3394,10,1302,3349,35,142,810,-2760,175,720,-2757,134,715,-2791,47,-635,2309,141,-629,2283,122,-528,2317,1738,-501,-46,1744,-414,-55,1727,142,930,1736,245,712,1459,-2414,-949,1489,-1908,-1014,1064,3119,1153,-222,-741,2242,612,682,1776,-1850,1689,-1911,-339,2809,-2414,92,3519,1255,62,3552,1179,4,3465,1287,-433,2811,1862,-582,2841,1805,-445,2758,1872,151,-3340,968,584,654,1874,824,-2835,751,-1990,702,-243,-2001,675,-137,-1998,740,-190,-1949,-297,-917,689,2944,-2252,624,2943,-2313,639,3005,-2247,-1462,-1450,-1179,-1412,-1447,-1200,-305,-2540,-1829,-508,-2407,-1761,-370,-2376,-1798,-1899,1839,204,1934,1172,194,2034,1234,82,1293,3334,131,1222,3424,89,-187,297,2480,-604,1998,-2742,-664,2005,-2695,-42,3648,-1577,645,-3136,789,515,-3217,834,-1327,2667,1145,-1368,2694,1066,-1394,2648,1059,-471,3092,-2221,1494,2235,997,858,-1687,-1572,859,-1629,-1576,-1341,547,1658,-1404,-873,-1495,-1386,-783,-1484,-1368,-832,-1541,-551,-1106,1940,-668,-1125,1842,-506,-1334,1975,1048,-1622,1621,-764,1483,-2764,-844,1425,-2751,1963,2857,-914,2020,2883,-672,2041,2812,-681,-710,393,-2647,-559,253,-2612,-668,232,-2577,2101,2131,-1386,2125,2050,-1322,923,3651,-1016,1944,1725,202,2039,1713,12,1834,445,438,1853,415,371,-855,-3928,879,-902,-3810,818,-996,-3929,797,-1197,3347,-1483,-1264,3308,-1577,413,-1001,1953,381,-979,1926,1453,-1822,61,1396,-1795,187,1370,-1861,216,1872,1036,377,1913,1123,366,1863,1084,438,-1904,332,-283,-1937,447,-223,-1978,439,-263,-345,345,2158,-368,408,2078,-470,347,2046,-1646,2528,-2100,-1633,2318,-2258,-1666,2363,-2150,1839,-96,-1436,1896,-7,-1449,1872,-77,-1352,279,1726,-2773,242,1783,-2756,986,-237,-2161,891,-287,-2193,87,3723,763,174,3701,647,132,3739,645,826,949,-2694,902,955,-2714,2026,2311,-1456,2059,2441,-1342,1774,924,769,1799,1078,683,1756,1324,775,-1426,-2991,3,-1374,-2821,-17,628,22,-2469,672,-43,-2391,-1405,-1491,-1237,-1381,-1464,-1250,1782,1892,550,1761,1880,641,1784,1803,594,-1413,1018,-2476,-606,3626,-1381,-712,3638,-1348,-629,3682,-1239,-947,-734,-1841,-878,-764,-1944,-926,-817,-1880,230,-1656,-1859,263,-1656,-1900,1189,664,1759,1158,731,1792,1154,701,1802,637,3136,1477,751,3148,1415,682,3188,1363,1993,546,-1667,2056,641,-1633,1976,491,-1593,-1488,-588,-1558,-1463,-513,-1617,-1436,-583,-1578,1307,-3872,555,-1417,-1343,-1248,1038,553,1877,-369,1704,-2784,-316,1731,-2765,-301,1657,-2828,-81,-263,-2465,-106,-323,-2399,-121,-223,-2477,-555,-930,1752,248,3836,-451,315,3812,-395,311,3847,-525,626,1574,-2792,701,1515,-2796,1121,-1374,-1613,1045,-1264,-1605,1138,-1231,-1633,-1333,3432,-500,-2021,1471,-1795,1792,-755,-749,1588,-1336,-949,1618,-1316,-920,1615,-1299,-887,2000,2528,-1515,1929,2586,-1644,915,-876,1834,913,-1242,1787,375,745,1771,-152,2711,1999,-161,3729,479,1922,1374,200,1909,1458,202,1939,1428,265,2101,833,-1595,2124,850,-1516,301,3694,363,-567,2661,-2506,-133,-3859,-2195,1809,-67,94,1849,38,220,2105,2584,-1070,2077,2460,-1232,-598,446,-2641,0,2671,2016,39,2706,1995,-70,2706,2032,646,-272,-2250,613,-209,-2320,543,2194,-2683,572,2268,-2674,637,2250,-2652,-638,2182,-2680,-590,2259,-2665,1623,-170,-1676,1271,-1265,-1457,1306,-1232,-1402,349,-349,2474,449,-332,2223,410,-315,2340,2,-527,2325,94,-510,2358,-1302,1006,-2539,-1779,2195,495,-1707,2107,641,-1513,-2508,-483,-1541,-2774,-386,-221,2929,1915,-173,2870,1983,1899,294,32,1917,365,76,1279,558,1676,373,3498,-1602,311,2506,-2598,286,2556,-2592,-1663,834,-2237,-1636,863,-2319,-2014,-3787,109,-2107,-3929,79,-458,-774,2120,-1735,182,-1761,-1800,291,-1747,-512,-1061,1938,-395,-1190,2057,-407,-1112,2008,399,3114,1651,147,-329,-2423,86,-397,-2384,61,-303,-2457,122,382,2537,183,309,2484,-1647,761,-2179,-2024,288,-964,-2012,410,-992,1835,98,-1562,1888,88,-1510,1220,2955,1104,1236,2958,1014,902,-2088,1501,-1964,342,-1455,674,2153,2098,566,2067,2150,625,1932,2174,2252,1865,-611,2190,1772,-702,2267,1946,-714,1412,-310,-1804,1413,-522,-1653,1937,835,176,245,3420,-1902,793,2913,-2253,1633,-1270,-960,1636,-1282,-909,1606,-1298,-971,364,-1130,1852,330,-1104,1930,438,-1088,1816,1652,-1200,-984,1612,-1223,-1034,-1435,1464,-2528,-1463,1412,-2514,26,1430,2329,-29,-849,2296,-47,-797,2317,1810,773,622,1844,687,484,1831,902,595,1687,-897,-1130,1679,-962,-1117,1622,-987,-1135,-91,2222,-2678,-146,2212,-2723,1472,-625,-1617,796,-659,-2019,809,3721,-811,880,3690,-698,911,3701,-791,485,721,1791,-720,-3237,719,-715,-3094,762,-915,-2905,695,1794,1757,528,1793,1753,611,1940,503,65,1925,523,146,1896,449,133,1435,741,-2394,180,-2339,-1821,-148,3423,-1844,-198,3527,-1763,-160,3551,-1644,-14,-1691,-1921,-51,-1718,-1933,1026,755,-2648,1022,918,-2677,-1364,508,1669,1077,-2390,-1456,885,-2258,-1547,738,1403,2159,-61,-1817,-1896,1561,-1071,-1246,1520,-1099,-1258,-1448,-1412,-1177,-1489,-1399,-1166,-1472,-1372,-1168,-1629,1969,844,-1612,2030,870,-1662,1971,802,-2100,1322,-386,-2047,1360,-450,488,-790,2127,462,-860,2127,549,-854,2069,1711,1788,730,1902,1423,-2017,1837,1202,-2068,1835,1422,-2106,883,-2564,703,902,-2444,725,719,-2658,795,-1093,2913,-2175,-1198,2926,-2120,1995,1363,71,1971,1258,138,2025,1356,-17,-829,2552,1842,-572,2749,1821,-804,2696,1738,896,1654,-2711,1898,2029,313,1977,1987,97,-944,-213,-2150,-911,-161,-2225,-1597,-629,1065,-1696,-529,858,-1606,-900,941,1914,2907,-1087,2019,2685,-1266,1880,2830,-1252,410,3806,-701,411,3850,-836,228,-1001,2122,385,-1005,2032,2311,1680,-607,2266,1796,-527,-323,-895,-2067,-291,-894,-2110,-287,-1023,-2051,-1297,3282,-1457,-1257,3341,-1438,1430,1812,-2576,1374,1678,-2591,2074,876,-577,2134,994,-535,2048,862,-409,2053,362,-746,1939,2683,-30,1897,2828,-171,1855,2822,-27,-2020,2445,-804,590,3657,-161,574,-293,-2313,-968,-1519,1734,-1049,3672,-950,-989,3666,-809,1805,-102,326,1781,-298,361,1794,1439,613,1822,1355,556,-290,-385,2465,-239,-301,2433,-242,-379,2479,1053,2386,1793,-106,-626,-2233,-109,-464,-2337,-81,-604,-2277,1611,1447,1139,1571,1764,1089,686,1070,-2789,1499,3138,337,1472,3030,462,-14,-1593,2122,-129,-1437,2145,-168,-1566,2107,1951,623,60,1951,616,129,1293,3464,-450,-2616,-3818,-433,1180,-961,-1714,1120,1604,1968,1322,1550,1816,1082,1691,1997,-308,-335,-2347,-390,-295,-2342,-391,-219,-2370,70,3408,1406,184,3365,1459,132,3475,1333,-1537,2088,993,-1642,1924,872,-2088,1436,-751,-2079,1597,-741,-2056,1505,-905,226,-1438,-1936,67,-2870,1178,2,-2836,1206,809,-992,-1909,-495,-2766,990,-520,-2614,1072,-686,-2558,932,27,3683,760,-45,3724,628,-85,3699,749,1159,-3190,307,883,-3313,555,2324,1289,-939,2266,1130,-856,2259,1036,-945,-1467,-1315,-1204,-1476,-1369,-1210,-1483,-1342,-1174,-1760,-669,-1161,1997,2779,-1005,2036,2721,-1051,2008,2733,-1117,-568,-974,1987,-697,-958,1867,-501,-997,1958,378,-704,-2118,386,-851,-2013,349,-806,-2085,-1034,-370,-2038,-996,-242,-2108,-1664,970,-2203,1367,-2173,-1199,-1311,3403,-175,1951,1074,-1985,-221,3740,224,1553,-1361,729,-1782,-420,-140,-1855,-462,-306,1721,834,935,1740,581,904,-2074,646,-365,-2188,805,-436,-2184,752,-489,-605,3731,-1172,-602,3787,-944,-1696,-3245,-1159,-1685,-3079,-783,1466,355,1636,1594,1170,1338,-345,2016,-2728,-284,1926,-2749,-610,693,-2726,-716,778,-2711,-680,809,-2780,-1507,-1328,-1196,1589,-1126,-1126,1613,-1206,-1090,1560,-1215,-1105,2260,1409,-1228,2225,1411,-1166,2275,1315,-1166,1278,2314,1530,-547,3805,-873,-611,3839,-803,2090,552,-266,1248,3346,220,1198,3410,235,1972,181,-1377,1903,99,-1404,-1519,3282,-1015,-1496,3209,-1347,-1626,3175,-1115,-811,-430,2063,-920,-528,1989,-839,-546,1994,-731,-943,1791,-712,-932,1771,-57,2188,2209,-1445,2038,1325,-1571,1814,1058,-1498,-1574,641,-1495,-1529,759,-1567,-1356,602,1695,-1134,-871,-1599,-1273,-943,-1575,-1341,-1027,-1556,-1343,-996,-1552,-3326,-1563,-2018,-3771,-1656,-2005,2341,-816,-2040,2271,-991,236,1902,-2804,539,542,1818,668,564,1900,141,-680,-2201,132,-772,-2160,2181,2423,-831,2186,2614,-830,866,-784,-1977,638,-2067,1791,471,-2183,1736,259,-985,-2082,214,-938,-2080,-1300,801,1763,-1419,746,1641,1045,748,1714,1070,692,1712,924,-2836,701,-31,-1188,2133,-39,-1157,2072,-100,-1164,2088,1939,661,197,-405,-120,-2417,-373,2339,-2652,693,3514,763,726,3489,830,743,3485,724,1585,2797,474,1629,2696,654,152,-1150,2061,-1856,-489,-320,-528,958,-2780,2113,-21,-581,2010,28,-550,2009,2272,-1540,2004,2132,-1638,930,3676,-656,978,3660,-705,-1248,2747,-2255,-2191,350,-721,-2187,296,-807,-2123,23,-764,1401,3255,-1396,-451,2418,-2663,-510,2431,-2631,766,2480,-2571,177,-3096,1027,123,-3005,1104,-186,-3499,1015,-256,-1714,-1878,1911,1214,300,1869,1175,391,890,3563,0,957,3545,-109,920,3582,-66,899,534,1919,890,573,1910,791,582,1916,-1741,835,-2098,-1653,687,-2115,-558,657,1860,-435,700,1765,-479,714,1800,-1826,51,121,-1850,154,113,82,3592,-1676,1092,-1209,1708,1037,-1031,1748,1001,-1064,1767,694,-440,2045,849,-568,1972,729,-426,2070,-209,2033,-2746,-180,1903,-2783,-137,-1490,-1934,-74,-1398,-1972,372,-2574,1294,-2032,2244,-1505,-2076,2126,-1483,1718,2153,-2172,1762,2060,-2211,1524,-2540,-554,1509,-2636,-759,1509,-2459,-727,-1948,1594,-64,-2023,1613,-216,-1982,1534,-143,703,-3466,727,1326,-1291,1326,1406,-1063,1260,1329,-1055,1469,-24,79,2738,731,905,-2741,658,763,-2746,1733,1834,695,2039,2515,-1407,2040,2630,-1394,1141,3474,-1344,1898,2488,-1804,2102,1792,-1407,2144,1672,-1381,-237,2603,-2582,-290,2724,-2498,136,3740,502,1731,1511,730,1712,1587,801,1733,1512,812,311,578,1972,315,454,2103,-2025,1534,-316,2136,821,-272,1237,3464,-243,1242,2877,1162,246,-2279,1781,-2229,543,-660,-2246,553,-698,1515,-2304,-596,890,3226,1111,901,3208,1208,140,-879,-2095,180,-994,-2070,125,-1060,-2053,424,3770,-1102,547,3765,-1112,494,3746,-1202,-1002,-1379,-1588,-955,-1457,-1600,1168,1196,1956,980,1296,2067,-199,930,-2847,-543,-686,2065,-689,-716,1951,-660,-735,1969,729,-1771,-1595,794,-1703,-1575,1019,1755,-2708,1102,1843,-2669,-347,1374,2236,-285,1060,2168,-177,996,2222,-2803,-3928,-793,-2767,-3836,-705,-2701,-3809,-861,-1130,907,-2625,-1292,1042,-2617,349,1259,2203,1529,2774,-1931,1452,2816,-1967,1453,2974,-1777,513,666,-2752,-371,685,1771,1136,-2201,516,1107,-2266,522,950,2409,-2548,1047,2424,-2524,2099,763,-469,1959,441,-568,1979,580,-409,960,-210,2063,334,-1172,-1969,306,-1254,-1964,759,649,1793,180,-394,-2368,198,-443,-2335,156,-558,-2257,-1354,-1545,-1259,-1740,1716,742,-33,-904,2273,-1239,364,1848,601,2332,-2645,-2080,1063,-940,-2132,1049,-1016,215,2918,1894,212,2787,1930,248,2889,1860,1677,-737,-1249,1649,-815,-1165,833,3333,1096,887,3287,1075,869,3312,1024,-1493,-310,-1667,-1540,-335,-1623,191,-932,-2134,616,-1787,-1652,608,-1874,-1638,931,2548,-2457,-1783,948,-2081,-1781,751,-2041,504,-2600,1117,643,-2518,1069,-1351,1224,-2558,1716,3060,-1192,1793,3031,-1043,1796,2984,-1258,-719,2379,-2632,-585,-730,2038,-659,-762,1979,1186,3299,695,1159,3242,813,-1570,-1143,-1104,-1543,-1147,-1152,-1569,-1182,-1143,-511,717,-2772,-614,1026,-2797,463,3486,-1626,-452,3817,-1053,-494,3764,-1061,-499,3809,-916,-190,-1004,2069,-175,-979,2031,1539,3061,-1486,1645,2986,-1520,2295,800,-827,1134,705,1813,-1022,-1638,-1516,-970,-1683,-1499,-1075,-1644,-1461,1581,2466,-2125,264,813,1927,-1804,-830,-970,-1816,-735,-1008,-1730,-778,-1013,1850,1014,494,1834,968,527,1853,936,482,1740,-793,-377,1772,-702,-520,1795,-638,-423,1947,1275,-1936,-525,1492,-2802,1767,-833,-720,1815,-716,-702,1802,-781,-685,471,-1859,2012,396,-1689,2047,390,-1966,2069,-1599,1570,-2378,-1531,1513,-2480,-1870,1556,355,-1803,1639,480,-1863,1613,295,177,3783,-1270,231,3836,-1101,221,3773,-1236,-959,-926,-1805,-935,-875,-1838,487,729,1725,547,792,1765,29,733,-2788,806,-2031,1637,590,-2138,1694,-1672,1410,938,-1576,1704,1105,-1682,1635,886,-760,-512,2007,489,-2739,1018,245,-2821,1138,-2025,-224,-472,-1991,-275,-372,-1959,-213,-308,462,-272,2201,456,-350,2135,686,3723,-1212,643,3787,-1000,1680,1969,760,1707,2015,747,1660,2041,766,1344,1367,-2579,-1685,2019,755,-370,2489,-2602,-197,-332,2337,-240,-320,2337,1010,-2244,932,1849,-231,-1302,1903,-176,-1261,101,379,-2685,1304,3040,920,1260,3053,952,-1781,180,-1724,-21,-284,-2436,-1944,2378,-283,-1132,2354,-2512,2060,420,-462,2131,455,-428,365,2772,-2496,383,2699,-2528,323,2684,-2507,1045,3484,-1462,1070,3448,-1520,1010,3442,-1575,-526,-2850,889,-235,-3060,1008,-1500,-30,1571,3,1112,-2798,156,1845,2278,-55,1662,2306,-156,199,-2649,-195,105,-2652,1812,2565,322,1227,3519,-791,1352,3476,-807,1246,3540,-859,98,3048,-2318,117,3097,-2250,-538,-947,2050,-472,-982,2056,-387,-927,2138,2075,-34,-530,691,1867,-2757,465,1642,-2831,538,805,1821,615,823,1791,-950,496,1923,-844,468,1929,-826,497,1933,1820,487,466,1863,788,485,1837,755,493,1861,749,454,606,-19,2139,681,88,2087,504,141,2138,1140,1158,1942,1156,-1558,1471,1993,1531,-1805,1963,1307,-1799,1986,1359,-1865,-102,2662,2015,-112,2711,2039,-1507,2438,-2276,-99,394,-2728,1255,383,1818,-1868,639,-1955,-1894,570,-1829,-1924,697,-1783,-1451,2659,-2159,-1406,2578,-2276,-1465,2568,-2174,1857,2405,208,1373,3295,130,-2060,-199,-617,-227,2920,-2419,-196,2978,-2342,-165,2862,-2428,-1372,2350,-2389,-1352,2287,-2473,-1448,2302,-2392,796,3541,-1493,1688,1618,-2326,-404,2115,-2697,1085,-1678,1512,1517,2381,-2241,1498,2426,-2270,-1644,-1077,-1048,1748,1798,648,295,359,2217,304,290,2249,573,-376,2089,1190,2667,-2310,1294,2563,-2317,1546,3181,48,1553,3204,-127,143,3165,-2214,-1311,1873,-2600,740,1102,2019,610,1153,2069,-775,3532,-1470,149,-1149,-1998,126,-1204,-2020,1017,2745,1506,1809,-3848,286,1837,-3928,266,-582,-2867,830,-318,-3082,929,2231,1855,-381,149,937,-2808,194,858,-2825,2039,343,-1190,1976,93,-1177,2045,228,-1241,-764,2762,-2442,-672,2563,-2575,1671,-1255,-904,-1305,-1453,-1319,-1588,-1187,836,-1539,-1131,992,-1660,-951,771,-255,2457,2110,-123,2311,2193,-87,2468,2131,-615,-3664,869,-701,-3686,830,1130,-1255,-1554,-2063,555,-260,-2037,502,-242,-1298,-1784,1128,-1342,-1632,1133,-1371,-1759,932,-729,-564,-2055,1962,387,-298,-1842,544,-1919,862,3421,-1693,1666,-1074,-1033,1638,-1072,-1061,1646,-1012,-1056,953,840,1920,820,845,1894,279,-932,2197,293,-904,2198,1617,2207,-2250,1563,2122,-2341,2034,2419,-218,2198,2338,-389,2157,2432,-426,1923,578,232,1894,511,201,191,3448,1264,194,3438,1354,826,-1951,1728,251,-1243,2135,270,3300,1534,1943,701,86,1442,-1281,1116,1384,-1517,1095,1039,-419,1992,-2043,1118,-434,-2034,1080,-262,2197,209,-585,1739,2295,-2095,1803,2321,-2054,742,470,1921,668,504,1896,670,462,1882,689,1020,2000,1955,91,-1274,-1609,2306,753,-2110,716,-341,216,-1151,1981,261,-1178,1919,187,-1191,1950,-340,2348,2136,-990,2506,1761,-919,2459,1843,-917,581,-2538,-1007,593,-2565,-1014,694,-2551,1300,989,-2532,1218,895,-2532,-1855,-646,-1015,-1893,-555,-931,-2120,1997,-994,-2118,1893,-1168,-1923,-389,-1045,48,2555,2084,1801,2001,-2174,2263,1123,-1020,2327,1224,-1020,-869,3133,-2042,-174,-389,2441,-176,-438,2494,-190,-325,2440,1972,214,-758,1964,368,-691,-2084,1028,-1648,1881,1541,392,1799,1548,495,1373,3301,64,-1576,-807,-1331,-910,641,1861,-1113,655,1811,-1045,639,1859,327,-1702,-1816,313,-1635,-1855,-1210,-454,-1851,-1262,-510,-1757,-1273,-400,-1801,1865,-600,-704,1911,-539,-744,1436,3243,171,1502,3212,157,-1308,-581,-1683,-2254,856,-508,639,-1281,1867,692,-1334,1838,-596,1423,-2780,-625,1513,-2769,-1652,-1038,-1135,-1596,-1089,-1151,-1637,-1073,-1126,-2132,1501,-1211,-2148,1279,-1203,-2151,1367,-1147,1854,719,369,1954,783,308,1922,828,345,582,-1138,-1895,629,-1179,-1853,1542,-1422,-108,-1509,-1721,-230,-1485,-2009,-288,-1479,-1898,-58,-44,3866,-1120,-43,3802,-1244,557,-1004,-1961,546,-1108,-1966,-521,827,1865,-110,2825,1978,1981,767,-137,2019,851,-209,-1879,970,502,-1865,862,488,-1848,1047,539,899,-353,2069,-1205,-3246,273,-877,-3296,557,-1003,-3139,452,-150,-402,2769,-24,-437,2810,-98,-380,2826,897,905,1940,774,869,1928,984,110,2006,1104,183,1954,-255,-464,-2296,-188,-500,-2317,-200,3087,-2249,-156,3030,-2343,-1009,1945,-2684,-937,1975,-2681,1745,-498,-1331,1775,-441,-1302,-2380,857,-677,2105,1029,-344,2065,934,-356,2188,1074,-524,546,3448,1092,1611,2408,-2096,1598,2334,-2198,2209,1181,-485,1664,-1121,-962,1688,-1077,-977,-217,-876,-2135,-458,-333,2159,-471,-353,2126,-170,-1120,-2036,-112,-1187,-2035,981,-1294,1758,-1949,525,-106,-328,-249,2510,1268,3326,432,1308,3253,368,434,-460,-2216,439,-350,-2322,-109,190,-2685,-106,80,-2606,198,2251,-2697,-1902,317,-1,-1914,371,34,-1702,-398,-1436,-1668,-316,-1484,1668,1733,895,1743,-837,200,1743,-825,-113,1661,-89,1137,1729,-329,796,1732,-88,846,-1743,-767,-542,1430,-1327,-1259,1415,-1328,-1303,944,3255,-1905,-2301,803,-694,-2255,852,-568,-2117,1715,-1466,1202,3386,-1469,1125,3448,-1458,-2091,1043,-1087,-2089,929,-1039,1633,-1256,-858,-1766,1277,739,-1710,1050,898,2201,2091,-942,-95,-691,-2183,251,540,-2718,346,464,-2721,2065,2542,-1263,1161,-1281,1634,1388,413,1702,1359,483,1690,-2281,523,-831,-2323,668,-819,-2321,520,-856,2008,245,-824,2287,499,-839,2316,675,-808,1006,-1688,-1475,1046,-1679,-1448,1173,911,-2607,1043,690,-2586,1156,1017,-2639,1223,-1216,1590,1168,-1375,1592,1222,-1428,1440,357,3484,1129,-1128,3574,-704,-1125,3570,-583,1066,-1604,-1471,793,948,1950,1082,3159,-1937,1113,3078,-1976,1092,3055,-2026,306,-837,-2063,273,-752,-2162,-1141,56,-2230,1166,-3305,326,1342,-842,-1581,1350,-842,-1523,-1068,1238,2001,-1001,1169,1995,-958,1250,2045,2616,-3716,-558,2156,-3515,-382,2319,-3637,-374,1613,629,1318,-2172,143,-815,1140,3379,357,1095,3401,451,1145,3371,475,1725,-1047,-817,1694,-1114,-798,-1492,-422,-1655,-1402,-462,-1619,515,3666,100,528,3637,188,580,3639,156,1811,2265,553,1694,2285,729,1714,2171,682,-389,3654,-1421,-1808,1325,534,-1814,1224,559,-1781,1361,610,-352,1951,-2757,290,3002,-2328,297,2951,-2383,250,2948,-2353,-1826,1382,564,-1439,-806,-1466,-1449,-727,-1484,-555,-3140,815,-830,-2839,745,1827,-651,-738,1863,-609,-763,-260,3730,132,-196,3782,138,222,58,-2592,271,108,-2567,-69,-333,2860,27,-304,2871,1835,273,261,1892,238,236,1890,349,199,806,3701,-538,837,3691,-470,343,3195,1624,352,3242,1523,181,-1746,-1880,172,-1871,-1831,149,-1786,-1879,884,-2312,1043,1008,-2189,1042,-675,-599,2006,-1375,1120,-2505,1978,485,-642,1947,483,-538,1371,1197,-2556,1295,1210,-2575,-195,-1464,-1989,-198,-1590,-1943,-228,-1534,-1904,-906,927,1952,-853,901,1935,1834,210,290,112,3350,1493,14,3347,1607,104,3283,1618,-1446,-1690,794,716,-953,1817,1526,3282,-208,887,1656,2097,824,1511,2124,-1779,-173,-1442,-1687,871,-2129,594,208,2063,639,331,1967,-1422,-1739,632,-1483,-1611,453,988,3608,-531,978,3617,-420,2155,2045,-1114,2151,1881,-1219,1226,3445,-116,-1537,-1404,201,154,-1990,2162,1852,2990,-633,1869,2957,-507,997,1436,2086,1134,1376,2052,1810,-3699,209,1871,-3761,225,-973,-1769,-1481,-2010,2044,-1683,-1856,1094,515,-1817,1190,597,-1810,1552,514,-1840,1472,508,-1762,3018,-951,609,3765,-1114,-541,-1007,1871,-694,-365,2092,-780,-260,2116,-549,1937,-2763,150,-1461,-1963,119,-1401,-1991,161,-1363,-1967,799,-1589,-1639,852,-1617,-1639,487,1185,-2807,-833,-1391,-1713,-778,-1291,-1736,25,3602,1069,-861,-890,-1856,-840,-1074,-1803,40,3073,-2286,61,3145,-2237,240,3690,650,2078,2574,-1320,-2062,1154,-261,-2041,1066,-175,307,3428,1298,-136,47,2689,414,786,1800,-66,-715,-2232,-29,-701,-2199,1716,-1006,-925,1715,-1051,-900,1680,-1015,-1000,-2088,-172,-695,296,-690,-2157,50,-513,2396,118,642,-2744,-2003,202,-907,-2094,1948,-914,-442,1779,-2770,985,-879,1797,-1954,212,-757,-1951,-92,-772,16,-1188,2139,421,-1483,-1877,482,-1399,-1862,454,-1506,-1865,2113,2474,-578,2097,2535,-429,-1374,2160,-2496,-1309,2200,-2497,-1043,476,1899,-1044,532,1874,-1143,548,1817,-1870,369,143,-1899,464,115,-1389,-2278,94,-1399,-2058,131,-1408,2763,-2025,-1629,-529,-1428,-1644,-567,-1363,-1553,-1095,-1230,-1545,-1014,-1238,-1491,-1019,-1270,743,3231,1335,128,3635,-1585,102,3697,-1449,155,3737,-1400,1374,678,1665,1343,633,1665,1415,613,1627,918,-833,-1937,2019,486,-247,2032,499,-277,2130,693,-339,2234,920,-387,1105,-3756,626,925,-3792,798,-595,-1261,-1854,-531,-1186,-1904,-514,-1246,-1882,912,59,-2328,962,-26,-2266,835,-48,-2342,-555,-3928,979,-678,-3790,896,1934,672,291,1939,760,249,1664,2071,808,1632,2112,843,-31,1532,-2838,1742,369,-1786,1744,253,-1775,1652,285,-1794,983,3480,196,936,3535,148,858,3536,290,-835,3634,-1342,-916,3544,-1349,1592,199,-1793,1841,1234,514,1789,-447,-185,1784,-492,-141,581,-465,-2229,617,-531,-2133,-955,1094,-2739,-1460,-706,1319,-1422,-863,1315,-1390,-686,1536,116,2892,1917,90,2818,1930,2094,1314,-120,2076,1384,-155,-1864,954,443,-286,3421,-1845,-292,3327,-2035,-344,3322,-1993,529,-241,2114,-1055,3558,-566,-1082,3610,-774,815,-682,1926,909,-723,1863,838,-593,1953,-1029,1590,-2703,1542,-1864,-780,1540,-1853,-635,1130,-1542,-1486,1159,-1582,-1452,1245,-712,-1721,-1922,-489,-978,-1223,-586,-1668,-1240,-703,-1666,-1859,-215,-242,-1962,-271,-285,-1181,-562,-1802,621,2501,-2530,676,2553,-2556,708,-322,-2230,-476,3499,-1714,-493,3536,-1625,-611,-3246,792,1757,-900,-671,1728,-950,-689,-1502,-1653,-133,-1804,-778,-806,-1806,-741,-835,-1846,-761,-878,-640,3589,400,-679,3608,203,-1137,1066,-2701,-1389,737,-2409,-1837,-4,-174,-1018,-1012,-1687,1678,1938,807,-1102,1435,2021,-1143,1377,2044,-2202,706,-533,-2194,577,-512,-2113,633,-443,1615,2178,833,1824,277,-1692,1757,105,-1706,1787,307,-1744,-1924,1543,148,-2077,885,-904,-2023,799,-827,291,1437,-2825,-1762,-896,-788,-1517,1765,-2519,-1477,1889,-2524,-1463,1827,-2567,1413,2914,-1941,1373,2735,-2152,-1702,1625,-2325,-2108,975,-1469,-2054,848,-1440,-2112,1103,-1405,1077,504,-2507,-1404,-1134,-1345,-1377,-1305,-1339,2130,1101,-1623,2151,1244,-1544,2137,990,-1549,1357,-2175,208,2057,-205,-532,1787,-542,-1188,1811,-389,-1244,-611,3655,113,-622,3621,336,-573,3660,301,-1505,3169,16,607,2565,1939,835,2544,1845,-1800,2870,-340,363,1062,2118,-1,3763,-1269,-114,3721,627,-42,3773,524,-1910,2800,-579,-2238,643,-603,-2242,705,-622,-1519,-1267,-1121,-1524,-1217,-1132,-1522,-1260,-1165,-2796,-3929,-580,-2816,-3929,-685,-825,-981,-1887,-717,-943,-1916,-2,3822,134,-52,3850,111,-31,3815,229,477,3738,-281,-1247,1108,-2626,-2255,810,-618,-1945,607,54,-1924,701,115,-1961,714,69,918,3610,-419,929,3627,-344,2388,796,-739,2388,892,-636,-641,-1656,-1702,-620,-1691,-1732,-643,-1750,-1684,-1032,-3362,446,1079,-996,-1729,1143,-908,-1763,1835,-632,-967,1788,-734,-943,1798,3007,-389,1860,2968,-304,-243,-1211,-1972,-267,-1142,-2013,-1031,575,1870,-1176,606,1776,1253,605,-2470,1513,-1969,-917,1512,-2132,-815,1921,-154,-292,-1049,619,-2509,1692,1069,-2262,-2107,1604,-1657,455,-2683,1078,2013,165,-870,1981,-54,-896,-1216,2826,1293,671,-945,1727,-1362,-1863,240,-1376,-1862,377,-1441,-1697,108,68,967,-2787,9,932,-2778,1015,3128,-1935,1627,3148,-1000,1547,3222,-1015,-1127,2780,1383,-1098,2817,1447,-735,1868,-2742,-759,1927,-2741,-1190,1099,-2650,-748,-1443,-1743,-691,-1419,-1747,-705,-1522,-1705,336,3386,1347,-2061,1780,-495,-2058,1801,-413,-43,1074,-2819,851,3624,-259,825,3656,-381,-1399,2466,-2338,-1749,2473,239,-1727,2352,344,-1745,2579,227,1763,-934,-880,1023,3524,-132,959,3555,-218,-244,-923,-2070,-351,-2096,2047,-512,-2115,1872,1,1992,-2789,-59,1900,-2802,-273,-772,-2103,760,2965,-2196,733,2921,-2313,-2065,1342,-1439,1119,-2960,375,1243,-2918,211,1899,-198,-1158,1901,-315,-1157,1825,-687,-886,-668,3587,-1469,-651,3491,-1610,175,-1355,-1939,255,-1349,-1940,1938,521,-91,1952,535,-128,1967,556,-95,-34,3444,1403,1328,2877,1070,-747,-790,1904,-757,-1775,1852,390,-1268,-1941,446,-1344,-1870,188,1220,-2853,247,1335,-2822,202,1118,-2826,-779,342,1951,-946,376,1928,2349,888,-549,45,-1569,-1953,69,-1584,-1902,525,3780,-750,595,3771,-824,2015,449,-272,2057,478,-252,-1932,2214,-76,-1970,2305,-197,1412,2824,947,714,-935,1782,1133,664,1796,2093,940,-1590,-1896,128,-1462,-760,1839,2125,-616,1711,2189,1109,96,-2302,1076,140,-2377,303,3863,-700,357,3855,-670,1288,2720,-2201,1314,2881,-1992,1203,-2425,458,726,217,2019,836,267,1977,1095,391,-2446,1183,3339,419,1398,518,1653,1344,547,1656,1842,2306,380,1527,3148,116,1550,3112,203,1568,3054,96,1152,631,1771,-638,2592,1906,-791,2437,1932,-480,2508,2020,134,-1518,-1957,144,-1635,-1940,550,3628,280,715,279,-2510,2010,-84,-412,1154,3523,-223,617,3454,1069,1216,1202,1943,1141,1316,2034,1263,3537,-727,1218,3506,-610,-2220,417,-639,-2194,153,-660,1317,-1926,316,1390,-1838,452,-363,1871,-2742,-1185,-1963,1165,-1250,-1915,1034,1654,2129,733,1642,2202,757,1306,804,1763,1443,807,1660,-175,2398,-2653,-151,2437,-2627,1881,-3273,-378,1805,-3300,-222,-336,2269,-2671,-393,2292,-2693,432,3605,646,401,3633,578,354,3635,651,372,1897,-2781,-1614,-62,1302,-1540,-1274,-1079,-1576,-1291,-1049,-442,1417,-2780,-1972,39,-1174,-1937,47,-1211,-1888,-194,-1197,319,3633,747,341,3588,958,384,3596,867,-633,-950,1788,-696,-950,1812,612,738,-2720,1877,928,443,1861,980,421,1849,1016,459,-1498,2535,-2162,768,-845,1875,760,-879,1864,-1676,-1130,-768,1210,3378,366,2238,1786,-779,-2234,539,-580,478,3260,-1973,456,3194,-2065,-1197,2516,-2406,-604,-1600,-1734,-582,-1438,-1801,-495,1829,-2789,-591,1772,-2782,-1286,2693,-2296,-1354,-3026,-1467,-346,199,-2664,-368,139,-2604,465,-705,-2093,471,-549,-2192,512,-614,-2113,-1993,304,-1406,-1955,219,-1423,571,976,-2776,676,927,-2773,513,888,-2761,-1463,-2886,-1116,-1349,-2803,-1309,1508,-1492,-1036,1555,-1454,-897,1542,-1607,-865,-1495,-1110,-1292,-1431,-1049,-1364,-579,2772,-2447,-735,2830,-2374,-455,-1433,2011,-377,-1677,2054,-328,-1545,2063,-6,1990,2251,-1698,1851,783,-1687,1791,820,1239,-3044,219,1750,-958,-957,1698,-941,-990,-310,1427,-2826,-359,1339,-2834,1907,1940,318,1877,890,504,315,-3247,897,216,-3168,967,-2175,262,-574,-2188,484,-513,-2202,244,-622,644,2864,-2331,875,3704,-622,701,3752,-744,-1076,3253,-1770,1859,-657,-709,43,-1024,2179,188,-1007,2076,112,-484,-2347,-1164,-1543,1468,2076,2704,-988,1987,2776,-912,1890,-51,-1288,-1397,435,-2272,-1571,-1274,-17,15,3027,-2359,-35,3076,-2271,-2076,972,-853,-1607,3206,-898,-1556,3228,-1080,557,3274,1384,506,3232,1417,-632,1629,-2774,-848,432,-2511,-938,500,-2488,-1172,-840,-1633,799,3497,606,857,3473,646,-217,2473,-2627,-600,-1008,1884,2200,292,-731,2230,451,-679,-566,2342,-2653,981,-715,1816,478,786,1828,466,814,1822,-1746,2580,-1909,2194,438,-491,-1822,84,168,-1562,-431,1251,-1679,-218,1009,254,39,2429,341,47,2299,-1654,1498,-2275,-1646,1428,-2362,60,1077,-2828,101,1154,-2841,-168,3668,-1516,-133,3652,-1552,962,-2005,1519,-78,-1207,-1989,-46,-1311,-1949,2249,1732,-424,2188,1654,-351,2024,1002,-188,-1395,2699,1012,-1409,2709,955,-1434,2664,998,-295,5,-2602,-1701,-30,1013,-1736,70,839,-750,-109,-2347,-679,-165,-2342,-1312,349,-2274,-1363,293,-2212,1102,-1505,-1495,1191,-1458,-1485,1217,-1496,-1440,-1990,1310,-1776,-1117,2501,1608,-1005,2623,1624,-1141,2643,1425,997,2057,-2641,969,2107,-2597,1042,2152,-2621,97,2602,-2599,29,2553,-2585,263,-1269,-1936,-1437,3086,-1710,73,3276,1701,1112,3313,731,1041,3350,766,1050,3333,813,1800,-488,-1260,-8,2834,1959,37,2763,1963,-1582,3187,-722,-428,78,-2584,-465,249,-2656,-202,1157,-2818,1583,-902,989,-1415,1110,-2460,2062,603,-800,2041,407,-849,1767,1440,721,1802,1474,673,-1306,-475,-1677,18,-797,-2189,18,-636,-2282,-228,-414,2505,-519,-1790,1981,-644,-1511,1888,-609,-1750,1921,1344,561,1636,1292,588,1627,2065,2099,-1517,-1842,377,323,-1864,316,290,-1858,249,313,1823,362,366,1868,369,303,1874,455,309,1922,407,-1623,1699,60,1062,-2137,-33,-654,-1266,-1057,-1484,-1239,-1105,-1539,-1818,-24,-45,-1832,27,44,-216,1228,2267,1651,-1136,-18,1691,-1029,189,1012,2993,-2166,1098,3271,865,805,-1136,1793,695,3285,-1936,758,3386,-1830,1498,3229,-1167,1542,3197,-1146,1561,3159,-1273,-374,-695,2172,-437,-659,2136,904,1903,-2711,771,1921,-2696,950,1943,-2665,1159,3221,882,-1005,3301,-1821,-1043,3302,-1751,1491,-1226,-1269,1542,-1169,-1188,6,1268,-2855,49,1262,-2834,818,3072,1461,722,3034,1550,864,2991,1553,-1352,-2649,-1227,-1227,-2873,-1481,-1360,2419,-2414,-827,550,-2647,-765,578,-2703,2047,-149,-411,-787,-1197,1791,-744,-945,1812,-429,1623,2237,338,11,-2555,369,-128,-2468,302,-85,-2481,362,2841,-2457,-452,3834,-851,-511,3852,-792,1074,613,1843,-711,504,1908,-697,486,1906,-512,612,1811,-158,-403,2380,501,1324,2216,-1304,-1948,363,-754,2283,-2647,-708,2203,-2686,-835,2277,-2611,1848,1227,427,-300,-1130,1929,2088,-103,-506,-441,-252,-2318,-2143,18,-643,1828,-723,-667,-1050,-3928,-2054,-1448,-3819,-1974,-2056,2167,-899,-2092,2174,-1014,-260,3204,-2174,-261,3326,-1982,-269,-305,2380,-339,-365,2312,-270,-310,2360,1614,2134,803,435,2730,-2476,426,2792,-2454,2088,1772,-36,2094,1900,-89,1771,-794,-661,2004,2315,90,2066,2311,-95,2045,2473,-36,271,-313,2355,314,-373,2281,344,-364,2318,-1966,-211,-1069,-1961,-141,-1019,-2001,-79,-1069,-1063,17,-2229,-1006,-11,-2302,-36,-1442,-1911,-2078,997,-1338,171,3319,-2052,117,-1714,-1888,-487,2625,-2577,-411,2492,-2632,-1158,-3766,589,-909,-3620,665,-845,-3509,636,-81,159,2679,-131,190,2613,-2080,2173,-1299,227,-948,1979,-1491,-1116,-1219,-2136,72,-626,-2060,186,-592,-2125,325,-532,-1692,-552,-1323,705,-983,1831,-1539,-1423,-1001,-1516,-1435,-1068,-1508,-1456,-1043,-1895,1312,301,-1869,1288,396,-1859,1355,405,-1158,636,1769,-1839,2810,-1311,-1947,950,192,-1969,1040,161,-314,-384,2265,-1475,2521,943,-1471,2307,1009,-923,-2399,732,-1048,1769,-2707,-1147,1695,-2693,-1440,645,1593,-2032,297,-571,1645,-1009,-1106,1639,-1099,-1092,1601,-1071,-1109,-1746,-862,359,-1649,-1115,653,-1730,-813,555,251,3113,1729,908,3560,-139,925,3602,-204,-293,729,1834,-329,852,1886,-1521,-310,1460,135,2418,-2651,-2161,421,-503,-2109,452,-455,489,-964,-2000,433,-871,-2034,468,-819,-2008,2018,683,-1661,161,328,-2670,789,-1930,1786,543,927,1885,423,850,1837,-1992,453,-1607,-1959,309,-1536,970,1870,-2702,1054,1991,-2647,1660,-3010,-444,1571,-2803,-585,1560,-2797,-416,893,1945,2076,947,2133,1986,-602,-822,2026,-627,-837,1996,-1979,233,-1093,1836,1095,501,1849,1072,542,-2010,-129,-987,-1979,37,-968,-1930,-3688,100,-2034,388,-517,123,661,2322,-1121,3039,-2012,615,-1571,-1764,1491,-763,-1456,1506,-644,-1405,1468,-3121,-1409,1387,-2912,-1330,1481,-2964,-1163,2255,476,-606,2254,595,-631,-548,1699,-2754,-1005,122,-2384,358,3830,-1004,318,3840,-923,904,-66,2073,1391,3330,-1238,1463,3231,-1349,1422,3296,-1338,1794,2170,-2135,1764,2069,-2128,1153,-1115,-1652,1098,-1122,-1657,144,3691,783,841,1793,-2694,-638,1394,2186,-819,1286,2071,-2110,19,-610,-2031,121,-601,1275,2817,1157,-58,457,-2780,-106,686,-2808,954,3653,-584,877,3650,-444,1436,3226,290,-2031,43,-582,-613,2914,1739,-639,2897,1726,-574,2883,1785,-2054,1416,-502,-1609,-3304,-16,292,1923,-2762,832,3343,971,875,3383,909,429,1498,-2802,643,-924,1967,-1379,-500,-1687,-1412,-569,-1636,-1868,427,264,-1914,532,226,746,1683,-2722,-1161,-730,-1738,387,3736,-157,-2128,897,-1151,-2074,767,-1152,1127,290,1942,1054,325,1936,-769,-911,1841,1784,92,-1597,1774,8,-1638,54,-1086,-2033,-39,3285,1645,1373,-1070,-1375,1393,-973,-1426,322,3204,-2147,292,3084,-2247,986,268,-2424,1107,284,-2421,-1182,-3873,630,0,-1159,2042,35,2622,2043,2163,454,-455,1916,2679,-1513,-2073,1133,-1163,82,38,-2601,204,3850,-266,1523,2193,-2370,1553,2298,-2298,-1309,-835,1613,-1316,-640,1706,-1363,-634,1637,503,3534,880,540,3517,940,592,3769,-1041,222,-425,2514,280,-395,2501,-984,626,1885,-150,2544,2077,-220,2569,2041,-518,-831,2091,-96,2150,-2721,-47,2198,-2713,605,3387,-1857,579,3275,-2006,2139,-325,-580,2106,-321,-504,2063,2528,-158,1523,2993,482,1482,2943,701,-1223,1394,-2677,1125,3432,340,-1165,-694,-1665,-1355,1132,1851,-1388,1172,1855,2217,1701,-1132,1663,-1226,-932,1625,-1252,-927,239,-3405,959,-1760,174,552,-1731,300,683,-1960,-29,-472,-2060,-28,-530,-2018,-74,-424,1555,-665,-1403,1977,-388,-787,1956,-460,-776,1835,1824,510,-1466,-1790,30,-1444,-1737,72,-684,-494,-2180,152,3878,-1037,1596,2143,851,-110,584,-2815,446,-183,2158,446,-219,2211,463,-232,2145,-888,-266,-2181,1871,1167,538,1680,-384,-1419,1725,-925,391,1248,603,1681,716,-3328,708,390,3601,743,-342,2613,1986,-375,2700,1927,-447,2701,1894,1473,-1507,862,1526,-1460,675,-1859,1545,-2098,-1827,1698,-2048,-1787,1625,-2146,-1809,385,425,-1854,393,361,-1820,298,372,572,-615,-2150,547,3804,-1005,588,3790,-914,1849,73,-347,1856,193,-290,-482,-1157,-1926,-752,176,-2487,170,-2026,-1819,-1273,-2566,-1318,-1351,-2412,-1201,-1724,1800,-2262,-1706,1719,-2239,1168,-1182,-1562,1203,-1260,-1496,1183,-1349,-1532,202,-2446,1598,-540,3814,-676,-566,-1695,-1734,-1065,-276,-2091,4,-576,2318,-78,-574,2325,-100,-656,2294,2286,774,-709,1850,-180,-252,-854,-1353,-1646,-902,-1427,-1646,-947,-1370,-1632,-1203,-1123,1646,-236,-2255,1822,1415,3431,-580,1360,3451,-656,1418,3332,-66,710,2299,-2636,583,2369,-2598,2223,1390,-1369,2224,1285,-1293,2195,1252,-1418,897,3258,-1898,925,3171,-1961,877,3171,-2018,-1941,-117,-347,-1903,-30,-442,1226,362,1872,519,1388,2227,1030,-2700,628,-2077,1306,-598,343,3576,-1599,217,1450,-2835,-1223,3514,-1094,-1163,3585,-1133,-1221,3441,-1198,1227,3278,-1557,1168,3387,-1542,-187,-402,-2347,-154,-458,-2313,694,-2528,968,1857,-657,-102,1809,-673,-138,1866,-699,-152,-1740,1719,643,-1742,1790,706,-1748,1799,649,-1306,3349,-1304,1271,3221,692,1198,1044,1877,-25,2777,2008,-1911,777,176,1326,3473,-725,1265,3480,-675,567,3364,1221,535,3414,1209,-1053,2435,-2481,-1151,2450,-2467,-53,-3173,1042,1418,29,-2031,1439,207,-2065,1415,212,1709,1008,3112,1190,-1996,510,-249,1679,2019,812,2137,2268,-1212,2107,2142,-1260,2110,458,-1306,2073,387,-1269,2107,397,-1366,-1545,1124,1536,-1570,764,1441,127,3427,-1899,2183,-3488,-766,2598,-3685,-691,1941,492,5,-1533,-1176,-1205,-2043,568,-347,1453,3377,-767,1532,3340,-752,-499,2470,-2642,-552,2482,-2607,195,-62,-2511,164,-97,-2570,165,13,-2560,-1617,-1186,-887,-427,-558,-2165,-568,-602,-2163,1914,1218,-2034,2148,-3550,-1096,2278,794,-650,231,-412,2626,1271,1971,-2578,1325,2088,-2544,1050,3240,1052,1063,3286,925,719,-2437,1106,1439,-1709,117,1493,-1703,-76,59,-584,-2240,113,-718,-2220,70,-756,-2170,-1724,1842,655,-1688,1889,735,-1994,488,-260,-2078,507,-381,-450,1228,2160,877,-1709,-1525,-605,-650,2027,-739,-698,1942,874,3530,184,-737,2916,1679,-1400,592,1616,-1522,754,1533,-1426,796,1666,1601,-1126,-1170,1608,-1064,-1173,-900,-2362,872,-1048,-2241,792,-1289,1038,1823,1285,-1951,795,1298,-1987,669,-357,540,1964,-352,600,1877,-534,445,1931,1057,-428,-2036,288,3036,1791,-1830,1129,-2116,-1856,1304,-2131,-2029,1134,-172,-2065,1212,-332,-595,-481,-2228,-258,-928,2208,1229,2803,-2211,-932,-738,1843,1643,-45,-1740,1662,140,-1772,1549,-1508,-295,-1582,-722,-1286,697,-1376,-1812,712,-1436,-1811,1419,1921,-2587,1623,-3003,-281,-1550,2897,-1774,-1539,2815,-1851,1195,-1061,-1604,1853,580,-1790,1904,474,-1684,1835,440,-1773,1569,590,-2128,1556,631,-2203,1663,678,-2118,-368,1806,-2803,-372,-1005,2038,433,-665,2140,271,-567,2219,1510,3042,-1649,1416,3193,-1543,972,3116,-2009,976,3186,-1931,-1144,-1504,-1517,-1077,-1551,-1547,84,3765,536,-288,-1401,-1906,236,3759,77,257,3728,251,319,3717,230,1568,2284,-2238,443,2087,-2698,-1539,-1575,-485,-1240,1486,-2657,-1266,1606,-2635,-1210,1539,-2700,-808,318,-2453,-2131,522,-435,786,2237,-2633,-346,3630,-1533,-2431,-3690,-1002,-2185,-3678,-1336,973,626,1889,923,3143,1289,827,3112,1370,1920,2952,-769,-1088,673,1764,-1622,623,-2173,-1583,457,-2141,-1595,451,-2064,-116,2832,-2480,-110,2704,-2526,-1895,203,-1527,-616,-1439,-1766,-638,-1521,-1738,-924,3457,-1552,-880,3575,-1436,-877,3470,-1641,2,-494,2731,-28,-515,2640,284,3786,-201,265,3813,-311,1902,285,-1597,1925,233,-1549,1896,219,-190,1884,268,-148,1276,-811,-1594,1260,-970,-1558,-710,851,1893,797,3241,-1936,806,3383,-1710,715,2566,-2480,-970,802,1753,-1007,795,1857,88,3163,1795,110,3033,1884,-1691,2752,-1635,-1767,2630,-1776,-1759,2720,-1611,892,184,-2411,-383,-1828,-1760,1973,423,-367,476,-97,2184,-1173,-1278,-1539,-1158,-1215,-1520,-1122,-1243,-1561,1160,-1166,1672,31,3730,-1395,-73,3661,-1502,-596,2388,-2638,-2062,1425,-612,-1263,-1988,820,2057,1765,-1570,282,851,-2813,-1578,2154,883,-1642,2069,817,-594,-1758,-1682,-419,-140,2190,-375,-155,2275,418,-660,-2100,432,-778,-2086,-1888,1015,469,-1872,1049,495,219,-2569,1444,216,-2681,1277,1311,3171,665,1856,-401,-1133,-1864,217,52,-1286,317,1838,833,-2428,887,-1620,-1118,-1067,-813,3485,-1560,-2591,-3931,-1177,-2365,-3794,-1297,1869,2625,-1698,-246,-2622,1347,-166,-2605,1429,-507,2929,-2367,1575,3148,-1044,-1724,-989,-766,977,3169,1173,957,3093,1216,870,3621,-341,-204,3294,-2058,-161,3114,-2251,496,3015,-2249,439,2983,-2313,651,3776,-906,695,3771,-953,-1292,-1180,-1479,-1284,-1239,-1429,36,-1845,2174,1953,927,-1778,1940,870,-1848,1924,980,-1837,1204,3435,-1369,1266,3332,-1476,-1335,-1396,-1290,-1441,-2275,-160,-1514,-2030,-544,1328,279,-2254,1335,516,-2354,1452,452,-2276,1712,3057,-711,1763,1576,735,-189,-423,2688,-261,-349,2671,-59,-1231,2172,55,-1229,2174,2740,-3806,-639,1693,-866,-1084,42,-2286,1848,74,-2395,1717,-1270,1836,1819,-1305,1654,1813,-1175,1709,1933,-1396,2398,1151,945,1770,2066,-2246,-3507,-576,-2164,-3470,-723,1550,-1398,401,987,2770,-2342,-1834,-511,-1163,-1782,-721,-1106,-2092,-93,-578,193,650,-2746,202,559,-2763,147,552,-2709,1945,471,-166,1896,260,-212,-1855,2259,241,984,-1298,-1693,-901,2475,-2534,-1015,2490,-2497,-1892,872,418,419,-737,2153,477,-729,2109,-1584,-1375,-780,955,3530,72,1256,1061,-2556,312,2417,-2631,-1304,-767,-1592,228,768,-2774,1611,863,-2256,1545,880,-2333,-1455,262,-2177,2070,473,-330,2112,560,-412,2030,477,-281,-940,657,1761,-1062,682,1718,-652,-902,-1917,164,-2886,-1916,-1,-2725,-1863,1576,2670,-2021,366,2598,-2545,1125,3581,-801,1111,3612,-752,1179,3547,-734,-1812,98,295,-282,-3308,920,2261,1810,-927,2216,1732,-858,-1761,-520,-1253,-1837,-510,-1214,-2010,1422,-222,-2010,1470,-375,1061,-1563,-1547,1008,-1523,-1544,17,3760,480,1770,-440,495,-808,-138,-2278,-801,-4,-2336,-2048,685,-1482,-1091,99,-2300,-2425,-3929,-222,-2714,-3929,-452,-2077,760,-1044,-1831,143,211,-2005,-116,-388,-2016,-154,-390,1350,1077,-2554,-759,-1667,-1566,-743,-1706,-1596,-2087,-63,-552,1834,1193,551,623,2984,1639,654,3089,1554,559,2984,1698,572,-1751,-1694,-635,911,-2763,-719,1093,-2772,574,3075,1567,506,3034,1660,-1588,1232,1357,-1612,1467,1121,-1640,1192,1104,240,-38,-2536,-1883,571,173,-1903,595,208,1204,2313,-2507,1779,-523,-158,1877,-465,-465,1516,479,1541,1578,512,1420,1415,529,1604,240,3699,504,-21,-1901,2183,-1042,210,1969,411,3690,138,442,3663,201,349,-941,1913,545,-932,1764,-636,639,1893,1935,62,-279,1949,116,-262,1932,47,-255,1051,-744,-1846,1205,-744,-1827,-613,-1945,1892,1932,844,254,1898,882,291,-571,-204,-2373,1359,-1602,-1240,-1675,-1083,396,-1206,-760,-1608,-1176,-761,-1668,-377,0,2264,-447,-59,2205,-340,-92,2277,2136,1223,-190,1154,-2293,462,932,-2577,676,429,728,1770,-1560,-1538,-721,417,3810,-518,-107,1601,-2789,-173,1582,-2855,-179,1649,-2786,-1843,495,419,-1840,477,383,373,1827,-2772,1963,2823,-488,1920,922,174,332,1778,2256,423,1878,2231,1785,565,-1885,-1926,483,-166,-727,-1624,-1662,-686,-1699,-1657,-746,-1663,-1634,912,-1337,-1663,1992,114,-1093,1981,-16,-1043,-2093,843,-1218,-2091,692,-1268,-2113,751,-1215,-1303,540,1682,-1304,486,1744,-300,-1368,2110,-281,-1251,2125,1747,156,650,1758,251,558,-1908,-149,-291,196,3074,-2264,531,582,-2697,751,2146,-2691,-712,-3496,725,-1832,1229,505,-1835,1270,546,-15,2592,2079,897,3510,386,836,3508,409,-1828,-69,170,-1830,-28,169,1219,3089,-1914,1295,2983,-2001,1885,928,350,-706,-2036,1773,-2047,-153,-452,151,378,-2719,-1804,-84,104,-1818,13,80,194,-1605,-1925,-1677,2641,304,-1633,2943,179,2293,1430,-1092,2057,427,-1140,2115,490,-1192,341,3659,507,-13,-542,-2314,3,-659,-2208,-29,-593,-2229,-99,1511,-2774,1190,3224,-1732,1222,3260,-1639,1235,3181,-1735,-267,-962,2176,-1892,808,453,-1865,794,412,-766,-258,-2223,2114,2170,-110,-783,411,-2598,650,-956,1735,-468,2516,-2599,1713,-1090,-883,-297,-3811,1098,768,-1854,1827,922,-1743,1737,-1100,-2234,578,-1115,-2245,519,1860,695,432,1889,784,406,-848,-1690,-1553,-1688,2852,-1565,-1606,2925,-1600,1902,-576,-359,1804,-652,-165,1790,-586,-161,-1481,921,-2391,1537,-1408,169,1847,-677,-781,2226,662,-544,2249,681,-602,1085,3606,-1073,60,2745,-2524,-1,2655,-2576,1967,-11,-1076,1937,-126,-1103,1940,-5,-1113,-1843,242,128,-1892,277,94,-1901,190,85,638,3746,-654,681,3726,-594,694,3774,-652,-384,-106,2230,-1995,855,-265,-2037,797,-137,1134,3284,815,188,-163,-2514,225,-100,-2490,225,-184,-2452,-589,568,-2678,-705,671,-2704,1897,-523,-757,-209,-313,2447,510,2980,-2299,2169,1221,-434,274,2050,2216,-1793,205,424,-1797,186,363,-1810,78,386,-2036,2228,-690,1658,584,-2113,-836,-1607,-1573,1762,-393,-126,1298,322,1823,1367,347,1756,-22,-511,2400,1352,2853,1039,1555,-1483,-449,1571,-1414,-289,2117,2340,-227,2272,1212,-775,2253,1268,-712,1684,-189,-1597,-905,2144,-2660,1468,108,-2003,-138,1839,-2780,2010,1328,-1625,-1100,-1297,-1538,-1078,-1316,-1589,1460,-1538,-1125,453,58,2199,378,-169,-2423,1841,382,-1712,1861,322,-1646,529,1293,-2835,639,1334,-2813,926,3462,536,557,1066,-2782,1123,3456,104,182,2657,1982,1199,2273,1701,1563,252,-2017,105,2829,-2469,59,2948,-2385,-79,-1300,2185,1091,389,1901,1479,-1571,260,1428,-1696,423,1467,-1636,220,-470,51,2186,-1479,-2758,-941,-1577,-2929,-827,-1543,-2764,-712,-260,-2239,-1811,1813,-828,-949,1752,-865,-977,1879,1460,286,1933,1523,297,681,1487,2157,-1756,1837,-2165,-1720,1892,-2189,-158,-904,2247,-167,-876,2269,779,3444,841,-1264,2130,1682,-1343,1940,1659,488,3610,-1452,856,3716,-835,-11,3868,-332,-3,3848,-181,43,3845,-220,1085,3535,-242,-1307,-1180,1438,-1356,-972,1431,-1359,-1262,1269,-1979,1972,-554,1320,-482,-1863,-1034,877,1929,225,-132,2704,110,-1151,2024,-1835,-216,-217,1400,-768,1434,1365,-629,1639,2068,80,-781,1986,443,-341,-742,-933,1795,-701,-969,1825,2286,1176,-1076,2325,1328,-1016,-528,1209,-2801,-571,1167,-2775,-613,1273,-2805,1435,3395,-1035,1355,3419,-1045,720,-1261,-1804,-334,1064,2137,-359,1294,2211,-423,1121,2123,-1634,2083,783,1993,1684,-1774,-1877,1133,365,2072,2668,-258,-1863,2550,-1717,-1861,2658,-1633,997,-1519,1717,936,-1589,1752,-712,-925,1716,-1286,3183,-1667,1505,2669,829,1521,2517,895,-613,1828,-2730,-910,-289,2082,1913,699,-1791,1890,785,-1826,2041,881,-1712,-32,-2269,1878,1952,280,-1496,1999,255,-1451,-83,-73,-2554,-47,-141,-2518,719,3020,-2217,799,3081,-2144,1408,517,-2333,1849,2109,-2111,-1004,3514,-25,-1036,3460,51,-936,3545,112,933,3590,-282,-610,-3722,-2142,-621,-2785,-1814,-2028,358,-1196,-2009,263,-1144,-844,555,1918,-810,611,1919,-935,573,1904,1934,344,-1558,2003,352,-1485,443,3771,-863,-1823,1453,-2123,-1880,1538,-2027,1146,-1435,-1503,-1761,2667,-116,-1757,2772,46,1844,-78,-230,1494,3115,-1572,-1696,1507,-2183,-1716,1568,-2245,1746,-1059,-862,682,1843,2152,-2099,1029,-1219,1433,-1154,-1288,-40,3898,-556,-830,3515,496,1850,602,297,1861,512,265,2303,957,-604,2368,925,-728,2280,931,-693,824,1294,-2723,1968,-362,-313,-1753,-867,-961,-1089,3463,145,-1100,3472,-53,-216,2345,-2638,-875,2010,-2670,-945,2041,-2684,140,3398,-1973,-311,-1265,-1946,283,3784,-18,1077,2987,1295,-492,-904,2088,2680,-3929,-420,2707,-3832,-514,-759,-1218,-1805,1691,2127,-2234,-530,-3395,860,2128,-416,-586,1012,1065,-2717,208,748,2005,1702,2222,-2177,-140,1351,-2765,-130,1215,-2789,1957,527,-169,563,3560,870,1367,2346,-2380,1432,2426,-2330,1455,2360,-2335,-1508,-1439,119,-739,-1585,1849,-463,2177,-2702,1963,-22,-1164,-1176,-2101,867,-1248,1134,1879,748,3746,-895,685,3775,-829,-479,3295,-2015,200,3875,-477,37,-98,2818,-936,-27,-2293,1790,1335,-2170,1038,3420,537,992,3440,642,1039,3383,680,75,3861,-335,79,3828,-185,-722,3595,182,-719,3606,13,-765,3611,-4,-1877,266,-218,-1834,144,-255,-1873,189,-268,-368,-1750,-1794,-332,2666,1944,-1936,231,-693,-1928,365,-660,1307,612,1660,1274,604,1639,-639,3761,-585,-700,3762,-499,-392,2731,1913,-298,2743,1910,-1110,3378,-1580,1597,3039,-6,-595,2816,1789,1433,-1469,-1219,1372,-1497,-1277,1432,-1435,-1227,-900,763,-2709,-1391,1809,-2567,-1334,1694,-2635,-1382,1686,-2598,2023,965,-249,1811,1550,550,1776,1589,608,1825,1539,620,1903,203,188,-1610,-1197,-958,-1863,-80,-351,175,-930,2238,182,-979,2199,-380,41,-2594,-323,10,-2546,1851,624,412,-1800,-136,-296,1113,3324,800,-1513,-1388,-1109,2357,-3629,-948,-743,1970,-2693,368,-349,-2299,320,-409,-2273,-1614,-1193,-1032,-1605,-1169,-1088,-1559,-1186,-1097,1504,-2600,-354,625,3584,-1532,594,-153,-2392,-364,3865,-918,-347,3862,-872,364,-1092,-1984,383,-103,2229,570,3541,-1577,582,-1979,1897,615,-1833,1908,500,941,1919,520,2326,-2651,1514,2334,-2342,1380,2447,1149,-658,1673,2165,476,2676,-2528,413,2647,-2512,-1771,-662,232,-1754,-794,257,2089,1682,-173,1658,3107,-763,1614,3109,-892,-1933,375,-619,-1863,99,-421,-1836,204,-289,-1874,191,-406,-1474,881,1666,-281,3904,-765,-931,408,1932,-1095,406,1889,-1751,635,750,-1732,423,737,-554,-1819,-1686,2210,2274,-938,1693,-965,-290,-626,985,1984,-497,990,1974,1765,1154,-2136,1059,-3069,-1707,906,-2795,-1680,-692,-864,1944,-628,-864,1997,-1287,417,1798,-1311,453,1752,-917,3623,-470,-865,3679,-599,-944,3703,-743,2184,672,-1393,2158,515,-1258,-150,-1640,2116,-2121,1576,-1133,1982,408,-1552,-1828,-156,-267,2009,604,-639,362,3758,-1226,396,3685,-1279,1843,46,173,-438,2874,1839,-1018,811,1902,1067,840,1889,-1791,1761,527,-1755,1804,549,-1804,1819,491,-2042,2172,-646,790,-777,1898,-813,-1450,-1663,-762,-1409,-1684,-786,-1517,-1642,491,3362,-1927,678,615,1907,826,609,1921,43,3827,-62,1952,699,6,-1775,2189,-2100,-1781,2086,-2092,276,3880,-593,707,2084,-2668,-403,-1334,-1920,-494,-1314,-1899,-437,-1283,-1953,1945,2,-477,-1824,-106,-259,-643,1142,-2809,-1962,544,8,-1789,1693,606,575,1413,2200,-136,-948,2015,-247,-947,1970,1016,-707,1828,1219,-1353,-1445,1260,-1444,-1422,-814,2413,-2585,-881,2383,-2561,1101,2389,-2470,254,-502,-2270,754,-919,1856,697,-942,1916,753,-942,1821,-432,1905,2222,409,-1055,-2008,448,-1124,-1965,537,-886,2074,938,3702,-888,-214,-610,2241,-121,-538,2317,-259,-559,2223,1083,3450,200,1151,3436,163,1607,1725,-2400,1701,1864,-2305,763,3153,-2058,1787,2187,520,-1535,-1390,-1056,-1529,-1343,-1058,-1503,-1394,-1079,1507,1367,-2485,1562,1560,-2403,220,397,-2734,241,328,-2688,1474,3263,-84,1725,-3123,-745,1806,-3312,-1076,2014,2102,-1572,1999,1927,-1679,2013,2038,-1694,-2058,2002,-1550,-1656,193,1255,-1682,484,1159,-1706,255,1076,1697,1610,861,1723,1452,807,2006,418,-266,2038,1656,-1669,19,-529,-2306,725,-843,1919,743,-791,1911,700,-822,1950,1911,-689,-247,356,883,1906,633,2837,1759,593,2887,1745,-1855,1312,-2007,705,-732,1941,-1686,-893,-1066,-625,952,1920,-723,962,1964,-2043,1944,-1391,-730,-223,-2303,671,116,-2458,583,100,-2532,-1816,2724,-1534,1453,3336,-987,1946,2742,-1301,-133,2558,-2618,-198,2773,-2510,246,3092,-2279,-934,-1237,-1710,-864,-1296,-1675,1810,2615,-1760,1766,2697,-1684,540,3753,-875,500,3800,-812,-816,1578,-2768,2040,443,-401,-755,1678,-2779,1815,1379,526,1931,624,-1747,-1920,1413,-1993,-1900,1324,-1959,1958,-62,-734,2051,1606,-1741,2014,1782,-1712,-1503,184,-2021,1663,2697,-1773,2162,1006,-1460,2214,866,-1386,859,3713,-918,113,-1296,-1989,558,3177,-2069,514,3242,-2082,1638,470,-2017,1488,3358,-581,-1990,470,-274,-536,784,1759,2102,479,-380,-1630,-2964,-645,869,2552,-2483,886,2527,-2531,826,2473,-2516,-2100,1510,-1032,619,3591,159,1088,1554,-2711,-1760,1868,582,-1764,1872,491,-1877,1066,390,1574,3111,-270,-1891,728,398,-1913,355,-341,-1921,347,-309,-1945,424,-296,1180,1822,-2653,1745,-855,-640,1285,716,1742,1276,666,1718,-1851,247,206,-2068,1649,-591,-1312,1351,1887,-1354,1395,1829,-300,-987,2126,1318,1349,1881,663,3403,1046,717,3332,1122,1179,1180,-2655,1127,1082,-2690,1774,1523,673,-1764,2554,-11,1572,-1470,-660,-1530,2265,-2363,1979,1146,-1855,1786,1641,603,2187,1165,-1481,2152,1336,-1487,-1009,-2853,619,1946,-679,-169,-1302,1208,1915,-1728,-892,-1018,-1708,-955,-1039,644,3073,-2212,-497,3711,291,-192,-676,2263,209,-1193,2116,877,733,-2618,291,-1815,-1801,354,-1808,-1817,217,-318,-2403,2107,653,-360,2238,1962,-524,-1795,2144,373,1757,-1006,-894,-1952,4,-1265,1048,3639,-677,454,3824,-993,496,3754,-1028,152,3253,1660,1797,-104,-288,1802,-138,-295,-1299,-1974,704,-1382,-1854,498,-1536,137,-1911,601,948,1910,1894,1581,-2019,1979,1477,-1956,-1352,1832,1708,114,3490,-1856,-835,-716,1902,-273,213,-2658,-2002,471,-260,-1848,252,-222,-441,1356,2228,-486,1313,2209,1011,2340,-2538,2026,264,-1355,1733,353,757,1738,462,818,1193,-125,-2055,1255,-177,-2014,2054,1906,-1635,1890,881,411,-1265,-2016,383,-1893,272,-374,-1975,2089,-183,2298,394,-957,143,1313,-2822,247,3743,-1329,-807,3568,-18,-1649,-1127,-916,-1668,-1078,-893,81,-235,-2491,1580,-523,-1409,1554,-458,-1488,-1542,3301,-705,-1556,3249,-843,957,2320,-2556,2068,435,-1427,-39,-68,-2591,-2072,949,-1561,-2059,838,-1646,-47,2603,-2573,1965,460,-201,2012,536,-178,1478,-3812,-1965,1128,-3762,-2011,-884,252,1981,-1940,2684,-1422,837,3727,-999,2006,1090,-92,2012,1015,-33,1869,2791,-1438,1788,2857,-1385,-499,-1056,-2006,-424,-1080,-1996,2248,1300,-572,302,-3751,1086,141,-3667,1096,192,-3926,1146,-14,-162,-2549,-1109,2159,-2605,-1194,2129,-2591,-106,3754,-1307,-161,3790,-1253,-1736,1894,687,760,997,-2759,1719,-902,-1015,2186,-204,-742,-1779,-771,-939,772,3593,126,870,3550,73,186,-1527,-1890,51,2282,2204,-621,2337,-2636,-558,2306,-2678,-186,3905,-815,-132,3888,-854,1120,3414,243,1311,-870,1593,1150,-638,1829,-877,-1552,-1542,-1202,3448,-105,1997,619,-511,525,2524,-2584,1042,438,1917,997,388,1922,-1686,-1086,-935,1844,-323,-1190,1004,3546,-1405,1090,3550,-1281,-575,-1086,-1926,-599,-1062,-1889,2030,512,-1479,-76,-1013,2192,-1663,1912,817,1265,-1594,-1342,-710,-1261,1819,-1165,-132,1959,-1218,-365,1894,2267,1426,-745,1325,3420,-1144,1035,3473,107,-199,2163,-2712,-149,2109,-2696,-1328,-3199,-1631,-765,-777,-1947,1327,3404,-1234,2247,511,-688,2267,547,-716,-1218,1646,-2656,-1027,-1206,-1672,-1026,-1260,-1616,-884,2240,1989,-596,2399,2037,-33,-670,2306,-64,-749,2315,-1935,430,-370,-1916,355,-382,-1500,3304,-573,-1566,3243,-580,-421,-972,1896,-414,-937,1870,-131,2771,2015,2032,2754,-336,2143,2663,-627,2108,2755,-637,688,3084,1501,925,3028,1397,-195,3825,-1114,-2035,1867,-485,1421,-2656,-139,1366,3244,326,-1790,1961,428,1955,1297,187,-1161,3471,-1368,-1239,3392,-1359,162,-1283,-2010,-1546,-1305,-1126,1143,-537,-1914,-616,3476,-1700,-650,3364,-1794,-1816,1402,524,-1840,1382,472,1862,947,388,-2018,899,-176,-1996,921,-136,-2028,981,-315,-1969,469,-354,-1076,2767,1479,-1023,2779,1503,-169,-404,2349,-173,-340,2357,2139,1973,-1277,400,3547,991,-1338,1575,-2667,-1353,1557,-2595,2313,1429,-902,1123,3200,-1756,1176,3155,-1826,-2118,1104,-1304,1496,2632,-2127,377,-368,2310,436,-383,2143,806,134,-2442,-795,1243,-2792,-903,1336,-2750,-689,-2092,1660,-664,-2208,1571,-1839,1683,403,1635,3095,-1142,-840,2111,-2651,-801,2025,-2685,1867,649,378,-1678,-882,-1200,-2011,469,-393,-2090,476,-428,635,-1060,-1933,-863,2069,-2692,-1379,-401,-1679,715,3546,494,681,3551,442,-1176,3354,347,-1941,2724,-1233,-890,3711,-793,-750,-2686,-1724,-797,-1982,1734,-2016,438,-463,-1798,1753,611,2133,-3649,-188,-940,2741,1603,-460,3415,-1826,1566,-705,-1329,726,3698,-534,1592,3104,-593,1692,3032,-434,-92,2493,-2613,-1941,2012,35,-1861,2116,88,-1959,2091,-57,602,2798,-2439,621,2726,-2431,549,2703,-2476,1941,579,15,-1114,-2206,637,2089,530,-1366,-1496,-2261,-811,-1511,-2252,-611,-1539,-1789,-776,2003,2101,-1788,-355,2783,1904,2165,-221,-814,1651,-1227,-990,2107,1267,-160,-958,-1287,-1649,-1761,2509,-1844,-1519,-1412,794,-1933,447,-574,775,838,1799,889,-101,-2272,2148,-3459,-498,1840,680,-1867,503,-3904,-2196,629,-3723,-2136,2164,-315,-732,-88,2345,-2680,831,3516,488,704,3534,597,1165,39,-2196,-1481,2676,-2077,-2127,399,-816,-1977,329,-713,19,-3845,1143,2049,248,-576,-2153,1256,-906,-1930,493,-513,-1924,503,-531,-1969,612,-89,-1979,631,-39,1480,2872,587,644,1786,2181,-1936,486,-514,-1323,1382,-2624,1103,3387,540,1062,-2004,1360,-765,-940,1820,2110,1340,-226,-44,2095,-2720,1923,-329,-1081,936,1847,2047,-1835,186,-1632,-1744,39,-1720,263,3671,762,550,1137,-2826,-1886,1666,266,1761,-882,-711,691,-1143,-1900,0,2060,-2751,-5,2117,-2699,59,2102,-2741,-1838,-13,279,-1874,30,269,-1854,30,203,64,794,-2746,110,859,-2816,92,717,-2766,-1767,-353,559,503,3430,-1789,552,3397,-1815,-1446,3360,-1215,-1513,1951,-2500,-1432,1954,-2565,-903,1154,-2708,-950,1280,-2750,-861,1207,-2745,870,-2152,1415,-1537,2181,-2429,-1278,2423,-2431,1898,-364,-1034,1914,-157,-1054,1930,-312,-980,265,-153,-2478,-1076,3476,-1489,1704,-3618,-1761,180,2906,-2415,112,2963,-2388,790,-1207,-1850,-1601,-1238,-1039,-1588,-1252,-965,-1025,-2640,-1548,-294,-1591,-1851,931,-1465,1759,543,-1507,-1799,504,-1563,-1807,-1421,1370,1744,-1459,1631,1564,-1511,1262,1600,-942,-557,-1992,1196,-603,-1874,1265,-636,-1812,-2036,559,-1274,-2080,672,-1398,926,-1530,-1596,-1651,-1055,-1075,-1642,-996,-1111,-2058,1269,-248,270,3792,-1232,309,3760,-1179,71,-698,2306,1547,-3163,-1333,-1884,-395,-474,-860,479,-2606,-2054,732,-223,2058,1967,-1548,1383,3100,721,1452,3162,413,-1315,-1105,-1463,-1357,-1025,-1507,883,3457,713,-1486,2759,-1920,-1775,-356,-125,-695,3339,-1823,602,-966,-1981,577,-795,-2015,672,-939,-1943,1853,2150,458,-778,301,-2523,167,-2617,-1852,113,-857,2286,12,-817,2309,-637,-1287,1864,-645,3801,-857,185,488,-2693,-10,-1031,2122,616,-106,2144,522,3526,-1659,2082,412,-943,-1655,2078,-2341,1208,3225,691,75,1121,2293,545,3769,-553,531,3731,-412,-464,-1196,-1957,-1816,2935,-710,150,-460,2360,-1666,-970,-1088,-1955,541,-163,298,1837,-2784,-1515,2693,753,129,-769,2300,-1154,1949,-2657,-1073,2073,-2642,-1713,-956,-96,97,3923,-837,-1991,548,-179,-441,1066,-2802,-1415,-1492,1032,1683,-1175,-958,-1331,-1492,-1308,975,3466,565,511,2381,-2642,490,2426,-2620,-257,2786,1925,1835,1448,544,1804,1479,587,-1963,-210,-663,-1923,-256,-640,1098,3352,650,1248,628,1691,1755,2885,-5,1990,-489,-571,-1824,2060,292,404,-1543,-1853,296,715,1831,-477,3827,-624,-467,3843,-528,906,1028,-2696,1748,357,616,1778,424,529,864,3592,-199,-1470,-369,-1716,698,2748,-2416,670,2804,-2370,1488,1100,1697,-1099,692,1742,807,-1658,-1604,-2003,-201,-699,-1341,-1421,1224,-1198,-1621,1371,-1028,2014,-2678,-2021,-10,-741,-1943,92,-721,-1943,-52,-723,-1614,-1122,-1130,-311,671,1837,1971,-3605,-1481,-274,-1296,-1968,-1582,451,1427,-1537,391,1522,1249,-861,1682,1232,-602,1798,1756,783,-2097,-1964,1978,-221,-1967,1981,-386,1713,-791,-265,1032,3465,234,1944,361,-357,-910,3567,-96,1731,1882,-2217,1120,2267,-2521,-1981,372,-770,-1957,496,-640,-631,-584,-2132,-698,-655,-2010,178,2524,-2610,137,2536,-2605,341,665,1812,-135,3857,-1121,2013,700,-323,1977,631,-252,1978,615,-418,2003,2550,22,692,-121,-2322,-334,2810,1872,-16,1813,2289,-209,1873,2265,364,1736,-2818,1418,3018,-1826,295,-137,2411,-2107,831,-1327,-277,508,2114,-2069,613,-1325,1164,-799,1756,1806,2796,83,1994,373,-681,-1932,500,-501,1436,1429,-2491,1528,1495,-2491,-600,819,1787,265,-390,2480,350,-363,2369,2166,2530,-965,-2029,1922,-1519,-2006,1813,-1668,-2037,1789,-1529,-1579,2994,189,-211,-1643,-1882,-270,-1608,-1894,311,-313,2587,1957,406,-576,-377,-407,2192,-1195,2040,-2619,1480,3294,-1096,-354,2223,-2722,1899,-440,-894,-1858,426,201,2020,-542,-550,-1979,1922,-1681,-362,3411,-1848,2245,549,-554,656,3567,617,-353,2075,2195,-606,-47,2141,511,3623,338,-557,582,-2754,-899,518,1924,651,-964,1928,811,413,1917,2079,333,-1143,-1766,2798,-1403,-534,1374,2203,1413,-801,-1435,654,-3671,846,730,-3613,767,-1628,-101,-1732,847,2391,-2601,-1341,-3102,126,-822,-1721,-1541,-1258,2087,-2552,-2084,1283,-161,1351,-706,-1619,-2240,-3871,-83,115,-1194,2132,-1172,-117,-2141,-1110,-202,-2093,-604,3569,-1463,1224,-3042,-1586,-283,-503,-2282,-333,-466,-2295,1759,-630,-79,1779,-620,-310,1810,-536,-310,-1283,-1520,-1332,-1450,-1427,-1227,-470,818,1825,66,-1190,1986,381,3072,1729,2162,1793,-1172,2182,1703,-1250,-1741,-565,678,-1026,-2880,-1636,1589,3083,-229,-22,-1831,-1877,1846,332,332,1852,290,303,1738,-1021,-808,-227,583,2132,-1596,-1310,-940,-1598,-1327,-888,163,-446,2489,-1932,413,-23,1919,363,-210,1469,453,-2154,1694,533,1133,2247,1025,-1088,2266,938,-1032,1196,3592,-803,1175,3554,-858,1833,-706,-737,-1835,1890,-2066,-417,-3105,849,-1699,-992,-645,1007,573,1876,113,3821,30,-2282,710,-739,-297,-3579,1033,973,-1653,-1497,-1418,984,1743,-1132,-358,-1963,-1179,-417,-1909,-242,-298,-2399,1935,-244,-647,-162,-2369,1717,-76,-2302,1820,-289,165,2323,-318,-50,2328,-1876,61,-1516,1770,2943,-105,1245,1340,1986,1208,1294,1980,1321,1278,1918,-1952,2637,-1371,682,3528,686,-1139,3595,-810,-1182,-3446,-1858,-1096,-429,-1899,-480,-132,2173,-441,-177,2161,1434,3388,-481,-76,-459,-2312,28,3845,51,90,3800,118,1969,-61,-719,-1177,-1317,-1494,-1127,-1430,-1488,-1205,-1402,-1518,-609,1043,2016,1632,-343,-1539,-126,-1191,2119,-205,-1154,2063,-282,-1160,2065,-1630,-1175,-185,1792,-785,-637,1494,-1784,-77,1842,-594,-643,0,-1782,-1893,1655,1509,974,1265,2073,-2556,1143,3482,-127,1214,3482,-138,-1758,-910,-958,907,-546,1983,781,-753,-1956,949,3030,-2093,898,3038,-2158,902,3073,-2047,401,3791,-924,1520,-1475,49,1527,-1379,71,1754,3060,-902,1049,-335,-2093,1890,1017,-2022,1862,1088,-2082,-1505,-1348,-1147,-2657,-3725,-750,-648,2813,1780,-417,-3887,-2202,-1012,-893,-1687,-980,-848,-1759,-393,-3408,933,-285,-375,-2368,986,2812,1517,766,545,1920,-1861,347,210,-679,582,1903,-302,1853,-2785,1347,-272,-1912,1699,-1001,-75,-1367,-970,-1475,-1434,-933,-1411,1384,3366,-1273,-1457,-646,-1516,332,3661,603,-1276,2500,1323,-562,3217,-2054,-425,2867,-2391,498,430,-2671,2155,1481,-1402,319,-1856,-1790,1725,1967,678,1789,2017,568,988,3392,706,-809,-2027,1641,763,-1659,-1656,1899,2168,-1992,559,-1737,1950,-1857,-16,201,1142,3589,-676,-1867,-601,-850,-1895,-602,-908,-1104,-789,-1665,-1363,1820,-2621,1427,-788,-1534,1340,2802,1097,704,2971,1646,-1841,1168,476,-1521,-1558,-199,-1517,-2581,-656,220,3244,1627,-864,-1494,-1607,-841,-1552,-1616,0,3531,-1754,-17,3439,-1843,-43,3526,-1705,1188,650,1727,1234,633,1703,1049,-541,-1931,-1892,2473,-1771,1897,1800,317,-146,-3196,999,465,-2913,903,-2057,1536,-1388,-660,-2838,792,-910,-2582,691,-66,3329,-2051,-90,3223,-2120,2124,1575,-136,2268,1312,-854,3,-257,-2501,1825,11,335,2168,1497,-280,2182,1413,-270,-2223,644,-563,-863,1493,2113,-1328,2140,1561,-1369,2188,1427,1597,-1272,-1027,-1085,1607,-2666,-1430,-699,-1555,-1734,-3374,-1383,1698,1880,703,784,2574,-2507,788,2655,-2444,898,-776,1860,108,-1631,-1910,-1609,2042,833,-989,2795,-2312,-1112,-676,-1764,-692,2778,1749,-803,2808,1664,357,2728,1903,-153,1457,-2807,-870,-1069,1809,-1630,-1230,-928,-57,-945,2263,-207,-1837,-1828,-284,-1932,-1806,337,3678,-1346,2266,916,-1154,2282,942,-1240,234,1632,-2826,-1206,3515,-915,-1258,3481,-949,-1286,3515,-880,-488,3736,-22,1985,706,-195,2014,761,-228,-427,-367,2219,-1257,-1282,-1482,1900,266,72,-26,3549,1121,524,-785,-2074,520,-866,-2012,-404,3825,-900,-1707,1953,679,1230,3030,1051,-2043,2424,-1063,-1237,712,-2525,-1738,-975,-853,1465,311,-2074,1365,303,-2198,1834,-156,-262,-2246,632,-660,-820,863,-2747,-1905,1378,329,49,3755,683,-2265,727,-678,374,-2088,2034,-1917,520,134,-944,-1163,-1642,1961,447,-533,1962,546,-410,-922,-3147,-1815,-1136,-3119,-1692,-12,-1189,2000,1943,187,-257,1930,194,-274,2258,892,-716,452,-3617,985,554,-3697,931,1890,342,258,-1611,-1081,-1087,471,499,-2724,-1652,540,-2032,1441,589,1582,303,-3702,-2176,90,-3855,-2190,-22,-3851,-2187,688,-893,1940,675,-878,1962,691,1267,-2801,714,1185,-2771,1937,284,115,1950,371,133,-314,456,2105,909,318,1961,888,354,1936,739,357,1941,-1015,3446,-1517,993,3221,1092,243,3880,-820,-2022,829,-397,-1135,3617,-945,141,-50,-2583,-1411,-97,-1938,-1369,-205,-1886,-53,1439,-2844,-1597,1946,-2431,-137,3306,-2054,-838,868,1932,-955,1335,2099,2130,-241,-643,-610,-883,2007,522,2744,1843,1919,-11,-1200,-175,2684,1998,606,-1715,-1716,1847,1717,358,783,1470,-2724,-1523,-1395,-1029,173,1631,-2788,-1288,-90,-1976,502,724,1736,1592,3116,-1207,-2064,2496,-1184,-2056,2522,-946,1739,887,-2122,1672,784,-2136,2095,1468,-75,-1138,716,1821,1409,-1408,-1320,1383,-1472,-1336,-283,2360,-2654,-1842,-3255,-336,904,2209,1988,-718,1185,-2788,163,3274,1551,1395,1546,-2584,-852,-1748,-1533,2163,508,-441,1760,-692,-163,1200,2002,-2616,-2010,2124,-350,-1726,-3449,-1530,599,1620,2196,-857,3066,-2148,1683,-1071,-930,263,-235,2688,1722,1928,728,1545,-2883,-881,-831,-3189,636,1253,-1540,-1399,554,-709,-2068,-848,-594,1944,-1073,-3011,414,1677,-480,-1341,-173,-3686,1097,1601,519,-2069,-1782,1932,511,-1735,1985,576,-1786,493,-1974,-244,-1647,-1893,772,3452,894,1898,1775,362,1618,2528,-2050,52,2035,-2739,1862,2736,4,-1312,2300,1472,-1726,2880,-1461,-1776,-789,-39,-1384,3202,-1577,-1279,558,1656,-2378,923,-732,1774,-195,575,-1259,-2710,222,-1255,3416,-194,1969,8,-1001,1394,3040,720,-783,981,1989,1532,3317,-502,-844,648,1783,588,2040,-2730,-1497,3370,-984,-1131,1559,-2658,-1493,-44,-1896,802,-1103,-1905,-1923,-356,-714,1281,52,-2071,1541,2114,-2399,-386,2816,1894,-1850,112,-1556,-1203,-1214,-1488,534,143,-2546,1224,3510,-498,-2343,907,-779,-1093,3582,-1235,1416,3366,-391,-1073,-1224,1715,-201,-1706,-1888,1937,270,-423,-1611,2147,-2360,-242,1700,-2797,714,3578,137,714,3580,247,258,-302,2406,-489,-1031,1838,1444,-1982,33,335,633,1848,1532,3326,-939,1464,1030,1736,-1957,2780,-845,495,3793,-915,-1845,50,230,-702,1395,-2742,-666,1233,-2771,-2254,905,-692,2257,-3654,-1193,2397,-3789,-1255,72,1558,-2845,-43,820,2306,-13,978,2288,1615,728,1335,-1527,2096,-2416,-822,1938,-2698,-1010,-794,-1782,-1092,-895,-1685,-158,-125,-2540,1100,2331,-2544,-1105,-1591,-1504,-376,3528,-1726,-2073,199,-794,-1202,-2108,693,2261,1536,-865,-771,-488,-2065,980,3059,-2069,-1312,3052,-1876,-34,3667,809,-1705,-3590,139,-1815,-3744,249,-1911,712,278,-1872,667,227,-1896,623,290,-1608,2779,-1743,994,-3928,802,141,-1429,2149,1755,2108,549,-1275,-2247,350,1778,1410,654,1551,822,1504,653,2759,1780,270,3866,-973,-1282,-2018,601,-1973,214,-1301,1757,-896,-882,-1962,2222,-1628,-1968,2093,-1768,-2005,2186,-1574,-1002,-1581,-1536,959,2167,-2618,136,1433,-2824,812,2688,1740,-716,2051,-2686,-367,3737,366,-416,3703,491,-270,-708,2223,-315,-690,2205,1400,3347,-302,1474,3345,-341,1073,2735,-2340,-794,3074,-2120,-136,-1079,-2072,298,-1912,2124,-636,-957,1730,1999,1402,-1719,-892,-1681,-1517,-655,-1804,-1632,-79,3483,-1832,-111,3507,-1797,1574,45,-1760,1846,-589,-783,-1432,-1882,95,-2137,-3466,-460,-1291,1450,-2650,-1405,1542,-2566,536,3294,-1934,92,1291,-2858,-1825,-624,-938,-1822,-725,-920,-2084,1109,-1476,1854,914,553,1850,838,529,1894,421,241,2249,1106,-697,266,-346,-2350,1412,1452,-2545,-896,-3,2061,-985,-129,2055,-858,-150,2101,-467,-165,-2424,533,2767,-2434,50,-1161,2088,2121,1755,-1314,2098,-3932,-1712,2416,-3931,-1394,2269,-3930,-1554,-1064,-1619,-1477,-950,-1550,-1575,-781,-836,-1919,-730,-877,-1970,-1670,892,1052,-118,-1828,-1876,1081,3201,1027,-1768,1051,750,-1818,908,610,-1758,842,782,-1667,1185,-2247,1821,1030,552,-1931,2316,-1806,-1925,2282,-1719,-1887,2411,-1676,-1056,3621,-1093,1868,-3462,-1356,1197,-1597,-1404,-1916,2517,-1662,833,3122,-2081,294,3717,449,-1026,2338,1846,-1070,2129,1903,1444,1670,-2517,-522,367,-2613,613,-729,2017,-1210,3489,-804,2036,1311,-1698,-1097,-1859,-1420,1171,3256,-1679,1592,3174,-681,336,3347,-1979,100,-2512,1567,413,-140,2204,-324,3724,473,-372,3668,714,-317,3724,579,1089,2176,-2559,-1880,1018,374,1007,2187,-2559,61,2959,1901,-2035,774,-1584,-2024,810,-1506,440,-1299,2038,-264,3696,736,-1777,-348,271,-1790,-117,-291,2226,1410,-597,-346,2897,1875,275,2657,-2554,-2044,2481,-1315,-1985,2400,-1435,-378,-2631,1194,-1822,142,-262,1094,2124,-2600,-1522,2674,612,-1855,-7,308,-1832,49,331,-1840,-3793,-1817,2142,-3778,-1537,1463,172,1622,1904,384,-1683,322,-2792,-1887,583,-786,2049,687,-773,1964,170,-1621,-1882,225,2508,-2632,-75,455,2529,-1629,502,1303,2079,-483,-617,2603,-3718,-824,-1573,2867,-1703,-1821,-3,-343,-1868,7,-428,872,3489,489,-319,-109,2317,-632,-218,-2304,-611,-321,-2301,-736,3743,-734,-750,3739,-857,40,-431,-2401,65,-506,-2318,-1128,1842,-2676,1912,2823,-286,-537,3697,188,2019,1001,-1743,1801,-636,-821,169,-238,-2448,-47,-1724,2148,-1594,1348,-2335,962,2855,1503,931,2904,1543,302,642,-2784,1312,-658,-1661,1453,3321,-1165,-135,630,2311,1025,-1038,-1774,261,-1889,-1802,1740,-827,-571,1724,-410,-1384,611,1364,2185,2074,2647,-1166,-1556,2380,-2292,-1690,-1034,-885,789,3554,376,202,-333,2336,1597,-634,1066,-1200,-1448,-1454,1839,-643,-665,371,-1520,2051,188,-1588,2101,1755,11,682,-1078,908,-2670,-1930,282,-453,1249,641,1697,-771,-1589,-1578,2301,1648,-765,-1913,130,-484,1099,471,1891,-601,3791,-507,2078,1224,-1636,-891,-2157,-1539,1882,839,466,-653,2300,-2657,-787,2351,-2621,293,3563,-1584,-1470,1759,1445,-406,-817,-2133,-85,3729,-1411,-42,3730,-1364,343,3141,1697,-27,3195,1723,1646,3011,-244,-1983,194,-557,-2134,-3931,-1682,-2269,-3931,-1553,-221,-452,2280,-123,-509,2332,-1568,-2806,-558,-1989,297,-535,1428,1442,1703,-1825,1794,-2105,-100,2915,-2375,943,214,1983,53,1365,-2857,489,3760,-580,-1991,381,-491,-1359,-1180,-1439,2188,2129,-367,1709,1856,800,-1092,882,1912,-966,958,1978,1848,144,-251,-1333,2838,1109,336,-1129,2031,-466,-270,2142,1558,-1594,-667,-1788,752,660,203,-731,2248,939,3457,630,-1562,1673,-2442,1866,793,-1944,1243,3263,635,1665,-3225,-1201,850,3303,-1899,-1986,89,-567,1702,-954,-1041,112,891,2256,-658,2443,-2619,1544,2549,-2041,1520,-1679,-275,41,2209,-2680,-48,2278,-2684,-2468,-3931,-1334,618,3372,1188,308,2752,-2489,-476,-633,2107,598,-827,2025,-2061,652,-1215,1310,3464,-1085,-776,1409,2159,480,2492,-2621,490,2540,-2609,1851,-329,-1248,-1888,70,-455,-2027,942,-67,1443,3091,447,-674,-709,-2060,1242,1109,-2626,251,2771,1899,2124,-343,-754,2075,-389,-732,1114,3593,-913,-806,3745,-739,-801,3754,-590,-910,2147,2000,1171,1915,-2625,-768,1064,2007,1510,-2791,-261,306,3653,-1441,1488,3150,269,1675,2390,723,126,2722,-2528,-1460,-263,-1702,-232,3412,-1828,-995,887,1928,42,-1670,-1942,1561,469,-2101,-1224,617,1716,1946,-318,-851,1954,-407,-816,-1029,445,1925,-355,3717,144,1558,3266,-575,-240,818,1971,1869,247,-223,-1752,-779,-615,571,-2050,1872,1805,-717,-609,1441,-3929,472,468,-294,2142,1776,677,-1972,2100,-265,-823,-1881,2866,-668,1871,1128,478,512,-1047,1771,795,9,-2401,711,66,-2399,1294,614,-2398,-777,-3924,-2131,-544,-3899,-2188,-472,2671,-2504,-1029,3444,414,-1093,3377,440,-669,3670,24,1321,2382,-2418,1588,2886,374,1335,2640,-2238,-1333,-2160,253,-1315,682,-2425,-169,-1934,-1832,1545,3114,-1400,102,-3565,1054,-1686,1829,-2327,1346,-1109,-1429,1296,-1083,-1441,1015,2671,-2430,-183,-55,-2586,1099,-1081,1726,-704,-1642,-1719,-1355,1150,-2562,-1238,-829,1700,1590,416,-2065,-265,-315,2346,254,-319,2338,-525,-240,2110,1532,-2770,-782,2816,-3929,-655,2743,-3817,-764,-1823,-138,-196,-1365,362,1754,-1409,563,1618,-1843,-51,-254,-1838,-57,-216,1983,-668,-246,-930,1645,2074,-904,1721,2090,-2039,1305,-91,-255,-415,-2368,-862,156,2021,-1292,3526,-767,-1039,2827,1459,-170,3695,621,-1024,-988,1761,-397,-1924,2068,-309,-1863,2112,-1434,-1303,-1256,-972,3505,-1467,-1586,2786,448,447,3373,-1820,-1573,-1239,-1109,-221,-991,-2056,2171,1600,-1295,-2001,-662,-143,-1945,-562,-128,-1876,-654,-97,-1890,-591,-89,-209,-1007,2113,975,-634,-1998,946,-744,-1916,-744,3744,-543,-557,1356,-2805,1091,3632,-960,-1228,1577,1897,-1831,-569,-100,421,-44,2225,1164,-931,1719,1301,3280,-1490,1312,3273,-1569,-1883,-705,-138,-1955,-706,-142,-1739,2621,132,2113,408,-1196,194,1591,2299,-1006,2858,1491,-1565,3186,-187,-682,1964,-2746,236,2727,1927,-70,1415,2327,1382,-2419,-1148,-1837,-664,-130,503,-1440,1978,639,445,1898,2239,1187,-1356,2209,1050,-1397,-1446,3149,329,-1476,3198,123,-551,3820,-996,-42,2627,2077,-325,-2161,1995,-371,-2187,1898,-1649,-3781,-1903,-353,-3927,1088,-1574,1765,-2407,979,898,1935,-810,3374,-1836,-1122,1814,1940,1162,1688,-2648,225,3753,283,-301,359,2211,-287,301,2278,376,2117,-2711,313,2176,-2736,-1885,1797,-1986,-791,3288,-1950,-668,-3411,746,623,-735,-2054,-1570,-1066,-1209,-1539,-243,-1714,1369,2806,1037,692,3627,85,-696,1799,-2744,-687,281,1988,-1919,168,-284,-1928,160,-264,-1916,213,-268,-1916,68,-278,1300,558,1651,-950,2886,1531,437,-995,-1985,-1914,59,-254,-1877,2368,-1840,-1886,337,-199,-1884,260,-197,1028,1369,2102,-215,-3927,1142,1085,0,-2258,-1616,-1299,-809,-671,835,1800,0,1186,2309,1983,2748,-178,-1585,-805,-1273,1724,1013,895,885,2887,1609,-1506,-1415,-1121,2310,922,-448,1676,-995,-189,-755,-2455,985,-699,656,1793,-1720,2440,-1966,-1898,98,-226,-2026,1090,-70,-1998,1001,18,-12,-2413,1711,1575,-1321,-102,1416,-909,1306,1621,2999,-55,-759,649,1793,821,-3509,652,411,426,-2692,-1470,1548,-2538,-1709,2000,655,-1733,1928,624,2202,1927,-1103,1377,-1811,623,373,-518,-2219,-548,-1020,1753,935,3496,459,2004,910,54,359,3730,146,-73,2759,1999,-10,3016,1876,-27,2956,1922,1363,1011,1776,-1655,3121,-1048,946,3242,1092,-1041,-1460,-1517,-1089,-1500,-1514,-1102,-1431,-1538,1838,133,-261,-1980,802,-39,-1818,-105,242,2071,495,-235,1982,1246,-1733,1767,-809,-881,1962,570,-287,-1657,1187,-2321,545,3708,-143,-208,-1191,1941,1538,-3929,-1988,1503,2257,-2328,1398,471,1632,1483,-2363,-341,1984,681,-71,-378,2799,-2488,-1426,3244,103,-160,2606,2024,-159,458,2432,-108,575,2418,1228,-2112,367,1801,-3930,-1914,155,3099,-2276,1419,563,1622,-1259,2157,-2574,-1670,2798,-1715,-1608,292,1387,924,3171,1157,33,-773,2320,336,-3589,1028,1933,2924,-902,-1052,2562,-2431,1752,-864,359,1555,107,-1821,-1872,2193,-1899,-1426,1630,-2586,1935,-60,-1249,2769,-3929,-525,50,3061,1840,-1903,784,345,-1873,114,-283,-652,-785,-2002,509,2922,1744,379,3710,-5,659,292,-2576,-548,3758,-418,-1615,22,-1798,-329,-818,-2146,-823,1766,-2738,178,-1103,-2053,-851,450,1939,-1196,1770,-2660,328,-612,-2145,-1896,2151,-2010,1049,676,1724,1134,3594,-1007,-73,-1186,2128,1448,-1379,-1246,-1994,258,-1343,-1374,-1525,-1211,-1600,2898,293,-170,-336,2414,1657,-936,-1069,-1115,-32,-2177,49,-3926,1158,1794,-43,473,-552,-550,2070,-1913,2836,-884,109,-955,-2110,-1684,1141,-2189,1075,-919,-1760,-1808,-448,-174,-709,398,1917,-612,464,1875,1523,1328,1534,1776,-736,-635,-1673,-3829,356,2319,334,-842,-791,2863,1672,-1370,-1079,-1419,-242,1783,-2791,60,-1596,2118,726,-1133,-1827,-174,719,2146,-215,641,2093,-1112,1441,-2678,2536,-3930,-1252,892,3428,793,-2031,-3510,-256,-380,-913,-2074,-462,-1388,-1863,550,-971,1822,404,-1611,-1913,200,-674,-2225,-246,3046,-2318,-1437,3416,-994,1206,260,-2300,979,3390,794,-1981,420,-420,-208,-1220,2130,927,-1699,-1508,1509,-1078,-1309,857,-2466,-1602,1361,-561,-1694,734,3730,-624,318,-361,2404,648,3783,-584,88,3649,879,1930,1318,278,223,-520,-2304,784,3707,-603,-996,-1500,-1541,-1314,540,1662,1997,-247,-657,-180,2554,-2585,-1424,-1034,-1427,360,3487,-1721,-1678,-60,-1692,-1647,21,-1740,1174,-3929,647,1967,-345,-879,-88,3911,-865,683,835,1800,-112,424,2525,-64,2840,1996,-1945,-3407,-1058,-2160,-3568,-1122,-323,3839,-470,-508,3766,-360,-603,-725,-2046,-451,3788,-326,-368,3790,-333,-409,3752,-216,-369,3798,-189,-570,3759,-140,-361,3736,-49,-677,3594,517,-660,3749,-156,-700,3711,-234,-731,3672,-119,-608,3734,-143,2359,942,-604,-665,-1254,-1830,-1889,2116,-1871,-751,3731,-368,-638,3764,-322,2175,1219,-308,1242,1120,1872,-275,3889,-567,-331,3557,1047,-456,3595,802,-402,3556,968,-531,3621,733,643,3789,-735,1777,2394,-2002,-565,3579,765,-469,3565,931,-343,3467,1226,-426,3541,1042,-411,3427,1193,-461,3473,1119,-461,3473,1201,-531,3516,1029,-502,3419,1191,-588,3549,875,-553,3431,1199,-657,3490,946,-689,3391,1062,542,-3928,987,-624,3585,715,-583,3484,1023,-700,3524,808,409,-1436,-1919,1179,286,-2340,1157,344,-2382,1270,448,-2394,-605,3601,555,-682,3555,657,-1984,-3931,-1804,-360,3387,1300,-304,3424,1325,-419,3424,1333,-312,3356,1378,-362,3371,1435,-401,3321,1437,-287,3310,1490,-451,3399,1263,-499,3403,1311,-449,3357,1393,-514,3330,1386,551,3024,-2280,-285,3175,1707,-298,3231,1606,-344,3185,1642,-344,3257,1572,-405,3267,1539,-395,3181,1642,-493,3203,1534,-480,3146,1617,-663,3136,1430,-566,3087,1542,-613,3182,1424,-545,3171,1525,-591,3235,1420,-654,3284,1313,-542,3262,1399,-597,3287,1287,-868,3586,-37,-650,3328,1174,-584,3351,1270,-790,3708,-436,-842,3698,-445,-828,3595,-129,-867,3629,-477,-852,3574,-222,-926,3612,-268,-765,3608,-152,-1871,700,350,-1257,-1723,1254,-1058,3521,-213,-1122,3457,-156,-974,3561,-213,-1100,3485,-316,-1017,3578,-333,-1052,3511,-363,538,-753,2076,-1787,1271,630,-1068,-439,-1970,-971,3570,-102,-1126,3561,-444,733,-1053,-1885,-792,3472,705,-928,3473,488,-874,3471,671,485,-3716,-2164,-748,3439,869,-764,3411,1008,-814,3411,899,-790,3344,1061,-819,3460,839,-842,3367,977,-1007,3309,896,-939,3329,952,-993,3385,785,-943,3391,722,-1988,2581,-1300,-1027,3350,770,-1053,3407,598,-881,3347,901,-894,3405,793,-972,3421,573,1398,-1941,149,-902,3435,622,-706,3361,1122,-741,3315,1131,-697,3301,1216,-703,3230,1294,-825,3280,1083,-782,3288,1160,-813,3232,1177,754,2932,1640,-723,3166,1318,-737,3139,1417,-852,3208,1252,-805,3108,1402,286,-2047,2106,-1931,2714,-1175,-982,3093,1223,-931,3086,1303,-922,3119,1250,-987,3154,1172,-934,3226,1135,-966,3185,1102,-904,3185,1246,451,3816,-621,-1026,3244,998,185,2679,-2563,-1691,2759,134,572,229,-2565,-1592,3160,-402,-1559,3211,-316,-1481,3321,-460,-268,-1423,-1942,-1643,3139,-488,-1026,3559,-1231,-1670,3055,-360,-2016,1163,-118,-51,-951,2036,-1811,1309,611,-1812,2867,-253,-1700,2984,-162,-1713,2966,-433,1366,2176,-2511,-1742,2947,-585,-1689,3040,-219,-1186,1849,-2671,-512,-3021,827,569,-2816,871,479,3582,794,1291,-2145,300,1851,-14,-365,-63,-526,2330,-1457,3109,400,-1398,3163,398,-165,-1631,-1936,-1412,3062,603,-1367,3139,607,-1525,2949,386,-1499,2964,541,-1288,3074,883,-1327,3145,663,-1380,3103,689,-1365,3029,798,-1438,2977,763,-1464,2879,683,-1432,2937,807,-2742,-3929,-947,-1517,2823,654,-1443,2791,872,-1513,2835,530,-461,-1004,-2038,-1417,2831,864,387,-3927,1071,355,-3514,992,-664,-1751,-1642,-326,2646,-2542,-1282,3002,944,-1349,2972,956,1677,1905,761,1144,-2757,-1495,-1284,2957,1041,-1377,2905,928,-1423,2883,912,-1303,2872,1132,-1350,2861,1033,-1396,2811,966,-1430,2765,969,-1356,2915,1037,426,3594,785,-1429,2713,897,-1976,1114,50,-1998,1216,-25,-1992,1228,53,-1932,1159,161,-1968,1245,127,-1962,1463,-29,-2018,1346,51,-1938,1258,201,-1394,300,1734,-1881,1256,346,-1895,1225,300,-1899,1137,306,-1720,370,956,-1730,571,885,-541,-190,2144,-1902,1196,250,-1929,1124,255,-1878,923,367,-1898,967,292,17,-2515,1593,17,-2619,1478,-1779,1367,693,-1743,1437,699,-1757,1334,711,-349,-761,-2093,-1767,1493,705,-73,2631,2051,-1738,1582,768,-1724,1532,772,-1514,-1897,-919,-1735,1475,783,-1171,2841,1296,-97,2859,-2423,-1191,-1873,1273,-1520,149,1531,-1378,1845,1620,1939,463,-81,-1665,-3929,-1961,-1857,-3930,-1884,-144,2930,-2408,-1808,375,-1886,-1791,-200,322,1085,3270,-1703,-111,731,2289,-576,522,1841,1366,545,1630,2000,-16,-856,-1426,192,1690,-1516,286,1571,2804,-3928,-793,-1482,-1323,1006,2090,-198,-662,-622,-2476,1176,438,3266,1504,-766,-2372,1128,-634,-2345,1355,1453,-1501,-1170,-519,-2495,1271,-390,-2513,1367,-465,-2414,1444,-624,-2316,1441,-1541,2397,823,-274,-2440,1566,-1902,930,435,-475,588,1821,1363,573,1641,-210,761,2006,710,-921,1719,-87,-2485,1605,-168,-2527,1522,1683,-3584,149,-375,-597,-2140,709,-930,1723,831,-483,2036,-1193,1202,1954,743,-935,1800,-1036,2983,-2160,-511,565,1813,1016,3608,-953,-673,465,1886,-1214,-3929,612,-917,-2287,1019,-506,-1049,1773,1290,-1359,-1448,1632,-1020,-1175,-1560,2362,846,1480,926,-2372,844,-1360,-1740,-838,2916,1613,-65,1000,2278,-191,1462,2305,-1147,450,1870,-110,3822,155,967,-970,-1792,-1616,784,1308,-100,3846,233,-764,2963,1629,-803,2926,1592,-673,3024,1612,-728,2979,1558,-665,2949,1647,-885,3029,1420,-969,2928,1461,-905,2928,1517,-874,2960,1507,-934,3014,1380,-990,2976,1402,-1006,2938,1373,-870,2923,1570,-974,3022,1335,-827,3046,1397,-647,3099,1520,-619,3065,1570,-343,3137,1731,-328,3037,1815,-495,3096,1612,-469,2971,1750,-349,2973,1801,-412,2969,1793,-284,2943,1867,-558,2962,1721,-579,3018,1631,-533,3055,1615,337,-3893,-2203,-120,1027,2261,-96,829,2280,-119,900,2248,-190,906,2160,-169,828,2159,-1688,372,-1969,-48,-2584,1514,-62,701,2350,-1707,628,1029,-857,-2209,1233,892,1412,-2739,-77,3891,-360,-130,3878,-384,-50,3862,-212,-66,3845,-130,-189,3884,-327,-140,3856,-243,-180,3839,-160,-165,3813,69,-180,3802,-14,-307,3729,43,-237,3768,60,-273,3766,-24,-307,3762,-115,-279,3820,-179,-320,3792,-258,-230,3817,-35,-269,3835,-299,-107,3670,823,-56,3645,953,-174,3698,742,-188,3655,821,-127,3661,907,-170,3611,1035,-130,3586,1050,-58,3514,1215,-76,3498,1338,-129,3550,1209,-185,3514,1194,-270,3495,1239,-221,3581,1031,-272,3656,835,-215,3652,923,-46,3430,1478,-114,3400,1453,-63,3168,1790,-115,3226,1713,-166,3280,1616,-129,3149,1730,-120,3317,1593,-252,3181,1647,-200,3146,1716,-214,3216,1643,-231,3274,1552,-227,3323,1520,-169,3193,1663,-274,3375,1441,-213,3414,1411,-57,2904,1921,-108,2899,1963,-141,2914,1914,-68,3018,1884,-100,2953,1904,-160,2979,1898,-262,2927,1909,-221,3068,1826,-173,3016,1853,-177,3097,1757,-120,3067,1819,-145,3127,1795,-104,3022,1851,-77,3096,1800,-2637,-3736,-820,-63,-514,2543,-1064,3183,1053,-1116,3316,693,-1150,3295,742,-1117,3212,996,-1184,3225,854,-1035,3083,1228,-1095,3150,1090,-1082,3056,1150,-1123,3167,1020,-1128,3104,1065,-1236,3054,998,-1272,3164,833,-1206,3111,1010,-1274,3222,673,-1142,3366,488,-1071,3338,662,-1349,3230,439,-1150,3485,-515,-1214,3492,-499,-1150,3479,-396,-1182,3417,-375,-1159,3493,-295,-1256,3425,-520,-1314,3437,-370,-1385,3402,-435,-1199,3439,-216,-770,-2256,1314,-794,409,1916,-443,3665,-1439,-1155,1288,2014,-1237,1371,1950,-1245,1326,1968,-1222,1234,1958,-1340,1250,1915,-1248,1413,1933,-1043,3032,1232,-1042,3010,1318,-1151,3063,1092,-1138,3013,1135,-1107,3036,1207,-1093,2976,1215,-1170,2974,1184,-1080,2907,1342,-1140,2862,1331,-1122,2883,1290,-1177,2923,1186,-1219,2892,1219,-1274,2927,1132,-1718,804,912], diff --git a/examples/scenes/test_scene.js b/examples/scenes/test_scene.js index 6b688e956ad458..d1c5545e33524d 100644 --- a/examples/scenes/test_scene.js +++ b/examples/scenes/test_scene.js @@ -518,7 +518,7 @@ "colorDiffuse" : [0.8, 0.8, 0.8], "colorSpecular" : [0.5, 0.5, 0.5], "specularCoef" : 50, - "transparency" : 1.0, + "opacity" : 1.0, "vertexColors" : true }], diff --git a/src/loaders/Loader.js b/src/loaders/Loader.js index 6fa430e726c742..4dd0f7c440acd3 100644 --- a/src/loaders/Loader.js +++ b/src/loaders/Loader.js @@ -310,7 +310,7 @@ THREE.Loader.prototype = { if ( m.transparency ) { - console.warn( 'transparency has been renamed to opacity' ); + console.warn( 'THREE.Loader: transparency has been renamed to opacity' ); mpars.opacity = m.transparency; } From f9912deee8580f1e35d512a84467463e75c4ba26 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 25 Jan 2015 15:32:37 +0100 Subject: [PATCH 054/333] Editor/App: Didn't know you could just pass a single string. --- editor/js/libs/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/js/libs/app.js b/editor/js/libs/app.js index 0618eeccff3247..8c73e54c0735e9 100644 --- a/editor/js/libs/app.js +++ b/editor/js/libs/app.js @@ -47,7 +47,7 @@ var APP = { var script = scripts[ i ]; - var functions = ( new Function( 'player', 'scene', 'keydown', 'keyup', 'mousedown', 'mouseup', 'mousemove', 'touchstart', 'touchend', 'touchmove', 'update', script.source + '\nreturn { keydown: keydown, keyup: keyup, mousedown: mousedown, mouseup: mouseup, mousemove: mousemove, touchstart: touchstart, touchend: touchend, touchmove: touchmove, update: update };' ).bind( object ) )( this, scene ); + var functions = ( new Function( 'player, scene, keydown, keyup, mousedown, mouseup, mousemove, touchstart, touchend, touchmove, update', script.source + '\nreturn { keydown: keydown, keyup: keyup, mousedown: mousedown, mouseup: mouseup, mousemove: mousemove, touchstart: touchstart, touchend: touchend, touchmove: touchmove, update: update };' ).bind( object ) )( this, scene ); for ( var name in functions ) { From bbb78fc50bc48918cd4836d6017e7acee2a96084 Mon Sep 17 00:00:00 2001 From: tsone Date: Mon, 26 Jan 2015 16:35:49 +0800 Subject: [PATCH 055/333] WebGLRenderer: Fixes Mesh rendering drawArrays call when position attribute array itemSize is not 3. --- src/renderers/WebGLRenderer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d6e51c00a7528d..67caa018c61a0c 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2601,11 +2601,11 @@ THREE.WebGLRenderer = function ( parameters ) { // render non-indexed triangles - _gl.drawArrays( mode, 0, position.array.length / 3 ); + _gl.drawArrays( mode, 0, position.array.length / position.itemSize ); _this.info.render.calls ++; - _this.info.render.vertices += position.array.length / 3; - _this.info.render.faces += position.array.length / 9; + _this.info.render.vertices += position.array.length / position.itemSize; + _this.info.render.faces += position.array.length / ( 3 * position.itemsize ); } From c547d98f085c1e202300e2b81494abe424852e45 Mon Sep 17 00:00:00 2001 From: Theo Armour Date: Mon, 26 Jan 2015 14:09:44 -0800 Subject: [PATCH 056/333] Fix Chrome from 'Multiply' to 'MultiplyOperation' --- examples/webgl_materials_cars.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/webgl_materials_cars.html b/examples/webgl_materials_cars.html index 7a4527cd445565..9da6d635682626 100644 --- a/examples/webgl_materials_cars.html +++ b/examples/webgl_materials_cars.html @@ -250,7 +250,7 @@ "Carmine": new THREE.MeshPhongMaterial( { color: 0x770000, specular:0xffaaaa, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Gold": new THREE.MeshPhongMaterial( { color: 0xaa9944, specular:0xbbaa99, shininess:50, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Bronze": new THREE.MeshPhongMaterial( { color: 0x150505, specular:0xee6600, shininess:10, envMap: textureCube, combine: THREE.MixOperation, reflectivity: 0.25 } ), - "Chrome": new THREE.MeshPhongMaterial( { color: 0xffffff, specular:0xffffff, envMap: textureCube, combine: THREE.Multiply } ), + "Chrome": new THREE.MeshPhongMaterial( { color: 0xffffff, specular:0xffffff, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Orange metal": new THREE.MeshLambertMaterial( { color: 0xff6600, ambient: 0xff2200, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Blue metal": new THREE.MeshLambertMaterial( { color: 0x001133, ambient: 0x002266, envMap: textureCube, combine: THREE.MultiplyOperation } ), From 0c5b9d0e6cda1e77ab4fee81cae3f5ae37b5e91c Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 26 Jan 2015 23:11:36 +0100 Subject: [PATCH 057/333] Editor: Some work towards fixing #5982. Still not done, the first render doesn't show the new "groups". --- editor/js/Sidebar.Material.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index 44c752f72910db..e92e06ef8ad80b 100644 --- a/editor/js/Sidebar.Material.js +++ b/editor/js/Sidebar.Material.js @@ -369,7 +369,7 @@ Sidebar.Material = function ( editor ) { var geometry = object.geometry; var material = object.material; - + var textureWarning = false; var objectHasUvs = false; @@ -436,8 +436,20 @@ Sidebar.Material = function ( editor ) { if ( material.vertexColors !== undefined ) { - material.vertexColors = parseInt( materialVertexColors.getValue() ); - material.needsUpdate = true; + var vertexColors = parseInt( materialVertexColors.getValue() ); + + if ( material.vertexColors !== vertexColors ) { + + if ( geometry instanceof THREE.Geometry ) { + + geometry.groupsNeedUpdate = true; + + } + + material.vertexColors = vertexColors; + material.needsUpdate = true; + + } } From 348a3c3c53418fb7b3da61a87aebb6f5979e5ff2 Mon Sep 17 00:00:00 2001 From: repsac Date: Mon, 26 Jan 2015 20:44:30 -0800 Subject: [PATCH 058/333] Updated bl_info author, version, and blender metadata. Fixed menu label to read "Three.js". Reimplemented the "Frame index as time" option. Animation data is an array of all actions in the scene. Reimplemented the latest skeletal animation logic that had previously been missed. When copying textures destination files will be removed first. Return values of several mush functions were not consistent and causing errors. --- utils/exporters/blender/.gitignore | 1 + .../blender/addons/io_three/__init__.py | 20 +- .../blender/addons/io_three/constants.py | 13 +- .../addons/io_three/exporter/api/mesh.py | 333 +++++++++++------- .../blender/addons/io_three/exporter/io.py | 19 + .../exporters/blender/tests/blend/anim.blend | Bin 528636 -> 532940 bytes .../blender/tests/scripts/js/review.js | 8 +- 7 files changed, 256 insertions(+), 138 deletions(-) diff --git a/utils/exporters/blender/.gitignore b/utils/exporters/blender/.gitignore index 90e54781632294..c1c6da1922d327 100644 --- a/utils/exporters/blender/.gitignore +++ b/utils/exporters/blender/.gitignore @@ -1,2 +1,3 @@ tests/review __pycache__/ +tmp/ diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index b334a26866595f..fa3a466602f5bc 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -35,9 +35,9 @@ bl_info = { 'name': 'Three.js Format', - 'author': 'Ed Caspersen (repsac)', - 'version': (1, 0, 0), - 'blender': (2, 7, 2), + 'author': 'repsac, mrdoob, yomotsu, mpk, jpweeks', + 'version': (1, 1, 0), + 'blender': (2, 7, 3), 'location': 'File > Import-Export', 'description': 'Export Three.js formatted JSON files.', 'warning': '', @@ -232,6 +232,7 @@ def save_settings_export(properties): constants.MORPH_TARGETS: properties.option_animation_morph, constants.ANIMATION: properties.option_animation_skeletal, constants.FRAME_STEP: properties.option_frame_step, + constants.FRAME_INDEX_AS_TIME: properties.option_frame_index_as_time, constants.INFLUENCES_PER_VERTEX: properties.option_influences } @@ -366,6 +367,10 @@ def restore_settings_export(properties): properties.option_frame_step = settings.get( constants.FRAME_STEP, constants.EXPORT_OPTIONS[constants.FRAME_STEP]) + + properties.option_frame_index_as_time = settings.get( + constants.FRAME_INDEX_AS_TIME, + constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME]) ## } def compression_types(): @@ -522,6 +527,11 @@ class ExportThree(bpy.types.Operator, ExportHelper): description='Export animation (skeletal)', default=constants.EXPORT_OPTIONS[constants.ANIMATION]) + option_frame_index_as_time = BoolProperty( + name='Frame index as time', + description='Use (original) frame index as frame time', + default=constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME]) + option_frame_step = IntProperty( name='Frame step', description='Animation frame step', @@ -669,11 +679,13 @@ def draw(self, context): row.prop(self.properties, 'option_animation_skeletal') row = layout.row() row.prop(self.properties, 'option_frame_step') + row = layout.row() + row.prop(self.properties, 'option_frame_index_as_time') ## } def menu_func_export(self, context): default_path = bpy.data.filepath.replace('.blend', constants.EXTENSION) - text = 'Three (%s)' % constants.EXTENSION + text = 'Three.js (%s)' % constants.EXTENSION operator = self.layout.operator(ExportThree.bl_idname, text=text) operator.filepath = default_path diff --git a/utils/exporters/blender/addons/io_three/constants.py b/utils/exporters/blender/addons/io_three/constants.py index 18b514d1ed8abb..a442de8a730d03 100644 --- a/utils/exporters/blender/addons/io_three/constants.py +++ b/utils/exporters/blender/addons/io_three/constants.py @@ -49,7 +49,8 @@ COMPRESSION = 'compression' MAPS = 'maps' FRAME_STEP = 'frameStep' -ANIMATION = 'animation' +FRAME_INDEX_AS_TIME = 'frameIndexAsTime' +ANIMATION = 'animations' MORPH_TARGETS = 'morphTargets' SKIN_INDICES = 'skinIndices' SKIN_WEIGHTS = 'skinWeights' @@ -93,6 +94,7 @@ FACE_MATERIALS: False, SCALE: 1, FRAME_STEP: 1, + FRAME_INDEX_AS_TIME: False, SCENE: True, MIX_COLORS: False, COMPRESSION: None, @@ -210,10 +212,15 @@ NAME = 'name' PARENT = 'parent' - -#@TODO move to api.constants? +LENGTH = 'length' +FPS = 'fps' +HIERARCHY = 'hierarchy' POS = 'pos' ROTQ = 'rotq' +ROT = 'rot' +SCL = 'scl' +TIME = 'time' +KEYS = 'keys' AMBIENT = 'ambient' COLOR = 'color' diff --git a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py index 70ad1bf2c9d942..a75fc90496bd1e 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py @@ -24,57 +24,61 @@ def inner(name, *args, **kwargs): def animation(mesh, options): logger.debug('mesh.animation(%s, %s)', mesh, options) armature = _armature(mesh) - if armature and armature.animation_data: - return _skeletal_animations(armature, options) + animations = [] + if armature: + for action in data.actions: + logger.info('Processing action %s', action.name) + animations.append( + _skeletal_animations(action, armature, options)) + else: + logger.warning('No armature found') + + return animations @_mesh def bones(mesh): logger.debug('mesh.bones(%s)', mesh) armature = _armature(mesh) - if not armature: return - bones = [] bone_map = {} + + if not armature: + return bones, bone_map + bone_count = 0 - bone_index_rel = 0 - for bone in armature.data.bones: - logger.info('Parsing bone %s', bone.name) + armature_matrix = armature.matrix_world + for bone_count, pose_bone in enumerate(armature.pose.bones): + armature_bone = pose_bone.bone + bone_index = None - if bone.parent is None or bone.parent.use_deform is False: - bone_pos = bone.head_local + if armature_bone.parent is None: + bone_matrix = armature_matrix * armature_bone.matrix_local bone_index = -1 else: - bone_pos = bone.head_local - bone.parent.head_local - bone_index = 0 - index = 0 - for parent in armature.data.bones: - if parent.name == bone.parent.name: - bone_index = bone_map.get(index) + parent_bone = armature_bone.parent + parent_matrix = armature_matrix * parent_bone.matrix_local + bone_matrix = armature_matrix * armature_bone.matrix_local + bone_matrix = parent_matrix.inverted() * bone_matrix + bone_index = index = 0 + + for pose_parent in armature.pose.bones: + armature_parent = pose_parent.bone.name + if armature_parent == parent_bone.name: + bone_index = index index += 1 - bone_world_pos = armature.matrix_world * bone_pos - x_axis = bone_world_pos.x - y_axis = bone_world_pos.z - z_axis = -bone_world_pos.y - - if bone.use_deform: - logger.debug('Adding bone %s at: %s, %s', - bone.name, bone_index, bone_index_rel) - bone_map[bone_count] = bone_index_rel - bone_index_rel += 1 - bones.append({ - constants.PARENT: bone_index, - constants.NAME: bone.name, - constants.POS: (x_axis, y_axis, z_axis), - constants.ROTQ: (0,0,0,1) - }) - else: - logger.debug('Ignoring bone %s at: %s, %s', - bone.name, bone_index, bone_index_rel) + bone_map[bone_count] = bone_count - bone_count += 1 + pos, rot, scl = bone_matrix.decompose() + bones.append({ + constants.PARENT: bone_index, + constants.NAME: armature_bone.name, + constants.POS: (pos.x, pos.z, -pos.y), + constants.ROTQ: (rot.x, rot.z, -rot.y, rot.w), + 'scl': (scl.x, scl.z, scl.y) + }) return (bones, bone_map) @@ -101,8 +105,6 @@ def buffer_normal(mesh, options): return normals_ - - @_mesh def buffer_position(mesh, options): position = [] @@ -367,12 +369,12 @@ def materials(mesh, options): @_mesh def normals(mesh, options): logger.debug('mesh.normals(%s, %s)', mesh, options) - flattened = [] + normal_vectors = [] for vector in _normals(mesh, options): - flattened.extend(vector) + normal_vectors.extend(vector) - return flattened + return normal_vectors @_mesh @@ -631,12 +633,13 @@ def _armature(mesh): def _skinning_data(mesh, bone_map, influences, array_index): armature = _armature(mesh) - if not armature: return + manifest = [] + if not armature: + return manifest obj = object_.objects_using_mesh(mesh)[0] logger.debug('Skinned object found %s', obj.name) - manifest = [] for vertex in mesh.vertices: bone_array = [] for group in vertex.groups: @@ -648,9 +651,9 @@ def _skinning_data(mesh, bone_map, influences, array_index): if index >= len(bone_array): manifest.append(0) continue - - for bone_index, bone in enumerate(armature.data.bones): - if bone.name != obj.vertex_groups[bone_array[index][0]].name: + name = obj.vertex_groups[bone_array[index][0]].name + for bone_index, bone in enumerate(armature.pose.bones): + if bone.name != name: continue if array_index is 0: entry = bone_map.get(bone_index, -1) @@ -665,101 +668,177 @@ def _skinning_data(mesh, bone_map, influences, array_index): return manifest -def _skeletal_animations(armature, options): - action = armature.animation_data.action +def _find_channels(action, bone, channel_type): + result = [] + + if len(action.groups): + + group_index = -1 + for index, group in enumerate(action.groups): + if group.name == bone.name: + group_index = index + #@TODO: break? + + if group_index > -1: + for channel in action.groups[group_index].channels: + if channel_type in channel.data_path: + result.append(channel) + + else: + bone_label = '"%s"' % bone.name + for channel in action.fcurves: + data_path = [bone_label in channel.data_path, + channel_type in channel.data_path] + if all(data_path): + result.append(channel) + + return result + + +def _skeletal_animations(action, armature, options): + try: + current_context = context.area.type + except AttributeError: + logger.warning('No context, possibly running in batch mode') + else: + context.area.type = 'DOPESHEET_EDITOR' + context.space_data.mode = 'ACTION' + context.area.spaces.active.action = action + + armature_matrix = armature.matrix_world + fps = context.scene.render.fps + end_frame = action.frame_range[1] start_frame = action.frame_range[0] frame_length = end_frame - start_frame - l,r,s = armature.matrix_world.decompose() - rotation_matrix = r.to_matrix() - hierarchy = [] - parent_index = -1 + frame_step = options.get(constants.FRAME_STEP, 1) - fps = context.scene.render.fps + used_frames = int(frame_length / frame_step) + 1 + + keys = [] + channels_location = [] + channels_rotation = [] + channels_scale = [] + + for pose_bone in armature.pose.bones: + logger.info('Processing channels for %s', + pose_bone.bone.name) + keys.append([]) + channels_location.append( + _find_channels(action, + pose_bone.bone, + 'location')) + channels_rotation.append( + _find_channels(action, + pose_bone.bone, + 'rotation_quaternion')) + channels_rotation.append( + _find_channels(action, + pose_bone.bone, + 'rotation_euler')) + channels_scale.append( + _find_channels(action, + pose_bone.bone, + 'scale')) + + frame_step = options[constants.FRAME_STEP] + frame_index_as_time = options[constants.FRAME_INDEX_AS_TIME] + for frame_index in range(0, used_frames): + if frame_index == used_frames - 1: + frame = end_frame + else: + frame = start_frame + frame_index * frame_step - start = int(start_frame) - end = int(end_frame / frame_step) + 1 + logger.info('Processing frame %d', frame) - #@TODO need key constants - for bone in armature.data.bones: - if bone.use_deform is False: - logger.info('Skipping animation data for bone %s', bone.name) - continue + time = frame - start_frame + if frame_index_as_time is False: + time = time / fps - logger.info('Parsing animation data for bone %s', bone.name) + context.scene.frame_set(frame) - keys = [] - for frame in range(start, end): - computed_frame = frame * frame_step - pos, pchange = _position(bone, computed_frame, - action, armature.matrix_world) - rot, rchange = _rotation(bone, computed_frame, - action, rotation_matrix) + bone_index = 0 + + def has_keyframe_at(channels, frame): + def find_keyframe_at(channel, frame): + for keyframe in channel.keyframe_points: + if keyframe.co[0] == frame: + return keyframe + return None + + for channel in channels: + if not find_keyframe_at(channel, frame) is None: + return True + return False + + for pose_bone in armature.pose.bones: + logger.info('Processing bone %s', pose_bone.bone.name) + if pose_bone.parent is None: + bone_matrix = armature_matrix * pose_bone.matrix + else: + parent_matrix = armature_matrix * pose_bone.parent.matrix + bone_matrix = armature_matrix * pose_bone.matrix + bone_matrix = parent_matrix.inverted() * bone_matrix + + pos, rot, scl = bone_matrix.decompose() + + pchange = True or has_keyframe_at( + channels_location[bone_index], frame) + rchange = True or has_keyframe_at( + channels_rotation[bone_index], frame) + schange = True or has_keyframe_at( + channels_scale[bone_index], frame) - # flip y and z px, py, pz = pos.x, pos.z, -pos.y rx, ry, rz, rw = rot.x, rot.z, -rot.y, rot.w + sx, sy, sz = scl.x, scl.z, scl.y + + keyframe = {constants.TIME: time} + if frame == start_frame or frame == end_frame: + keyframe.update({ + constants.POS: [px, py, pz], + constants.ROT: [rx, ry, rz, rw], + constants.SCL: [sx, sy, sz] + }) + elif any([pchange, rchange, schange]): + if pchange is True: + keyframe[constants.POS] = [px, py, pz] + if rchange is True: + keyframe[constants.ROT] = [rx, ry, rz, rw] + if schange is True: + keyframe[constants.SCL] = [sx, sy, sz] + + if len(keyframe.keys()) > 1: + logger.info('Recording keyframe data for %s %s', + pose_bone.bone.name, str(keyframe)) + keys[bone_index].append(keyframe) + else: + logger.info('No anim data to record for %s', + pose_bone.bone.name) - if frame == start_frame: - - time = (frame * frame_step - start_frame) / fps - keyframe = { - 'time': time, - 'pos': [px, py, pz], - 'rot': [rx, ry, rz, rw], - 'scl': [1, 1, 1] - } - keys.append(keyframe) - - # END-FRAME: needs pos, rot and scl attributes - # with animation length (required frame) - - elif frame == end_frame / frame_step: - - time = frame_length / fps - keyframe = { - 'time': time, - 'pos': [px, py, pz], - 'rot': [rx, ry, rz, rw], - 'scl': [1, 1, 1] - } - keys.append(keyframe) - - # MIDDLE-FRAME: needs only one of the attributes, - # can be an empty frame (optional frame) - - elif pchange == True or rchange == True: - - time = (frame * frame_step - start_frame) / fps - - if pchange == True and rchange == True: - keyframe = { - 'time': time, - 'pos': [px, py, pz], - 'rot': [rx, ry, rz, rw] - } - elif pchange == True: - keyframe = { - 'time': time, - 'pos': [px, py, pz] - } - elif rchange == True: - keyframe = { - 'time': time, - 'rot': [rx, ry, rz, rw] - } - - keys.append(keyframe) - - hierarchy.append({'keys': keys, 'parent': parent_index}) - parent_index += 1 - - #@TODO key constants + bone_index += 1 + + hierarchy = [] + bone_index = 0 + for pose_bone in armature.pose.bones: + hierarchy.append({ + constants.PARENT: bone_index - 1, + constants.KEYS: keys[bone_index] + }) + bone_index += 1 + + if frame_index_as_time is False: + frame_length = frame_length / fps + + context.scene.frame_set(start_frame) + if context.area: + context.area.type = current_context + animation = { - 'hierarchy': hierarchy, - 'length':frame_length / fps, - 'fps': fps, - 'name': action.name + constants.HIERARCHY: hierarchy, + constants.LENGTH:frame_length, + constants.FPS: fps, + constants.NAME: action.name } return animation diff --git a/utils/exporters/blender/addons/io_three/exporter/io.py b/utils/exporters/blender/addons/io_three/exporter/io.py index 749d02c1e1660d..903a128be0a4f0 100644 --- a/utils/exporters/blender/addons/io_three/exporter/io.py +++ b/utils/exporters/blender/addons/io_three/exporter/io.py @@ -1,4 +1,7 @@ +import os +import sys import shutil +import traceback from .. import constants, logger from . import _json @@ -11,6 +14,22 @@ def copy_registered_textures(dest, registration): def copy(src, dst): logger.debug('io.copy(%s, %s)' % (src, dst)) + if os.path.exists(dst) and os.path.isfile(src): + file_name = os.path.basename(src) + dst = os.path.join(dst, file_name) + + logger.info('Destination file exists, attempting to remove %s', dst) + try: + os.remove(dst) + except: + logger.error('Failed to remove destination file') + info = sys.exc_info() + trace = traceback.format_exception( + info[0], info[1], info[2].tb_next) + trace = ''.join(trace) + logger.error(trace) + raise + shutil.copy(src, dst) diff --git a/utils/exporters/blender/tests/blend/anim.blend b/utils/exporters/blender/tests/blend/anim.blend index 8a136463e860ebd8fa5866ab9794272335097e90..c8e5095735d90a05661cee7c65854cd554ce9a3a 100644 GIT binary patch literal 532940 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 literal 528636 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

XfLSj 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 0 ) { console.log( 'loading animation' ); data.materials[ 0 ].skinning = true; - mesh = new THREE.SkinnedMesh( data.geometry, material, false); + mesh = new THREE.SkinnedMesh( data.geometry, material, false ); - var name = data.geometry.animation.name; - animation = new THREE.Animation( mesh, data.geometry.animation ); + var name = data.geometry.animations[0].name; + animation = new THREE.Animation( mesh, data.geometry.animations[0] ); } else { From 0f4ff31f3890429ad5e4a5bcfcd12b022438e7d0 Mon Sep 17 00:00:00 2001 From: Cem Schemel Date: Mon, 26 Jan 2015 21:17:30 -0800 Subject: [PATCH 059/333] Add missing line break after the fog property description --- docs/api/materials/MeshLambertMaterial.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/materials/MeshLambertMaterial.html b/docs/api/materials/MeshLambertMaterial.html index 4028b0ea7d04b7..71da28735a4db6 100644 --- a/docs/api/materials/MeshLambertMaterial.html +++ b/docs/api/materials/MeshLambertMaterial.html @@ -29,7 +29,7 @@

[name]([page:Object parameters])

specularMap — Set specular map. Default is null.
alphaMap — Set alpha map. Default is null.
envMap — Set env map. Default is null.
- fog — Define whether the material color is affected by global fog settings. Default is false. + fog — Define whether the material color is affected by global fog settings. Default is false.
shading — How the triangles of a curved surface are rendered. Default is [page:Materials THREE.SmoothShading].
wireframe — Render geometry as wireframe. Default is false (i.e. render as smooth shaded).
wireframeLinewidth — Controls wireframe thickness. Default is 1.
From a5aa8b7e317517831b65d3e4aef8f777bf18cfcf Mon Sep 17 00:00:00 2001 From: tsone Date: Tue, 27 Jan 2015 18:03:20 +0800 Subject: [PATCH 060/333] MTLLoader: Added support to load bump maps ('bump', 'map_bump' property). --- examples/js/loaders/MTLLoader.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/js/loaders/MTLLoader.js b/examples/js/loaders/MTLLoader.js index 475894ef1ecea8..150a391955bd9c 100644 --- a/examples/js/loaders/MTLLoader.js +++ b/examples/js/loaders/MTLLoader.js @@ -340,6 +340,17 @@ THREE.MTLLoader.MaterialCreator.prototype = { break; + case 'map_bump': + case 'bump': + + // Bump texture map + + params[ 'bumpMap' ] = this.loadTexture( this.baseUrl + value ); + params[ 'bumpMap' ].wrapS = this.wrap; + params[ 'bumpMap' ].wrapT = this.wrap; + + break; + default: break; From 48d416cf7dd9986ffc3b325bdff386cc4fb0596e Mon Sep 17 00:00:00 2001 From: tsone Date: Tue, 27 Jan 2015 18:23:09 +0800 Subject: [PATCH 061/333] MTLLoader: Fix to avoid loading bump map twice in case material contains both 'bump' and 'bump_map'. --- examples/js/loaders/MTLLoader.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/js/loaders/MTLLoader.js b/examples/js/loaders/MTLLoader.js index 150a391955bd9c..5bd4133f2471c1 100644 --- a/examples/js/loaders/MTLLoader.js +++ b/examples/js/loaders/MTLLoader.js @@ -345,6 +345,8 @@ THREE.MTLLoader.MaterialCreator.prototype = { // Bump texture map + if ( params[ 'bumpMap' ] ) break; // Avoid loading twice. + params[ 'bumpMap' ] = this.loadTexture( this.baseUrl + value ); params[ 'bumpMap' ].wrapS = this.wrap; params[ 'bumpMap' ].wrapT = this.wrap; From ee3898e18a3f537dfa2fd65f9c3c8dacef54601b Mon Sep 17 00:00:00 2001 From: repsac Date: Tue, 27 Jan 2015 14:02:06 -0800 Subject: [PATCH 062/333] Fixed a bug that was occuring when removing destination files. --- utils/exporters/blender/addons/io_three/exporter/io.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/io.py b/utils/exporters/blender/addons/io_three/exporter/io.py index 903a128be0a4f0..59f1edc993ef11 100644 --- a/utils/exporters/blender/addons/io_three/exporter/io.py +++ b/utils/exporters/blender/addons/io_three/exporter/io.py @@ -14,10 +14,12 @@ def copy_registered_textures(dest, registration): def copy(src, dst): logger.debug('io.copy(%s, %s)' % (src, dst)) - if os.path.exists(dst) and os.path.isfile(src): + if os.path.isfile(src): file_name = os.path.basename(src) dst = os.path.join(dst, file_name) + if os.path.exists(dst): + logger.info('Destination file exists, attempting to remove %s', dst) try: os.remove(dst) From a53d5d202594ed75f143975800d9e27cb7c132ab Mon Sep 17 00:00:00 2001 From: Wandalen Date: Wed, 28 Jan 2015 22:14:39 +0200 Subject: [PATCH 063/333] Color/Euler: 'toArray' expected behavior fix --- src/math/Color.js | 10 ++++++++-- src/math/Euler.js | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/math/Color.js b/src/math/Color.js index d2b4763790a7e4..b7e3afba3e661f 100644 --- a/src/math/Color.js +++ b/src/math/Color.js @@ -372,10 +372,16 @@ THREE.Color.prototype = { }, - toArray: function () { + toArray: function( array, offset ) { - return [ this.r, this.g, this.b ]; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; + array[ offset + 0 ] = this.r; + array[ offset + 1 ] = this.g; + array[ offset + 2 ] = this.b; + + return array; }, clone: function () { diff --git a/src/math/Euler.js b/src/math/Euler.js index ee323f431374d9..8d44cba79b261e 100644 --- a/src/math/Euler.js +++ b/src/math/Euler.js @@ -280,10 +280,20 @@ THREE.Euler.prototype = { }, - toArray: function () { + toArray: function( array, offset, withoutOrder ) { - return [ this._x, this._y, this._z, this._order ]; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; + array[ offset + 0 ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + + if( !withoutOrder ) { + array[ offset + 3 ] = this._order; + } + + return array; }, toVector3: function ( optionalResult ) { From f8579eb07893b5f9fdf5f4bb2610f5575dea215e Mon Sep 17 00:00:00 2001 From: Wandalen Date: Wed, 28 Jan 2015 23:21:59 +0200 Subject: [PATCH 064/333] Color/Euler: fix 'toArray' broken expected behavior #2 --- src/math/Color.js | 2 +- src/math/Euler.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/math/Color.js b/src/math/Color.js index b7e3afba3e661f..3cc3cf5780dfe9 100644 --- a/src/math/Color.js +++ b/src/math/Color.js @@ -377,7 +377,7 @@ THREE.Color.prototype = { if ( array === undefined ) array = []; if ( offset === undefined ) offset = 0; - array[ offset + 0 ] = this.r; + array[ offset ] = this.r; array[ offset + 1 ] = this.g; array[ offset + 2 ] = this.b; diff --git a/src/math/Euler.js b/src/math/Euler.js index 8d44cba79b261e..ec46f976d6a9a4 100644 --- a/src/math/Euler.js +++ b/src/math/Euler.js @@ -280,16 +280,16 @@ THREE.Euler.prototype = { }, - toArray: function( array, offset, withoutOrder ) { + toArray: function ( array, offset, withoutOrder ) { if ( array === undefined ) array = []; if ( offset === undefined ) offset = 0; - array[ offset + 0 ] = this._x; + array[ offset ] = this._x; array[ offset + 1 ] = this._y; array[ offset + 2 ] = this._z; - if( !withoutOrder ) { + if( withoutOrder === true ) { array[ offset + 3 ] = this._order; } From cacd2e312625fbf3727aed9d1221e2b0685fa881 Mon Sep 17 00:00:00 2001 From: Wandalen Date: Wed, 28 Jan 2015 23:26:44 +0200 Subject: [PATCH 065/333] Color/Euler: fix 'toArray' broken expected behavior #3 --- src/math/Color.js | 2 +- src/math/Euler.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/math/Color.js b/src/math/Color.js index 3cc3cf5780dfe9..eb98b4585597bb 100644 --- a/src/math/Color.js +++ b/src/math/Color.js @@ -372,7 +372,7 @@ THREE.Color.prototype = { }, - toArray: function( array, offset ) { + toArray: function ( array, offset ) { if ( array === undefined ) array = []; if ( offset === undefined ) offset = 0; diff --git a/src/math/Euler.js b/src/math/Euler.js index ec46f976d6a9a4..d5c1735b298d6d 100644 --- a/src/math/Euler.js +++ b/src/math/Euler.js @@ -289,7 +289,7 @@ THREE.Euler.prototype = { array[ offset + 1 ] = this._y; array[ offset + 2 ] = this._z; - if( withoutOrder === true ) { + if( !withoutOrder ) { array[ offset + 3 ] = this._order; } From 26c6443da4f2bd30a6fc56bd970ae74b8cdc77d9 Mon Sep 17 00:00:00 2001 From: repsac Date: Wed, 28 Jan 2015 23:36:42 -0800 Subject: [PATCH 066/333] Fixing a bad logic mistake where I the incorrect disk node type is queried against the wrong variable --- utils/exporters/blender/addons/io_three/exporter/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/io.py b/utils/exporters/blender/addons/io_three/exporter/io.py index 59f1edc993ef11..e547b282087dc4 100644 --- a/utils/exporters/blender/addons/io_three/exporter/io.py +++ b/utils/exporters/blender/addons/io_three/exporter/io.py @@ -14,7 +14,7 @@ def copy_registered_textures(dest, registration): def copy(src, dst): logger.debug('io.copy(%s, %s)' % (src, dst)) - if os.path.isfile(src): + if os.path.isdir(dst): file_name = os.path.basename(src) dst = os.path.join(dst, file_name) From 80b7ac91566ee551c787c560e81a536d645b3c26 Mon Sep 17 00:00:00 2001 From: Wandalen Date: Thu, 29 Jan 2015 09:51:32 +0200 Subject: [PATCH 067/333] Color/Euler: fix 'toArray' broken expectated behavior #4 --- src/math/Euler.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/math/Euler.js b/src/math/Euler.js index d5c1735b298d6d..21ef3f0f3376ce 100644 --- a/src/math/Euler.js +++ b/src/math/Euler.js @@ -289,10 +289,6 @@ THREE.Euler.prototype = { array[ offset + 1 ] = this._y; array[ offset + 2 ] = this._z; - if( !withoutOrder ) { - array[ offset + 3 ] = this._order; - } - return array; }, From ca5dfc040f7eb2d3aff669be24764b76a3556a27 Mon Sep 17 00:00:00 2001 From: Wandalen Date: Thu, 29 Jan 2015 10:14:44 +0200 Subject: [PATCH 068/333] Color/Euler: fix 'toArray' broken expectated behavior #5 --- src/math/Euler.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/math/Euler.js b/src/math/Euler.js index 21ef3f0f3376ce..67d810898fe65b 100644 --- a/src/math/Euler.js +++ b/src/math/Euler.js @@ -280,7 +280,7 @@ THREE.Euler.prototype = { }, - toArray: function ( array, offset, withoutOrder ) { + toArray: function ( array, offset ) { if ( array === undefined ) array = []; if ( offset === undefined ) offset = 0; @@ -288,6 +288,7 @@ THREE.Euler.prototype = { array[ offset ] = this._x; array[ offset + 1 ] = this._y; array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._order; return array; }, From d4228099f5f8d7258667942c646d86bc6574c696 Mon Sep 17 00:00:00 2001 From: repsac Date: Thu, 29 Jan 2015 10:27:12 -0800 Subject: [PATCH 069/333] Enable Precision is now on by default Adjusted the precision widgets so they are laid out in a manner easier to read --- utils/exporters/blender/addons/io_three/__init__.py | 5 ++++- utils/exporters/blender/addons/io_three/constants.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index fa3a466602f5bc..0018f682d661df 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -36,7 +36,7 @@ bl_info = { 'name': 'Three.js Format', 'author': 'repsac, mrdoob, yomotsu, mpk, jpweeks', - 'version': (1, 1, 0), + 'version': (1, 1, 1), 'blender': (2, 7, 3), 'location': 'File > Import-Export', 'description': 'Export Three.js formatted JSON files.', @@ -633,10 +633,13 @@ def draw(self, context): row = layout.row() row.prop(self.properties, 'option_scale') + row = layout.row() row = layout.row() row.prop(self.properties, 'option_round_off') + row = layout.row() row.prop(self.properties, 'option_round_value') + row = layout.row() row = layout.row() row.prop(self.properties, 'option_logging') diff --git a/utils/exporters/blender/addons/io_three/constants.py b/utils/exporters/blender/addons/io_three/constants.py index a442de8a730d03..dcf1c2f2eece4b 100644 --- a/utils/exporters/blender/addons/io_three/constants.py +++ b/utils/exporters/blender/addons/io_three/constants.py @@ -107,7 +107,7 @@ LIGHTS: False, COPY_TEXTURES: True, LOGGING: DEBUG, - ENABLE_PRECISION: False, + ENABLE_PRECISION: True, PRECISION: DEFAULT_PRECISION, EMBED_GEOMETRY: True, EMBED_ANIMATION: True, From a9be06221458f79f5b5c062b9827cef202d19359 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 29 Jan 2015 20:57:00 +0100 Subject: [PATCH 070/333] Updated builds. --- build/three.js | 29 +++++++++++++++++------- build/three.min.js | 56 +++++++++++++++++++++++----------------------- 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/build/three.js b/build/three.js index 3a8bfa62b10b0c..de09d8822125a4 100644 --- a/build/three.js +++ b/build/three.js @@ -601,10 +601,16 @@ THREE.Color.prototype = { }, - toArray: function () { + toArray: function ( array, offset ) { + + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - return [ this.r, this.g, this.b ]; + array[ offset ] = this.r; + array[ offset + 1 ] = this.g; + array[ offset + 2 ] = this.b; + return array; }, clone: function () { @@ -3406,10 +3412,17 @@ THREE.Euler.prototype = { }, - toArray: function () { + toArray: function ( array, offset ) { - return [ this._x, this._y, this._z, this._order ]; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._order; + + return array; }, toVector3: function ( optionalResult ) { @@ -11516,7 +11529,7 @@ THREE.Loader.prototype = { if ( m.transparency ) { - console.warn( 'transparency has been renamed to opacity' ); + console.warn( 'THREE.Loader: transparency has been renamed to opacity' ); mpars.opacity = m.transparency; } @@ -20101,11 +20114,11 @@ THREE.WebGLRenderer = function ( parameters ) { // render non-indexed triangles - _gl.drawArrays( mode, 0, position.array.length / 3 ); + _gl.drawArrays( mode, 0, position.array.length / position.itemSize ); _this.info.render.calls ++; - _this.info.render.vertices += position.array.length / 3; - _this.info.render.faces += position.array.length / 9; + _this.info.render.vertices += position.array.length / position.itemSize; + _this.info.render.faces += position.array.length / ( 3 * position.itemsize ); } diff --git a/build/three.min.js b/build/three.min.js index 043050dd5c8cbe..5ce9f5ed56e39a 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -12,7 +12,7 @@ Math.min(100,parseInt(a[1],10))/100,this.g=Math.min(100,parseInt(a[2],10))/100,t a.g;this.b=a.b;return this},copyGammaToLinear:function(a,b){void 0===b&&(b=2);this.r=Math.pow(a.r,b);this.g=Math.pow(a.g,b);this.b=Math.pow(a.b,b);return this},copyLinearToGamma:function(a,b){void 0===b&&(b=2);var c=0=h?k/(e+f):k/(2-e-f);switch(e){case b:g=(c-d)/k+(cMath.abs(g)?(this._x=Math.atan2(-n,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(q,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h, k)):(this._y=Math.atan2(-p,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(q,-1,1)),.99999>Math.abs(q)?(this._y=Math.atan2(-p,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(p,-1,1)),.99999>Math.abs(p)?(this._x=Math.atan2(q,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-n,k),this._y=Math.atan2(-p,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z= Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(q,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-n,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z, -b||this._order)},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(){return[this._x,this._y,this._z,this._order]},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new THREE.Vector3(this._x, -this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Euler(this._x,this._y,this._z,this._order)}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; +b||this._order)},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a? +a.set(this._x,this._y,this._z):new THREE.Vector3(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Euler(this._x,this._y,this._z,this._order)}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; THREE.Line3.prototype={constructor:THREE.Line3,set:function(a,b){this.start.copy(a);this.end.copy(b);return this},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},center:function(a){return(a||new THREE.Vector3).addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){return(a||new THREE.Vector3).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a, b){var c=b||new THREE.Vector3;return this.delta(c).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);var e=b.dot(b),e=b.dot(a)/e;d&&(e=THREE.Math.clamp(e,0,1));return e}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);c=c||new THREE.Vector3;return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a); this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)},clone:function(){return(new THREE.Line3).copy(this)}};THREE.Box2=function(a,b){this.min=void 0!==a?a:new THREE.Vector2(Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector2(-Infinity,-Infinity)}; @@ -253,9 +253,9 @@ THREE.Loader.prototype={constructor:THREE.Loader,crossOrigin:void 0,addStatusEle d,e,g,h,k,r){var u=b+e,v,y=THREE.Loader.Handlers.get(u);null!==y?v=y.load(u):(v=new THREE.Texture,y=f.imageLoader,y.crossOrigin=f.crossOrigin,y.load(u,function(a){if(!1===THREE.Math.isPowerOfTwo(a.width)||!1===THREE.Math.isPowerOfTwo(a.height)){var b=c(a.width),d=c(a.height),e=document.createElement("canvas");e.width=b;e.height=d;e.getContext("2d").drawImage(a,0,0,b,d);v.image=e}else v.image=a;v.needsUpdate=!0}));v.sourceFile=e;g&&(v.repeat.set(g[0],g[1]),1!==g[0]&&(v.wrapS=THREE.RepeatWrapping), 1!==g[1]&&(v.wrapT=THREE.RepeatWrapping));h&&v.offset.set(h[0],h[1]);k&&(e={repeat:THREE.RepeatWrapping,mirror:THREE.MirroredRepeatWrapping},void 0!==e[k[0]]&&(v.wrapS=e[k[0]]),void 0!==e[k[1]]&&(v.wrapT=e[k[1]]));r&&(v.anisotropy=r);a[d]=v}function e(a){return(255*a[0]<<16)+(255*a[1]<<8)+255*a[2]}var f=this,g="MeshLambertMaterial",h={color:15658734,opacity:1,map:null,lightMap:null,normalMap:null,bumpMap:null,wireframe:!1};if(a.shading){var k=a.shading.toLowerCase();"phong"===k?g="MeshPhongMaterial": "basic"===k&&(g="MeshBasicMaterial")}void 0!==a.blending&&void 0!==THREE[a.blending]&&(h.blending=THREE[a.blending]);if(void 0!==a.transparent||1>a.opacity)h.transparent=a.transparent;void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide);void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe);void 0!==a.vertexColors&&("face"=== -a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));a.transparency&&(console.warn("transparency has been renamed to opacity"),h.opacity=a.transparency);a.opacity&&(h.opacity=a.opacity);a.specularCoef&&(h.shininess=a.specularCoef);a.mapDiffuse&&b&&d(h,"map",a.mapDiffuse,a.mapDiffuseRepeat, -a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&d(h,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&d(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&d(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&d(h,"specularMap",a.mapSpecular,a.mapSpecularRepeat,a.mapSpecularOffset,a.mapSpecularWrap, -a.mapSpecularAnisotropy);a.mapAlpha&&b&&d(h,"alphaMap",a.mapAlpha,a.mapAlphaRepeat,a.mapAlphaOffset,a.mapAlphaWrap,a.mapAlphaAnisotropy);a.mapBumpScale&&(h.bumpScale=a.mapBumpScale);a.mapNormalFactor&&(h.normalScale=new THREE.Vector2(a.mapNormalFactor,a.mapNormalFactor));g=new THREE[g](h);void 0!==a.DbgName&&(g.name=a.DbgName);return g}}; +a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));a.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),h.opacity=a.transparency);a.opacity&&(h.opacity=a.opacity);a.specularCoef&&(h.shininess=a.specularCoef);a.mapDiffuse&&b&&d(h,"map",a.mapDiffuse, +a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&d(h,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&d(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&d(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&d(h,"specularMap",a.mapSpecular,a.mapSpecularRepeat,a.mapSpecularOffset, +a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapAlpha&&b&&d(h,"alphaMap",a.mapAlpha,a.mapAlphaRepeat,a.mapAlphaOffset,a.mapAlphaWrap,a.mapAlphaAnisotropy);a.mapBumpScale&&(h.bumpScale=a.mapBumpScale);a.mapNormalFactor&&(h.normalScale=new THREE.Vector2(a.mapNormalFactor,a.mapNormalFactor));g=new THREE[g](h);void 0!==a.DbgName&&(g.name=a.DbgName);return g}}; THREE.Loader.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=0,c=this.handlers.length;bd.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+ f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);L(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),B(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D, From 7490565f8a6350f26104c91272c37c21e696f856 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 29 Jan 2015 22:59:58 +0100 Subject: [PATCH 071/333] WebGLRenderer: Workaround for influences array size mismatch. See #5916. --- src/renderers/WebGLRenderer.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 67caa018c61a0c..005b8f1654252f 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3158,6 +3158,14 @@ THREE.WebGLRenderer = function ( parameters ) { var activeInfluenceIndices = []; var influences = object.morphTargetInfluences; + var morphTargets = object.geometry.morphTargets; + + if ( influences.length > morphTargets.length ) { + + console.warn( 'THREE.WebGLRenderer: Influences array is bigger than morphTargets array.' ); + influences.length = morphTargets.length; + + } for ( var i = 0, il = influences.length; i < il; i ++ ) { From c26ced5d51b9c533b02661d5cfed343e87fe9ecc Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 29 Jan 2015 23:00:43 +0100 Subject: [PATCH 072/333] Updated builds. --- build/three.js | 8 ++++++++ build/three.min.js | 47 +++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/build/three.js b/build/three.js index de09d8822125a4..e69ea8fc92ee90 100644 --- a/build/three.js +++ b/build/three.js @@ -20671,6 +20671,14 @@ THREE.WebGLRenderer = function ( parameters ) { var activeInfluenceIndices = []; var influences = object.morphTargetInfluences; + var morphTargets = object.geometry.morphTargets; + + if ( influences.length > morphTargets.length ) { + + console.warn( 'THREE.WebGLRenderer: Influences array is bigger than morphTargets array.' ); + influences.length = morphTargets.length; + + } for ( var i = 0, il = influences.length; i < il; i ++ ) { diff --git a/build/three.min.js b/build/three.min.js index 5ce9f5ed56e39a..1bd7bc66d3c2b4 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -543,29 +543,30 @@ c[p].index,c[p].count),I.info.render.calls++,I.info.render.points+=c[p].count;el q;p++)s=c[p].index,b&&(e(d,a,g,s),l.bindBuffer(l.ELEMENT_ARRAY_BUFFER,k.buffer)),l.drawElements(h,c[p].count,m,c[p].start*n),I.info.render.calls++,I.info.render.vertices+=c[p].count;else if(b&&e(d,a,g,0),d=g.attributes.position,c=g.offsets,0===c.length)l.drawArrays(h,0,d.array.length/3),I.info.render.calls++,I.info.render.vertices+=d.array.length/3;else for(p=0,q=c.length;pd.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+ -f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);L(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),B(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D, -0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):L(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D); -b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=ib,a=Pa,d=hb,e=db);b!==Ab&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),Ab=b);xc=c;yc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); -else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==Ab&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)===l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."); -g&&l.bindFramebuffer(l.FRAMEBUFFER,Ab)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +e.__webglMorphNormalsBuffers[n[m]]),g(s),l.vertexAttribPointer(s,3,l.FLOAT,!1,0,0)),k.__webglMorphTargetInfluences[m]=q[n[m]],m++;else{n=[];q=k.morphTargetInfluences;m=k.geometry.morphTargets;q.length>m.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&& +n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]= +l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);L(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: +l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),B(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER, +l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):L(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=ib,a=Pa,d=hb,e=db);b!==Ab&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),Ab=b);xc=c;yc=a};this.readRenderTargetPixels= +function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==Ab&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== +l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,Ab)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; +this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; From a6919f1ba84151a0cb483544a450fd13a6640c03 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 29 Jan 2015 23:35:30 +0100 Subject: [PATCH 073/333] Editor: Started implementing sortable. --- editor/index.html | 8 +++++++- editor/js/libs/sortable.min.js | 2 ++ editor/js/libs/ui.js | 12 +++++++++--- 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 editor/js/libs/sortable.min.js diff --git a/editor/index.html b/editor/index.html index f2ef6ffc17ea66..34614028a187dd 100644 --- a/editor/index.html +++ b/editor/index.html @@ -42,6 +42,7 @@ + @@ -213,7 +214,12 @@ document.addEventListener( 'drop', function ( event ) { event.preventDefault(); - editor.loader.loadFile( event.dataTransfer.files[ 0 ] ); + + if ( event.dataTransfer.files.length > 0 ) { + + editor.loader.loadFile( event.dataTransfer.files[ 0 ] ); + + } }, false ); diff --git a/editor/js/libs/sortable.min.js b/editor/js/libs/sortable.min.js new file mode 100644 index 00000000000000..56d114ba9679be --- /dev/null +++ b/editor/js/libs/sortable.min.js @@ -0,0 +1,2 @@ +/*! Sortable 1.0.1 - MIT | git://github.com/rubaxa/Sortable.git */ +!function(a){"use strict";"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=a():"undefined"!=typeof Package?Sortable=a():window.Sortable=a()}(function(){"use strict";function a(a,b){this.el=a,this.options=b=b||{};var d={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(a.nodeName)?"li":">*",ghostClass:"sortable-ghost",ignore:"a, img",filter:null,animation:0,setData:function(a,b){a.setData("Text",b.textContent)},dropBubble:!1,dragoverBubble:!1};for(var e in d)!(e in b)&&(b[e]=d[e]);var g=b.group;g&&"object"==typeof g||(g=b.group={name:g}),["pull","put"].forEach(function(a){a in g||(g[a]=!0)}),L.forEach(function(d){b[d]=c(this,b[d]||M),f(a,d.substr(2).toLowerCase(),b[d])},this),a[E]=g.name+" "+(g.put.join?g.put.join(" "):"");for(var h in this)"_"===h.charAt(0)&&(this[h]=c(this,this[h]));f(a,"mousedown",this._onTapStart),f(a,"touchstart",this._onTapStart),I&&f(a,"selectstart",this._onTapStart),f(a,"dragover",this._onDragOver),f(a,"dragenter",this._onDragOver),P.push(this._onDragOver),b.store&&this.sort(b.store.get(this))}function b(a){s&&s.state!==a&&(i(s,"display",a?"none":""),!a&&s.state&&t.insertBefore(s,q),s.state=a)}function c(a,b){var c=O.call(arguments,2);return b.bind?b.bind.apply(b,[a].concat(c)):function(){return b.apply(a,c.concat(O.call(arguments)))}}function d(a,b,c){if(a){c=c||G,b=b.split(".");var d=b.shift().toUpperCase(),e=new RegExp("\\s("+b.join("|")+")\\s","g");do if(">*"===d&&a.parentNode===c||(""===d||a.nodeName.toUpperCase()==d)&&(!b.length||((" "+a.className+" ").match(e)||[]).length==b.length))return a;while(a!==c&&(a=a.parentNode))}return null}function e(a){a.dataTransfer.dropEffect="move",a.preventDefault()}function f(a,b,c){a.addEventListener(b,c,!1)}function g(a,b,c){a.removeEventListener(b,c,!1)}function h(a,b,c){if(a)if(a.classList)a.classList[c?"add":"remove"](b);else{var d=(" "+a.className+" ").replace(/\s+/g," ").replace(" "+b+" ","");a.className=d+(c?" "+b:"")}}function i(a,b,c){var d=a&&a.style;if(d){if(void 0===c)return G.defaultView&&G.defaultView.getComputedStyle?c=G.defaultView.getComputedStyle(a,""):a.currentStyle&&(c=a.currentStyle),void 0===b?c:c[b];b in d||(b="-webkit-"+b),d[b]=c+("string"==typeof c?"":"px")}}function j(a,b,c){if(a){var d=a.getElementsByTagName(b),e=0,f=d.length;if(c)for(;f>e;e++)c(d[e],e);return d}return[]}function k(a){a.draggable=!1}function l(){J=!1}function m(a,b){var c=a.lastElementChild,d=c.getBoundingClientRect();return b.clientY-(d.top+d.height)>5&&c}function n(a){for(var b=a.tagName+a.className+a.src+a.href+a.textContent,c=b.length,d=0;c--;)d+=b.charCodeAt(c);return d.toString(36)}function o(a){for(var b=0;a&&(a=a.previousElementSibling)&&"TEMPLATE"!==a.nodeName.toUpperCase();)b++;return b}function p(a,b){var c,d;return function(){void 0===c&&(c=arguments,d=this,setTimeout(function(){1===c.length?a.call(d,c[0]):a.apply(d,c),c=void 0},b))}}var q,r,s,t,u,v,w,x,y,z,A,B,C,D={},E="Sortable"+(new Date).getTime(),F=window,G=F.document,H=F.parseInt,I=!!G.createElement("div").dragDrop,J=!1,K=function(a,b,c,d,e,f){var g=G.createEvent("Event");g.initEvent(b,!0,!0),g.item=c||a,g.from=d||a,g.clone=s,g.oldIndex=e,g.newIndex=f,a.dispatchEvent(g)},L="onAdd onUpdate onRemove onStart onEnd onFilter onSort".split(" "),M=function(){},N=Math.abs,O=[].slice,P=[];return a.prototype={constructor:a,_dragStarted:function(){h(q,this.options.ghostClass,!0),a.active=this,K(t,"start",q,t,y)},_onTapStart:function(a){var b=a.type,c=a.touches&&a.touches[0],e=(c||a).target,g=e,h=this.options,i=this.el,l=h.filter;if(!("mousedown"===b&&0!==a.button||h.disabled)){if(h.handle&&(e=d(e,h.handle,i)),e=d(e,h.draggable,i),y=o(e),"function"==typeof l){if(l.call(this,a,e,this))return K(g,"filter",e,i,y),void a.preventDefault()}else if(l&&(l=l.split(",").some(function(a){return a=d(g,a.trim(),i),a?(K(a,"filter",e,i,y),!0):void 0})))return void a.preventDefault();if(e&&!q&&e.parentNode===i){"selectstart"===b&&e.dragDrop(),B=a,t=this.el,q=e,v=q.nextSibling,A=this.options.group,q.draggable=!0,h.ignore.split(",").forEach(function(a){j(e,a.trim(),k)}),c&&(B={target:e,clientX:c.clientX,clientY:c.clientY},this._onDragStart(B,!0),a.preventDefault()),f(G,"mouseup",this._onDrop),f(G,"touchend",this._onDrop),f(G,"touchcancel",this._onDrop),f(q,"dragend",this),f(t,"dragstart",this._onDragStart),f(G,"dragover",this);try{G.selection?G.selection.empty():window.getSelection().removeAllRanges()}catch(m){}}}},_emulateDragOver:function(){if(C){i(r,"display","none");var a=G.elementFromPoint(C.clientX,C.clientY),b=a,c=this.options.group.name,d=P.length;if(b)do{if((" "+b[E]+" ").indexOf(c)>-1){for(;d--;)P[d]({clientX:C.clientX,clientY:C.clientY,target:a,rootEl:b});break}a=b}while(b=b.parentNode);i(r,"display","")}},_onTouchMove:function(a){if(B){var b=a.touches[0],c=b.clientX-B.clientX,d=b.clientY-B.clientY,e="translate3d("+c+"px,"+d+"px,0)";C=b,i(r,"webkitTransform",e),i(r,"mozTransform",e),i(r,"msTransform",e),i(r,"transform",e),this._onDrag(b),a.preventDefault()}},_onDragStart:function(a,b){var c=a.dataTransfer,d=this.options;if(this._offUpEvents(),"clone"==A.pull&&(s=q.cloneNode(!0),i(s,"display","none"),t.insertBefore(s,q)),b){var e,g=q.getBoundingClientRect(),h=i(q);r=q.cloneNode(!0),i(r,"top",g.top-H(h.marginTop,10)),i(r,"left",g.left-H(h.marginLeft,10)),i(r,"width",g.width),i(r,"height",g.height),i(r,"opacity","0.8"),i(r,"position","fixed"),i(r,"zIndex","100000"),t.appendChild(r),e=r.getBoundingClientRect(),i(r,"width",2*g.width-e.width),i(r,"height",2*g.height-e.height),f(G,"touchmove",this._onTouchMove),f(G,"touchend",this._onDrop),f(G,"touchcancel",this._onDrop),this._loopId=setInterval(this._emulateDragOver,150)}else c&&(c.effectAllowed="move",d.setData&&d.setData.call(this,c,q)),f(G,"drop",this);if(u=d.scroll,u===!0){u=t;do if(u.offsetWidth=i-g)-(e>=g),l=(e>=j-h)-(e>=h);k||l?b=F:u&&(b=u,c=u.getBoundingClientRect(),k=(N(c.right-g)<=e)-(N(c.left-g)<=e),l=(N(c.bottom-h)<=e)-(N(c.top-h)<=e)),(D.vx!==k||D.vy!==l||D.el!==b)&&(D.el=b,D.vx=k,D.vy=l,clearInterval(D.pid),b&&(D.pid=setInterval(function(){b===F?F.scrollTo(F.scrollX+k*f,F.scrollY+l*f):(l&&(b.scrollTop+=l*f),k&&(b.scrollLeft+=k*f))},24)))}},30),_onDragOver:function(a){var c,e,f,g=this.el,h=this.options,j=h.group,k=j.put,n=A===j,o=h.sort;if(void 0!==a.preventDefault&&(a.preventDefault(),!h.dragoverBubble&&a.stopPropagation()),!J&&A&&(n?o||(f=!t.contains(q)):A.pull&&k&&(A.name===j.name||k.indexOf&&~k.indexOf(A.name)))&&(void 0===a.rootEl||a.rootEl===this.el)){if(c=d(a.target,h.draggable,g),e=q.getBoundingClientRect(),f)return b(!0),void(s||v?t.insertBefore(q,s||v):o||t.appendChild(q));if(0===g.children.length||g.children[0]===r||g===a.target&&(c=m(g,a))){if(c){if(c.animated)return;u=c.getBoundingClientRect()}b(n),g.appendChild(q),this._animate(e,q),c&&this._animate(u,c)}else if(c&&!c.animated&&c!==q&&void 0!==c.parentNode[E]){w!==c&&(w=c,x=i(c));var p,u=c.getBoundingClientRect(),y=u.right-u.left,z=u.bottom-u.top,B=/left|right|inline/.test(x.cssFloat+x.display),C=c.offsetWidth>q.offsetWidth,D=c.offsetHeight>q.offsetHeight,F=(B?(a.clientX-u.left)/y:(a.clientY-u.top)/z)>.5,G=c.nextElementSibling;J=!0,setTimeout(l,30),b(n),p=B?c.previousElementSibling===q&&!C||F&&C:G!==q&&!D||F&&D,p&&!G?g.appendChild(q):c.parentNode.insertBefore(q,p?G:c),this._animate(e,q),this._animate(u,c)}}},_animate:function(a,b){var c=this.options.animation;if(c){var d=b.getBoundingClientRect();i(b,"transition","none"),i(b,"transform","translate3d("+(a.left-d.left)+"px,"+(a.top-d.top)+"px,0)"),b.offsetWidth,i(b,"transition","all "+c+"ms"),i(b,"transform","translate3d(0,0,0)"),clearTimeout(b.animated),b.animated=setTimeout(function(){i(b,"transition",""),b.animated=!1},c)}},_offUpEvents:function(){g(G,"mouseup",this._onDrop),g(G,"touchmove",this._onTouchMove),g(G,"touchend",this._onDrop),g(G,"touchcancel",this._onDrop)},_onDrop:function(b){var c=this.el,d=this.options;clearInterval(this._loopId),clearInterval(D.pid),g(G,"drop",this),g(G,"dragover",this),g(c,"dragstart",this._onDragStart),this._offUpEvents(),b&&(b.preventDefault(),!d.dropBubble&&b.stopPropagation(),r&&r.parentNode.removeChild(r),q&&(g(q,"dragend",this),k(q),h(q,this.options.ghostClass,!1),t!==q.parentNode?(z=o(q),K(q.parentNode,"sort",q,t,y,z),K(t,"sort",q,t,y,z),K(q,"add",q,t,y,z),K(t,"remove",q,t,y,z)):(s&&s.parentNode.removeChild(s),q.nextSibling!==v&&(z=o(q),K(t,"update",q,t,y,z),K(t,"sort",q,t,y,z))),a.active&&K(t,"end",q,t,y,z)),t=q=r=v=s=B=C=w=x=A=a.active=null,this.save())},handleEvent:function(a){var b=a.type;"dragover"===b?(this._onDrag(a),e(a)):("drop"===b||"dragend"===b)&&this._onDrop(a)},toArray:function(){for(var a,b=[],c=this.el.children,e=0,f=c.length;f>e;e++)a=c[e],d(a,this.options.draggable,this.el)&&b.push(a.getAttribute("data-id")||n(a));return b},sort:function(a){var b={},c=this.el;this.toArray().forEach(function(a,e){var f=c.children[e];d(f,this.options.draggable,c)&&(b[a]=f)},this),a.forEach(function(a){b[a]&&(c.removeChild(b[a]),c.appendChild(b[a]))})},save:function(){var a=this.options.store;a&&a.set(this)},closest:function(a,b){return d(a,b||this.options.draggable,this.el)},option:function(a,b){var c=this.options;return void 0===b?c[a]:void(c[a]=b)},destroy:function(){var a=this.el,b=this.options;L.forEach(function(c){g(a,c.substr(2).toLowerCase(),b[c])}),g(a,"mousedown",this._onTapStart),g(a,"touchstart",this._onTapStart),g(a,"selectstart",this._onTapStart),g(a,"dragover",this._onDragOver),g(a,"dragenter",this._onDragOver),Array.prototype.forEach.call(a.querySelectorAll("[draggable]"),function(a){a.removeAttribute("draggable")}),P.splice(P.indexOf(this._onDragOver),1),this._onDrop(),this.el=null}},a.utils={on:f,off:g,css:i,find:j,bind:c,is:function(a,b){return!!d(a,b,a)},throttle:p,closest:d,toggleClass:h,dispatchEvent:K,index:o},a.version="1.0.1",a.create=function(b,c){return new a(b,c)},a}); \ No newline at end of file diff --git a/editor/js/libs/ui.js b/editor/js/libs/ui.js index 3221ed641e27b3..4286c6632fa7bf 100644 --- a/editor/js/libs/ui.js +++ b/editor/js/libs/ui.js @@ -15,7 +15,7 @@ UI.Element.prototype = { setId: function ( id ) { this.dom.id = id; - + return this; }, @@ -137,7 +137,7 @@ UI.Panel.prototype.add = function () { UI.Panel.prototype.remove = function () { for ( var i = 0; i < arguments.length; i ++ ) { - + var argument = arguments[ i ]; if ( argument instanceof UI.Element ) { @@ -515,6 +515,12 @@ UI.FancySelect = function () { dom.className = 'FancySelect'; dom.tabIndex = 0; // keyup event is ignored without setting tabIndex + Sortable.create( dom, { + onUpdate: function ( event ) { + console.log( event ); + } + } ); + // Broadcast for object selection after arrow navigation var changeEvent = document.createEvent('HTMLEvents'); changeEvent.initEvent( 'change', true, true ); @@ -1154,7 +1160,7 @@ UI.Button.prototype.setLabel = function ( value ) { UI.Dialog = function ( value ) { var scope = this; - + var dom = document.createElement( 'dialog' ); if ( dom.showModal === undefined ) { From c78f9ffdb1460381d53f7c0bb161b9b278879dc6 Mon Sep 17 00:00:00 2001 From: DodekaHydra Date: Thu, 29 Jan 2015 15:33:59 -0800 Subject: [PATCH 074/333] Update CurvePath.js Removal of unreachable break statement --- src/extras/core/CurvePath.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/extras/core/CurvePath.js b/src/extras/core/CurvePath.js index b60feca5a89658..3cd14fe81926cc 100644 --- a/src/extras/core/CurvePath.js +++ b/src/extras/core/CurvePath.js @@ -72,7 +72,6 @@ THREE.CurvePath.prototype.getPoint = function( t ) { return curve.getPointAt( u ); - break; } i ++; From dcb58cc7de99a9962980af773ec5ae510a15f730 Mon Sep 17 00:00:00 2001 From: DodekaHydra Date: Thu, 29 Jan 2015 15:36:25 -0800 Subject: [PATCH 075/333] Update Curve.js Removal of unnecessary continue statements --- src/extras/core/Curve.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/extras/core/Curve.js b/src/extras/core/Curve.js index 04decdccd13363..b0a9e070d03fdf 100644 --- a/src/extras/core/Curve.js +++ b/src/extras/core/Curve.js @@ -182,12 +182,10 @@ THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) { if ( comparison < 0 ) { low = i + 1; - continue; } else if ( comparison > 0 ) { high = i - 1; - continue; } else { From 788c1e7a807dd3b69e053aff8ed24538dc694ac6 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 30 Jan 2015 01:11:46 +0100 Subject: [PATCH 076/333] Fixed example. --- examples/js/shaders/NormalDisplacementShader.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/js/shaders/NormalDisplacementShader.js b/examples/js/shaders/NormalDisplacementShader.js index e245805c21bcdc..4189bed17ce36b 100644 --- a/examples/js/shaders/NormalDisplacementShader.js +++ b/examples/js/shaders/NormalDisplacementShader.js @@ -1,4 +1,4 @@ -/* +/* * @author alteredq / http://alteredqualia.com/ * * Normal map shader @@ -126,6 +126,7 @@ THREE.NormalDisplacementShader = { "varying vec3 vWorldPosition;", "varying vec3 vViewPosition;", + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], @@ -174,7 +175,7 @@ THREE.NormalDisplacementShader = { " #endif", " }", - + THREE.ShaderChunk[ "alphatest_fragment" ], " if( enableSpecular )", @@ -494,6 +495,7 @@ THREE.NormalDisplacementShader = { "varying vec3 vWorldPosition;", "varying vec3 vViewPosition;", + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "skinning_pars_vertex" ], THREE.ShaderChunk[ "shadowmap_pars_vertex" ], THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], From 6fef12c5ffc0510d220d3c94d745fba52a1d13d5 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 30 Jan 2015 01:19:54 +0100 Subject: [PATCH 077/333] Fixed more examples. --- examples/js/ShaderDeferred.js | 1 + examples/js/ShaderTerrain.js | 2 +- examples/js/shaders/NormalDisplacementShader.js | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/js/ShaderDeferred.js b/examples/js/ShaderDeferred.js index b6d2bb75a5243b..1b2db5b8e1f9a3 100644 --- a/examples/js/ShaderDeferred.js +++ b/examples/js/ShaderDeferred.js @@ -169,6 +169,7 @@ THREE.ShaderDeferred = { "#endif", + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "specularmap_pars_fragment" ], diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index 857d0826c42637..51e939de2afe46 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -170,7 +170,7 @@ THREE.ShaderTerrain = { "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", "vec3 lVector = lPosition.xyz + vViewPosition.xyz;", - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );" + "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );", "lVector = normalize( lVector );", diff --git a/examples/js/shaders/NormalDisplacementShader.js b/examples/js/shaders/NormalDisplacementShader.js index 4189bed17ce36b..7cde51f96e2c5e 100644 --- a/examples/js/shaders/NormalDisplacementShader.js +++ b/examples/js/shaders/NormalDisplacementShader.js @@ -495,7 +495,6 @@ THREE.NormalDisplacementShader = { "varying vec3 vWorldPosition;", "varying vec3 vViewPosition;", - THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "skinning_pars_vertex" ], THREE.ShaderChunk[ "shadowmap_pars_vertex" ], THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], From b64ac919f90d9ea02ddfec03afe106281a23fc5c Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 30 Jan 2015 01:20:10 +0100 Subject: [PATCH 078/333] Removed redundant code. --- editor/js/Toolbar.js | 2 -- src/renderers/WebGLRenderer.js | 6 ------ 2 files changed, 8 deletions(-) diff --git a/editor/js/Toolbar.js b/editor/js/Toolbar.js index 2905c2084b5354..d754748e0142eb 100644 --- a/editor/js/Toolbar.js +++ b/editor/js/Toolbar.js @@ -62,8 +62,6 @@ var Toolbar = function ( editor ) { } - update(); - return container; } diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 005b8f1654252f..6422aa51ef411d 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -4002,12 +4002,6 @@ THREE.WebGLRenderer = function ( parameters ) { var geometryGroup = geometryGroupsList[ i ]; var material = getBufferMaterial( object, geometryGroup ); - if ( geometry.groupsNeedUpdate === true ) { - - initMeshBuffers( geometryGroup, object ); - - } - var customAttributesDirty = material.attributes && areCustomAttributesDirty( material ); if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate || From c90e7a7e99c4c8b8eadee6d7c10182fba8e0a1ea Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 30 Jan 2015 01:20:21 +0100 Subject: [PATCH 079/333] Updated builds. --- build/three.js | 6 - build/three.min.js | 642 ++++++++++++++++++++++----------------------- 2 files changed, 321 insertions(+), 327 deletions(-) diff --git a/build/three.js b/build/three.js index e69ea8fc92ee90..92cb48568ac8fc 100644 --- a/build/three.js +++ b/build/three.js @@ -21515,12 +21515,6 @@ THREE.WebGLRenderer = function ( parameters ) { var geometryGroup = geometryGroupsList[ i ]; var material = getBufferMaterial( object, geometryGroup ); - if ( geometry.groupsNeedUpdate === true ) { - - initMeshBuffers( geometryGroup, object ); - - } - var customAttributesDirty = material.attributes && areCustomAttributesDirty( material ); if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate || diff --git a/build/three.min.js b/build/three.min.js index 1bd7bc66d3c2b4..f37fc0b0344a83 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -22,10 +22,10 @@ tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215, THREE.Quaternion.prototype={constructor:THREE.Quaternion,_x:0,_y:0,_z:0,_w:0,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get w(){return this._w},set w(a){this._w=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this.onChangeCallback();return this},copy:function(a){this._x=a.x;this._y=a.y;this._z=a.z; this._w=a.w;this.onChangeCallback();return this},setFromEuler:function(a,b){if(!1===a instanceof THREE.Euler)throw Error("THREE.Quaternion: .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var c=Math.cos(a._x/2),d=Math.cos(a._y/2),e=Math.cos(a._z/2),f=Math.sin(a._x/2),g=Math.sin(a._y/2),h=Math.sin(a._z/2);"XYZ"===a.order?(this._x=f*d*e+c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e-f*g*h):"YXZ"===a.order?(this._x=f*d*e+c*g*h,this._y=c*g*e-f*d*h,this._z= c*d*h-f*g*e,this._w=c*d*e+f*g*h):"ZXY"===a.order?(this._x=f*d*e-c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e-f*g*h):"ZYX"===a.order?(this._x=f*d*e-c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e+f*g*h):"YZX"===a.order?(this._x=f*d*e+c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e-f*g*h):"XZY"===a.order&&(this._x=f*d*e-c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e+f*g*h);if(!1!==b)this.onChangeCallback();return this},setFromAxisAngle:function(a, -b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w=Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],n=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y= +b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w=Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],p=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y= .25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+k)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):a.crossVectors(c,d);this._x=a.x;this._y=a.y;this._z=a.z;this._w=b;this.normalize();return this}}(),inverse:function(){this.conjugate().normalize();return this},conjugate:function(){this._x*= -1;this._y*=-1;this._z*=-1;this.onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this.onChangeCallback();return this}, -multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,n=b._w;this._x=c*n+f*g+d*k-e*h;this._y=d*n+f*h+e*g-c*k;this._z=e*n+f*k+c*h-d*g;this._w=f*n-c*g-d*h-e*k;this.onChangeCallback();return this},multiplyVector3:function(a){console.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead."); +multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,p=b._w;this._x=c*p+f*g+d*k-e*h;this._y=d*p+f*h+e*g-c*k;this._z=e*p+f*k+c*h-d*g;this._w=f*p-c*g-d*h-e*k;this.onChangeCallback();return this},multiplyVector3:function(a){console.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead."); return a.applyQuaternion(this)},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;var h=Math.acos(g),k=Math.sqrt(1-g*g);if(.001>Math.abs(k))return this._w=.5*(f+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;g=Math.sin((1-b)*h)/k;h= Math.sin(b*h)/k;this._w=f*g+this._w*h;this._x=c*g+this._x*h;this._y=d*g+this._y*h;this._z=e*g+this._z*h;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback= a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Quaternion(this._x,this._y,this._z,this._w)}};THREE.Quaternion.slerp=function(a,b,c,d){return c.copy(a).slerp(b,d)};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; @@ -41,7 +41,7 @@ a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:functio this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y= a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&&console.error("THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));return this}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),applyMatrix3:function(a){var b=this.x, c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z= -(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,n=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-n*-f;this.y=k*a+b*-f+n*-e-h*-g;this.z=n*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0=== +(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,p=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-p*-f;this.y=k*a+b*-f+p*-e-h*-g;this.z=p*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0=== a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},min:function(a){this.x> a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3,b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a, b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z); @@ -57,8 +57,8 @@ THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x= case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this}, addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b= this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a):(this.z=this.y=this.x=0,this.w=1);return this},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this}, -setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var n=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+n-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;n=(n+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>n?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>n?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h), -b=d/c,d=k/c):.01>n?(c=b=.707106781,d=0):(d=Math.sqrt(n),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+n-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xMath.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+p-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;p=(p+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>p?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>p?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h), +b=d/c,d=k/c):.01>p?(c=b=.707106781,d=0):(d=Math.sqrt(p),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+p-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);this.wb.w&&(this.w=b.w);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector4,b=new THREE.Vector4);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w); return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w); return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())}, @@ -66,9 +66,9 @@ setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b) b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=a.array[b+3];return this},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)}};THREE.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||THREE.Euler.DefaultOrder};THREE.Euler.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" "); THREE.Euler.DefaultOrder="XYZ"; THREE.Euler.prototype={constructor:THREE.Euler,_x:0,_y:0,_z:0,_order:THREE.Euler.DefaultOrder,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get order(){return this._order},set order(a){this._order=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this.onChangeCallback();return this},copy:function(a){this._x= -a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],n=e[9],p=e[2],q=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-n,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(q,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h, -k)):(this._y=Math.atan2(-p,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(q,-1,1)),.99999>Math.abs(q)?(this._y=Math.atan2(-p,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(p,-1,1)),.99999>Math.abs(p)?(this._x=Math.atan2(q,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-n,k),this._y=Math.atan2(-p,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z= -Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(q,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-n,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z, +a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],p=e[9],n=e[2],q=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-p,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(q,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h, +k)):(this._y=Math.atan2(-n,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(q,-1,1)),.99999>Math.abs(q)?(this._y=Math.atan2(-n,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._x=Math.atan2(q,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-p,k),this._y=Math.atan2(-n,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z= +Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(q,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-p,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z, b||this._order)},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a? a.set(this._x,this._y,this._z):new THREE.Vector3(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Euler(this._x,this._y,this._z,this._order)}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; THREE.Line3.prototype={constructor:THREE.Line3,set:function(a,b){this.start.copy(a);this.end.copy(b);return this},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},center:function(a){return(a||new THREE.Vector3).addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){return(a||new THREE.Vector3).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a, @@ -87,38 +87,38 @@ this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max. new THREE.Vector3;return function(b){b=b||new THREE.Sphere;b.center=this.center();b.radius=.5*this.size(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];return function(b){a[0].set(this.min.x,this.min.y, this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.makeEmpty();this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a); this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box3).copy(this)}};THREE.Matrix3=function(){this.elements=new Float32Array([1,0,0,0,1,0,0,0,1]);0this.determinant()&&(g=-g);c.x=f[12]; -c.y=f[13];c.z=f[14];b.elements.set(this.elements);c=1/g;var f=1/h,n=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=n;b.elements[9]*=n;b.elements[10]*=n;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makeFrustum:function(a,b,c,d,e,f){var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(d-c);g[9]=(d+c)/(d-c);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0; -g[11]=-1;g[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(THREE.Math.degToRad(.5*a));var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=b-a,k=c-d,n=f-e;g[0]=2/h;g[4]=0;g[8]=0;g[12]=-((b+a)/h);g[1]=0;g[5]=2/k;g[9]=0;g[13]=-((c+d)/k);g[2]=0;g[6]=0;g[10]=-2/n;g[14]=-((f+e)/n);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0], +1,c,0,0,0,1);return this},makeRotationX:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(1,0,0,0,0,b,-a,0,0,a,b,0,0,0,0,1);return this},makeRotationY:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,0,a,0,0,1,0,0,-a,0,b,0,0,0,0,1);return this},makeRotationZ:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,-a,0,0,a,b,0,0,0,0,1,0,0,0,0,1);return this},makeRotationAxis:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=1-c,f=a.x,g=a.y,h=a.z,k=e*f,p=e*g;this.set(k*f+c,k*g-d*h,k*h+d*g,0,k* +g+d*h,p*g+c,p*h-d*f,0,k*h-d*g,p*h+d*f,e*h*h+c,0,0,0,0,1);return this},makeScale:function(a,b,c){this.set(a,0,0,0,0,b,0,0,0,0,c,0,0,0,0,1);return this},compose:function(a,b,c){this.makeRotationFromQuaternion(b);this.scale(c);this.setPosition(a);return this},decompose:function(){var a=new THREE.Vector3,b=new THREE.Matrix4;return function(c,d,e){var f=this.elements,g=a.set(f[0],f[1],f[2]).length(),h=a.set(f[4],f[5],f[6]).length(),k=a.set(f[8],f[9],f[10]).length();0>this.determinant()&&(g=-g);c.x=f[12]; +c.y=f[13];c.z=f[14];b.elements.set(this.elements);c=1/g;var f=1/h,p=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=p;b.elements[9]*=p;b.elements[10]*=p;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makeFrustum:function(a,b,c,d,e,f){var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(d-c);g[9]=(d+c)/(d-c);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0; +g[11]=-1;g[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(THREE.Math.degToRad(.5*a));var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=b-a,k=c-d,p=f-e;g[0]=2/h;g[4]=0;g[8]=0;g[12]=-((b+a)/h);g[1]=0;g[5]=2/k;g[9]=0;g[13]=-((c+d)/k);g[2]=0;g[6]=0;g[10]=-2/p;g[14]=-((f+e)/p);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0], a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]]},clone:function(){return(new THREE.Matrix4).fromArray(this.elements)}};THREE.Ray=function(a,b){this.origin=void 0!==a?a:new THREE.Vector3;this.direction=void 0!==b?b:new THREE.Vector3}; THREE.Ray.prototype={constructor:THREE.Ray,set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){return(b||new THREE.Vector3).copy(this.direction).multiplyScalar(a).add(this.origin)},recast:function(){var a=new THREE.Vector3;return function(b){this.origin.copy(this.at(b,a));return this}}(),closestPointToPoint:function(a,b){var c=b||new THREE.Vector3;c.subVectors(a,this.origin); var d=c.dot(this.direction);return 0>d?c.copy(this.origin):c.copy(this.direction).multiplyScalar(d).add(this.origin)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceTo(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceTo(b)}}(),distanceSqToSegment:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5); -b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var h=.5*d.distanceTo(e),k=-this.direction.dot(b),n=c.dot(this.direction),p=-c.dot(b),q=c.lengthSq(),m=Math.abs(1-k*k),t;0=-t?e<=t?(h=1/m,d*=h,e*=h,k=d*(d+k*e+2*n)+e*(k*d+e+2*p)+q):(e=h,d=Math.max(0,-(k*e+n)),k=-d*d+e*(e+2*p)+q):(e=-h,d=Math.max(0,-(k*e+n)),k=-d*d+e*(e+2*p)+q):e<=-t?(d=Math.max(0,-(-k*h+n)),e=0=-s?e<=s?(h=1/m,d*=h,e*=h,k=d*(d+k*e+2*p)+e*(k*d+e+2*n)+q):(e=h,d=Math.max(0,-(k*e+p)),k=-d*d+e*(e+2*n)+q):(e=-h,d=Math.max(0,-(k*e+p)),k=-d*d+e*(e+2*n)+q):e<=-s?(d=Math.max(0,-(-k*h+p)),e=0f)return null;f=Math.sqrt(f-e);e=d-f;d+=f;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),isIntersectionPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0==b)return 0==a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){var c=this.distanceToPlane(a);return null===c?null:this.at(c,b)}, isIntersectionBox:function(){var a=new THREE.Vector3;return function(b){return null!==this.intersectBox(b,a)}}(),intersectBox:function(a,b){var c,d,e,f,g;d=1/this.direction.x;f=1/this.direction.y;g=1/this.direction.z;var h=this.origin;0<=d?(c=(a.min.x-h.x)*d,d*=a.max.x-h.x):(c=(a.max.x-h.x)*d,d*=a.min.x-h.x);0<=f?(e=(a.min.y-h.y)*f,f*=a.max.y-h.y):(e=(a.max.y-h.y)*f,f*=a.min.y-h.y);if(c>f||e>d)return null;if(e>c||c!==c)c=e;if(fg||e>d)return null;if(e>c||c!==c)c=e;if(gd?null:this.at(0<=c?c:d,b)},intersectTriangle:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3,d=new THREE.Vector3;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0f)h=-1,f=-f;else return null;a.subVectors(this.origin,e);e=h*this.direction.dot(c.crossVectors(a,c));if(0>e)return null;g=h*this.direction.dot(b.cross(a)); @@ -127,8 +127,8 @@ THREE.Sphere.prototype={constructor:THREE.Sphere,set:function(a,b){this.center.c this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},clampPoint:function(a,b){var c=this.center.distanceToSquared(a),d=b||new THREE.Vector3;d.copy(a);c>this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=a||new THREE.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius); return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius},clone:function(){return(new THREE.Sphere).copy(this)}}; THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]}; -THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],n=c[7],p=c[8],q=c[9],m=c[10],t=c[11],s=c[12],r=c[13],u=c[14],c=c[15];b[0].setComponents(f-a,n-g,t-p,c-s).normalize();b[1].setComponents(f+ -a,n+g,t+p,c+s).normalize();b[2].setComponents(f+d,n+h,t+q,c+r).normalize();b[3].setComponents(f-d,n-h,t-q,c-r).normalize();b[4].setComponents(f-e,n-k,t-m,c-u).normalize();b[5].setComponents(f+e,n+k,t+m,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes, +THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],p=c[7],n=c[8],q=c[9],m=c[10],s=c[11],t=c[12],r=c[13],u=c[14],c=c[15];b[0].setComponents(f-a,p-g,s-n,c-t).normalize();b[1].setComponents(f+ +a,p+g,s+n,c+t).normalize();b[2].setComponents(f+d,p+h,s+q,c+r).normalize();b[3].setComponents(f-d,p-h,s-q,c-r).normalize();b[4].setComponents(f-e,p-k,s-m,c-u).normalize();b[5].setComponents(f+e,p+k,s+m,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes, c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)e;e++){var f=d[e];a.x=0g&&0>f)return!1}return!0}}(), containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d, @@ -139,11 +139,11 @@ a.constant==this.constant},clone:function(){return(new THREE.Plane).copy(this)}} THREE.Math={generateUUID:function(){var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d;return function(){for(var e=0;36>e;e++)8==e||13==e||18==e||23==e?b[e]="-":14==e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19==e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return a=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){return(65280*Math.random()+255*Math.random())/65535},randInt:function(a,b){return Math.floor(this.randFloat(a,b))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a= 180/Math.PI;return function(b){return b*a}}(),isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a}}; -THREE.Spline=function(a){function b(a,b,c,d,e,f,g){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,f,g,h,k,n,p,q,m;this.initFromArray=function(a){this.points=[];for(var b=0;bthis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ -2;n=this.points[c[0]];p=this.points[c[1]];q=this.points[c[2]];m=this.points[c[3]];h=g*g;k=g*h;d.x=b(n.x,p.x,q.x,m.x,g,h,k);d.y=b(n.y,p.y,q.y,m.y,g,h,k);d.z=b(n.z,p.z,q.z,m.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;athis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ +2;p=this.points[c[0]];n=this.points[c[1]];q=this.points[c[2]];m=this.points[c[3]];h=g*g;k=g*h;d.x=b(p.x,n.x,q.x,m.x,g,h,k);d.y=b(p.y,n.y,q.y,m.y,g,h,k);d.z=b(p.z,n.z,q.z,m.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a=b.x+b.y}}(); THREE.Triangle.prototype={constructor:THREE.Triangle,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*a.cross(b).length()}}(),midpoint:function(a){return(a|| new THREE.Vector3).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return THREE.Triangle.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new THREE.Plane).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return THREE.Triangle.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return THREE.Triangle.containsPoint(a,this.a,this.b,this.c)},equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}, @@ -184,44 +184,44 @@ THREE.Uint32Attribute=function(a,b){console.warn("THREE.Uint32Attribute has been THREE.Float64Attribute=function(a,b){console.warn("THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.");return new THREE.BufferAttribute(a,b)};THREE.DynamicBufferAttribute=function(a,b){THREE.BufferAttribute.call(this,a,b);this.updateRange={offset:0,count:-1}};THREE.DynamicBufferAttribute.prototype=Object.create(THREE.BufferAttribute.prototype);THREE.DynamicBufferAttribute.prototype.constructor=THREE.DynamicBufferAttribute; THREE.DynamicBufferAttribute.prototype.clone=function(){return new THREE.DynamicBufferAttribute(new this.array.constructor(this.array),this.itemSize)};THREE.BufferGeometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="BufferGeometry";this.attributes={};this.attributesKeys=[];this.offsets=this.drawcalls=[];this.boundingSphere=this.boundingBox=null}; THREE.BufferGeometry.prototype={constructor:THREE.BufferGeometry,addAttribute:function(a,b,c){!1===b instanceof THREE.BufferAttribute?(console.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),this.attributes[a]={array:b,itemSize:c}):(this.attributes[a]=b,this.attributesKeys=Object.keys(this.attributes))},getAttribute:function(a){return this.attributes[a]},addDrawCall:function(a,b,c){this.drawcalls.push({start:a,count:b,index:void 0!==c?c:0})},applyMatrix:function(a){var b= -this.attributes.position;void 0!==b&&(a.applyToVector3Array(b.array),b.needsUpdate=!0);b=this.attributes.normal;void 0!==b&&((new THREE.Matrix3).getNormalMatrix(a).applyToVector3Array(b.array),b.needsUpdate=!0)},center:function(){},fromGeometry:function(a,b){b=b||{vertexColors:THREE.NoColors};var c=a.vertices,d=a.faces,e=a.faceVertexUvs,f=b.vertexColors,g=0Xa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=Ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],n=[],p=0;pr;r++)s=a[3*c+r],-1==m[s]?(q[2*r]=s,q[2*r+1]=-1,p++):m[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),m[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hja?-1:1;h[4*a]=na.x;h[4*a+1]=na.y;h[4*a+2]=na.z;h[4*a+3]=xa}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, +e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],p=[],n=0;nr;r++)t=a[3*c+r],-1==m[t]?(q[2*r]=t,q[2*r+1]=-1,n++):m[t]k.index+b)for(k={start:f,count:0,index:g},h.push(k),n=0;6>n;n+=2)r=q[n+1],-1n;n+=2)t=q[n],r=q[n+1],-1===r&&(r=g++),m[t]=r,s[r]=t,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,s,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(x.x,x.y,x.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;ca.opacity)h.transparent=a.transparent;void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide);void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe);void 0!==a.vertexColors&&("face"=== a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));a.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),h.opacity=a.transparency);a.opacity&&(h.opacity=a.opacity);a.specularCoef&&(h.shininess=a.specularCoef);a.mapDiffuse&&b&&d(h,"map",a.mapDiffuse, @@ -264,13 +264,13 @@ a}};THREE.JSONLoader=function(a){THREE.Loader.call(this,a);this.withCredentials= THREE.JSONLoader.prototype.loadAjaxJSON=function(a,b,c,d,e){var f=new XMLHttpRequest,g=0;f.onreadystatechange=function(){if(f.readyState===f.DONE)if(200===f.status||0===f.status){if(f.responseText){var h=JSON.parse(f.responseText);if(void 0!==h.metadata&&4<=h.metadata.version){console.error('THREE.JSONLoader: "'+b+'" should be loaded with THREE.ObjectLoader instead.');return}if(void 0!==h.metadata&&"scene"===h.metadata.type){console.error('THREE.JSONLoader: "'+b+'" seems to be a Scene. Use THREE.SceneLoader instead.'); return}h=a.parse(h,d);c(h.geometry,h.materials)}else console.error('THREE.JSONLoader: "'+b+'" seems to be unreachable or the file is empty.');a.onLoadComplete()}else console.error("THREE.JSONLoader: Couldn't load \""+b+'" ('+f.status+")");else f.readyState===f.LOADING?e&&(0===g&&(g=f.getResponseHeader("Content-Length")),e({total:g,loaded:f.responseText.length})):f.readyState===f.HEADERS_RECEIVED&&void 0!==e&&(g=f.getResponseHeader("Content-Length"))};f.open("GET",b,!0);f.withCredentials=this.withCredentials; f.send(null)}; -THREE.JSONLoader.prototype.parse=function(a,b){var c=new THREE.Geometry,d=void 0!==a.scale?1/a.scale:1;(function(b){var d,g,h,k,n,p,q,m,t,s,r,u,v,y=a.faces;p=a.vertices;var E=a.normals,x=a.colors,O=0;if(void 0!==a.uvs){for(d=0;dg;g++)m=y[k++],v=u[2*m],m=u[2*m+1],v=new THREE.Vector2(v,m),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*y[k++],t.normal.set(E[q++],E[q++],E[q]),r.normal.copy(t.normal));if(s)for(d=0;4>d;d++)q=3*y[k++],s=new THREE.Vector3(E[q++], -E[q++],E[q]),2!==d&&t.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);p&&(p=y[k++],p=x[p],t.color.setHex(p),r.color.setHex(p));if(b)for(d=0;4>d;d++)p=y[k++],p=x[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&r.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(r)}else{t=new THREE.Face3;t.a=y[k++];t.b=y[k++];t.c=y[k++];h&&(h=y[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)m=y[k++],v=u[2*m],m=u[2*m+1], -v=new THREE.Vector2(v,m),c.faceVertexUvs[d][h].push(v);q&&(q=3*y[k++],t.normal.set(E[q++],E[q++],E[q]));if(s)for(d=0;3>d;d++)q=3*y[k++],s=new THREE.Vector3(E[q++],E[q++],E[q]),t.vertexNormals.push(s);p&&(p=y[k++],t.color.setHex(x[p]));if(b)for(d=0;3>d;d++)p=y[k++],t.vertexColors.push(new THREE.Color(x[p]));c.faces.push(t)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;dg;g++)m=x[k++],v=u[2*m],m=u[2*m+1],v=new THREE.Vector2(v,m),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]),r.normal.copy(s.normal));if(t)for(d=0;4>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++], +C[q++],C[q]),2!==d&&s.vertexNormals.push(t),0!==d&&r.vertexNormals.push(t);n&&(n=x[k++],n=w[n],s.color.setHex(n),r.color.setHex(n));if(b)for(d=0;4>d;d++)n=x[k++],n=w[n],2!==d&&s.vertexColors.push(new THREE.Color(n)),0!==d&&r.vertexColors.push(new THREE.Color(n));c.faces.push(s);c.faces.push(r)}else{s=new THREE.Face3;s.a=x[k++];s.b=x[k++];s.c=x[k++];h&&(h=x[k++],s.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)m=x[k++],v=u[2*m],m=u[2*m+1], +v=new THREE.Vector2(v,m),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]));if(t)for(d=0;3>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++],C[q++],C[q]),s.vertexNormals.push(t);n&&(n=x[k++],s.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=x[k++],s.vertexColors.push(new THREE.Color(w[n]));c.faces.push(s)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;df||(E=b.origin.distanceTo(p),Ed.far||e.push({distance:E,point:n.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, -object:this}))}}else for(m=m.position.array,g=0;gf||(E=b.origin.distanceTo(p),Ed.far||e.push({distance:E,point:n.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(E=b.origin.distanceTo(p),Ed.far||e.push({distance:E,point:n.clone().applyMatrix4(this.matrixWorld), +THREE.Line.prototype.raycast=function(){var a=new THREE.Matrix4,b=new THREE.Ray,c=new THREE.Sphere;return function(d,e){var f=d.linePrecision,f=f*f,g=this.geometry;null===g.boundingSphere&&g.computeBoundingSphere();c.copy(g.boundingSphere);c.applyMatrix4(this.matrixWorld);if(!1!==d.ray.isIntersectionSphere(c)){a.getInverse(this.matrixWorld);b.copy(d.ray).applyMatrix4(a);var h=new THREE.Vector3,k=new THREE.Vector3,p=new THREE.Vector3,n=new THREE.Vector3,q=this.mode===THREE.LineStrip?1:2;if(g instanceof +THREE.BufferGeometry){var m=g.attributes;if(void 0!==m.index){var s=m.index.array,m=m.position.array,t=g.offsets;0===t.length&&(t=[{start:0,count:s.length,index:0}]);for(var r=0;rf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, +object:this}))}}else for(m=m.position.array,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld), index:g,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(a){void 0===a&&(a=new THREE.Line(this.geometry,this.material,this.mode));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype); THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0g.far||h.push({distance:z,point:O,face:new THREE.Face3(p,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=p.position.array,s=k=0,x=r.length;k -g.far||h.push({distance:z,point:O,face:new THREE.Face3(p,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(s=this.material instanceof THREE.MeshFaceMaterial,r=!0===s?this.material.materials:null,t=g.precision,u=k.vertices,v=0,y=k.faces.length;vg.far||h.push({distance:z,point:O,face:E,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; +THREE.Mesh.prototype.raycast=function(){var a=new THREE.Matrix4,b=new THREE.Ray,c=new THREE.Sphere,d=new THREE.Vector3,e=new THREE.Vector3,f=new THREE.Vector3;return function(g,h){var k=this.geometry;null===k.boundingSphere&&k.computeBoundingSphere();c.copy(k.boundingSphere);c.applyMatrix4(this.matrixWorld);if(!1!==g.ray.isIntersectionSphere(c)&&(a.getInverse(this.matrixWorld),b.copy(g.ray).applyMatrix4(a),null===k.boundingBox||!1!==b.isIntersectionBox(k.boundingBox)))if(k instanceof THREE.BufferGeometry){var p= +this.material;if(void 0!==p){var n=k.attributes,q,m,s=g.precision;if(void 0!==n.index){var t=n.index.array,r=n.position.array,u=k.offsets;0===u.length&&(u=[{start:0,count:t.length,index:0}]);for(var v=0,x=u.length;vg.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=n.position.array,t=k=0,w=r.length;k +g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(t=this.material instanceof THREE.MeshFaceMaterial,r=!0===t?this.material.materials:null,s=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:C,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(this.boneTextureHeight=this.boneTextureWidth=a=256h&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(p={id:mc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:n},q[k]=p,r.push(p)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=r;b.groupsNeedUpdate=!1}f=kb[b.id];g=0;for(d=f.length;gW;W++)pa=N[W],Ua[Za]=pa.x,Ua[Za+1]=pa.y,Ua[Za+2]=pa.z,Za+=3;else for(W=0;3>W;W++)Ua[Za]=L.x,Ua[Za+1]=L.y,Ua[Za+2]=L.z,Za+=3;l.bindBuffer(l.ARRAY_BUFFER, -v.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Ua,z)}if(zb&&nb){w=0;for(A=Z.length;wW;W++)ya=S[W],Bb[Wa]=ya.x,Bb[Wa+1]=ya.y,Wa+=2;0W;W++)ta=P[W],rb[ma]=ta.x,rb[ma+1]=ta.y,ma+=2;0ua;ua++)ob[ua]=!I.autoScaleCubemaps||da||xb?xb?la.image[ua].image:la.image[ua]:K(la.image[ua],Gc);var Rb=ob[0],Ob=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height), -pb=N(la.format),Sb=N(la.type);B(l.TEXTURE_CUBE_MAP,la,Ob);for(ua=0;6>ua;ua++)if(da)for(var gb,Eb=ob[ua].mipmaps,yb=0,Yb=Eb.length;yb=sc&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Kb+=1;return a}function F(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function D(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a){a*=J;a!==tc&&(l.lineWidth(a), -tc=a)}function w(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function B(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,N(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,N(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,N(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,N(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&& -b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,T(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,T(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+ -b.sourceFile+" )"));(c=ca.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height); -console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function L(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, -l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function H(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function T(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? -l.NEAREST:l.LINEAR}function N(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a=== +!0}b.__webglCustomAttributesList.push(e)}}}function c(a,b){return a.material instanceof THREE.MeshFaceMaterial?a.material.materials[b.materialIndex]:a.material}function d(a,b,c,d){c=c.attributes;var e=b.attributes;b=b.attributesKeys;for(var h=0,k=b.length;hh&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(n={id:mc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m, +numMorphNormals:p},q[k]=n,s.push(n)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=s;b.groupsNeedUpdate=!1}f=ib[b.id];g=0;for(d=f.length;gV;V++)ra=M[V],Va[Ya]=ra.x,Va[Ya+1]=ra.y,Va[Ya+2]=ra.z,Ya+=3;else for(V=0;3>V;V++)Va[Ya]=Q.x,Va[Ya+1]=Q.y,Va[Ya+2]=Q.z,Ya+=3;l.bindBuffer(l.ARRAY_BUFFER, +u.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Va,C)}if(Bb&&lb){y=0;for(z=Y.length;yV;V++)na=T[V],Qa[rb]=na.x,Qa[rb+1]=na.y,rb+=2;0V;V++)cb=R[V],sb[xa]=cb.x,sb[xa+1]=cb.y,xa+=2;0ta;ta++)mb[ta]=!B.autoScaleCubemaps||ba||zb?zb?la.image[ta].image:la.image[ta]:M(la.image[ta],Gc);var Rb=mb[0],Ob=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height), +nb=T(la.format),Sb=T(la.type);z(l.TEXTURE_CUBE_MAP,la,Ob);for(ta=0;6>ta;ta++)if(ba)for(var fb,Eb=mb[ta].mipmaps,Ab=0,Yb=Eb.length;Ab=sc&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Kb+=1;return a}function A(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function F(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a){a*=Q;a!==tc&&(l.lineWidth(a), +tc=a)}function E(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function z(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,T(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,T(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,T(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,T(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&& +b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,L(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,L(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+ +b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height); +console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function J(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, +l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function K(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function L(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? +l.NEAREST:l.LINEAR}function T(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a=== THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT; if(a===THREE.FloatType)return l.FLOAT;if(a===THREE.AlphaFormat)return l.ALPHA;if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a=== THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE; -b=ca.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=ca.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; -if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=ca.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var V=void 0!==a.canvas?a.canvas:document.createElement("canvas"),R=void 0!==a.context?a.context:null,J=1,S=void 0!==a.precision?a.precision:"highp", -oa=void 0!==a.alpha?a.alpha:!1,aa=void 0!==a.depth?a.depth:!0,ta=void 0!==a.stencil?a.stencil:!0,P=void 0!==a.antialias?a.antialias:!1,Ca=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,pa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,Xa=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,U=new THREE.Color(0),Qa=0,xa=[],Ea={},Fa=[],Ra=[],Ga=[],eb=[],fb=[];this.domElement=V;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor= -this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var I=this,Wa=[],Wb=null,Ab=null,zb=-1,ma="",Fb=null,Kb=0,qb=-1,Nb=-1,Xb=-1,Ob=-1,Yb=-1,Zb=-1,ec=-1,fc=-1,gc= --1,hc=-1,ic=-1,uc=null,vc=null,wc=null,tc=null,hb=0,db=0,ib=V.width,Pa=V.height,xc=0,yc=0,jb=new Uint8Array(16),Da=new Uint8Array(16),tb=new THREE.Frustum,ub=new THREE.Matrix4;new THREE.Matrix4;var ya=new THREE.Vector3,na=new THREE.Vector3,Mb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[], -groundColors:[],positions:[]}},l;try{var zc={alpha:oa,depth:aa,stencil:ta,antialias:P,premultipliedAlpha:Ca,preserveDrawingBuffer:pa};l=R||V.getContext("webgl",zc)||V.getContext("experimental-webgl",zc);if(null===l){if(null!==V.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}V.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();Ea={}},!1)}catch(Hc){console.error(Hc)}void 0===l.getShaderPrecisionFormat&& -(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var ca=new THREE.WebGLExtensions(l);ca.get("OES_texture_float");ca.get("OES_texture_float_linear");ca.get("OES_standard_derivatives");Xa&&ca.get("EXT_frag_depth");var jc=function(a,b,c,d){!0===Ca&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND); -l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(hb,db,ib,Pa);jc(U.r,U.g,U.b,Qa)},Ac=function(){Fb=Wb=null;Nb=qb=ic=hc=Xb=-1;ma="";zb=-1;Mb=!0;for(var a=0;ab;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]), -l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}I.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), -c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&& -n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]= -l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);L(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: -l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),B(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER, -l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):L(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=ib,a=Pa,d=hb,e=db);b!==Ab&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),Ab=b);xc=c;yc=a};this.readRenderTargetPixels= -function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==Ab&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== -l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,Ab)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; +b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; +if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var P=void 0!==a.canvas?a.canvas:document.createElement("canvas"),N=void 0!==a.context?a.context:null,Q=1,U=void 0!==a.precision?a.precision:"highp", +I=void 0!==a.alpha?a.alpha:!1,na=void 0!==a.depth?a.depth:!0,ca=void 0!==a.stencil?a.stencil:!0,sa=void 0!==a.antialias?a.antialias:!1,R=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,xa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,ra=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ja=new THREE.Color(0),wa=0,ya=[],za={},La=[],Sa=[],Ra=[],Ea=[],qb=[];this.domElement=P;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor= +this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,cb=[],Wb=null,ob=null,Bb=-1,Ka="",Fb=null,Kb=0,pb=-1,Nb=-1,Xb=-1,Ob=-1,Yb=-1,Zb=-1,ec=-1,fc=-1,gc= +-1,hc=-1,ic=-1,uc=null,vc=null,wc=null,tc=null,gb=0,db=0,hb=P.width,Pa=P.height,xc=0,yc=0,ub=new Uint8Array(16),Qa=new Uint8Array(16),vb=new THREE.Frustum,wb=new THREE.Matrix4;new THREE.Matrix4;var Ca=new THREE.Vector3,ma=new THREE.Vector3,Mb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[], +groundColors:[],positions:[]}},l;try{var zc={alpha:I,depth:na,stencil:ca,antialias:sa,premultipliedAlpha:R,preserveDrawingBuffer:xa};l=N||P.getContext("webgl",zc)||P.getContext("experimental-webgl",zc);if(null===l){if(null!==P.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}P.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();za={}},!1)}catch(Hc){console.error(Hc)}void 0===l.getShaderPrecisionFormat&& +(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_standard_derivatives");ra&&aa.get("EXT_frag_depth");var jc=function(a,b,c,d){!0===R&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND); +l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(gb,db,hb,Pa);jc(ja.r,ja.g,ja.b,wa)},Ac=function(){Fb=Wb=null;Nb=pb=ic=hc=Xb=-1;Ka="";Bb=-1;Mb=!0;for(var a=0;a +b;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), +c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&& +n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]= +l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: +l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),z(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER, +l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=hb,a=Pa,d=gb,e=db);b!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),ob=b);xc=c;yc=a};this.readRenderTargetPixels= +function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== +l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,ob)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; @@ -573,64 +573,64 @@ THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:f a.shareDepthFrom=this.shareDepthFrom;return a},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube.prototype.constructor=THREE.WebGLRenderTargetCube; THREE.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c])return b[c];var d;switch(c){case "EXT_texture_filter_anisotropic":d=a.getExtension("EXT_texture_filter_anisotropic")||a.getExtension("MOZ_EXT_texture_filter_anisotropic")||a.getExtension("WEBKIT_EXT_texture_filter_anisotropic");break;case "WEBGL_compressed_texture_s3tc":d=a.getExtension("WEBGL_compressed_texture_s3tc")||a.getExtension("MOZ_WEBGL_compressed_texture_s3tc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc"); break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;default:d=a.getExtension(c)}null===d&&console.log("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}; -THREE.WebGLProgram=function(){var a=0;return function(b,c,d,e){var f=b.context,g=d.defines,h=d.__webglShader.uniforms,k=d.attributes,n=d.__webglShader.vertexShader,p=d.__webglShader.fragmentShader,q=d.index0AttributeName;void 0===q&&!0===e.morphTargets&&(q="position");var m="SHADOWMAP_TYPE_BASIC";e.shadowMapType===THREE.PCFShadowMap?m="SHADOWMAP_TYPE_PCF":e.shadowMapType===THREE.PCFSoftShadowMap&&(m="SHADOWMAP_TYPE_PCF_SOFT");var t="ENVMAP_TYPE_CUBE",s="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY"; -if(e.envMap){switch(d.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:t="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:t="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:t="ENVMAP_TYPE_SPHERE"}switch(d.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:s="ENVMAP_MODE_REFRACTION"}switch(d.combine){case THREE.MultiplyOperation:r="ENVMAP_BLENDING_MULTIPLY"; -break;case THREE.MixOperation:r="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:r="ENVMAP_BLENDING_ADD"}}var u=0T;T++)B[T]=new THREE.Vector3,A[T]=new THREE.Vector3;B=w.shadowCascadeNearZ[H];w=w.shadowCascadeFarZ[H];A[0].set(-1,-1,B);A[1].set(1,-1,B);A[2].set(-1,1,B);A[3].set(1,1,B);A[4].set(-1,-1,w);A[5].set(1,-1,w);A[6].set(-1,1,w);A[7].set(1,1,w);L.originalCamera=v;A=new THREE.Gyroscope;A.position.copy(z.shadowCascadeOffset);A.add(L);A.add(L.target);v.add(A);z.shadowCascadeArray[D]=L;console.log("Created virtualLight",L)}H= -z;B=D;w=H.shadowCascadeArray[B];w.position.copy(H.position);w.target.position.copy(H.target.position);w.lookAt(w.target);w.shadowCameraVisible=H.shadowCameraVisible;w.shadowDarkness=H.shadowDarkness;w.shadowBias=H.shadowCascadeBias[B];A=H.shadowCascadeNearZ[B];H=H.shadowCascadeFarZ[B];w=w.pointsFrustum;w[0].z=A;w[1].z=A;w[2].z=A;w[3].z=A;w[4].z=H;w[5].z=H;w[6].z=H;w[7].z=H;K[F]=L;F++}else K[F]=z,F++;u=0;for(O=K.length;uH;H++)B=w[H],B.copy(A[H]),B.unproject(D),B.applyMatrix4(F.matrixWorldInverse),B.xt.x&&(t.x=B.x),B.yt.y&&(t.y=B.y),B.zt.z&&(t.z=B.z);F.left=m.x;F.right=t.x;F.top=t.y;F.bottom=m.y;F.updateProjectionMatrix()}F=z.shadowMap;A=z.shadowMatrix;D=z.shadowCamera;D.position.setFromMatrixPosition(z.matrixWorld);s.setFromMatrixPosition(z.target.matrixWorld);D.lookAt(s);D.updateMatrixWorld();D.matrixWorldInverse.getInverse(D.matrixWorld);z.cameraHelper&& -(z.cameraHelper.visible=z.shadowCameraVisible);z.shadowCameraVisible&&z.cameraHelper.update();A.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);A.multiply(D.projectionMatrix);A.multiply(D.matrixWorldInverse);q.multiplyMatrices(D.projectionMatrix,D.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(F);a.clear();r.length=0;e(c,c,D);z=0;for(F=r.length;z 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); -x.compileShader(T);x.compileShader(N);x.attachShader(H,T);x.attachShader(H,N);x.linkProgram(H);F=H;v=x.getAttribLocation(F,"position");y=x.getAttribLocation(F,"uv");c=x.getUniformLocation(F,"uvOffset");d=x.getUniformLocation(F,"uvScale");e=x.getUniformLocation(F,"rotation");f=x.getUniformLocation(F,"scale");g=x.getUniformLocation(F,"color");h=x.getUniformLocation(F,"map");k=x.getUniformLocation(F,"opacity");n=x.getUniformLocation(F,"modelViewMatrix");p=x.getUniformLocation(F,"projectionMatrix");q= -x.getUniformLocation(F,"fogType");m=x.getUniformLocation(F,"fogDensity");t=x.getUniformLocation(F,"fogNear");s=x.getUniformLocation(F,"fogFar");r=x.getUniformLocation(F,"fogColor");u=x.getUniformLocation(F,"alphaTest");H=document.createElement("canvas");H.width=8;H.height=8;T=H.getContext("2d");T.fillStyle="white";T.fillRect(0,0,8,8);D=new THREE.Texture(H);D.needsUpdate=!0}x.useProgram(F);x.enableVertexAttribArray(v);x.enableVertexAttribArray(y);x.disable(x.CULL_FACE);x.enable(x.BLEND);x.bindBuffer(x.ARRAY_BUFFER, -O);x.vertexAttribPointer(v,2,x.FLOAT,!1,16,0);x.vertexAttribPointer(y,2,x.FLOAT,!1,16,8);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,z);x.uniformMatrix4fv(p,!1,L.projectionMatrix.elements);x.activeTexture(x.TEXTURE0);x.uniform1i(h,0);T=H=0;(N=K.fog)?(x.uniform3f(r,N.color.r,N.color.g,N.color.b),N instanceof THREE.Fog?(x.uniform1f(t,N.near),x.uniform1f(s,N.far),x.uniform1i(q,1),T=H=1):N instanceof THREE.FogExp2&&(x.uniform1f(m,N.density),x.uniform1i(q,2),T=H=2)):(x.uniform1i(q,0),T=H=0);for(var N=0,V=b.length;N< -V;N++){var R=b[N];R._modelViewMatrix.multiplyMatrices(L.matrixWorldInverse,R.matrixWorld);R.z=-R._modelViewMatrix.elements[14]}b.sort(E);for(var J=[],N=0,V=b.length;NT;T++)M[T]=new THREE.Vector3,E[T]=new THREE.Vector3;M=z.shadowCascadeNearZ[L];z=z.shadowCascadeFarZ[L];E[0].set(-1,-1,M);E[1].set(1,-1,M);E[2].set(-1,1,M);E[3].set(1,1,M);E[4].set(-1,-1,z);E[5].set(1,-1,z);E[6].set(-1,1,z);E[7].set(1,1,z);K.originalCamera=u;E=new THREE.Gyroscope;E.position.copy(A.shadowCascadeOffset);E.add(K);E.add(K.target);u.add(E);A.shadowCascadeArray[G]=K;console.log("Created virtualLight",K)}L= +A;M=G;z=L.shadowCascadeArray[M];z.position.copy(L.position);z.target.position.copy(L.target.position);z.lookAt(z.target);z.shadowCameraVisible=L.shadowCameraVisible;z.shadowDarkness=L.shadowDarkness;z.shadowBias=L.shadowCascadeBias[M];E=L.shadowCascadeNearZ[M];L=L.shadowCascadeFarZ[M];z=z.pointsFrustum;z[0].z=E;z[1].z=E;z[2].z=E;z[3].z=E;z[4].z=L;z[5].z=L;z[6].z=L;z[7].z=L;J[F]=K;F++}else J[F]=A,F++;v=0;for(y=J.length;vL;L++)M=z[L],M.copy(E[L]),M.unproject(G),M.applyMatrix4(F.matrixWorldInverse),M.xs.x&&(s.x=M.x),M.ys.y&&(s.y=M.y),M.zs.z&&(s.z=M.z);F.left=m.x;F.right=s.x;F.top=s.y;F.bottom=m.y;F.updateProjectionMatrix()}F=A.shadowMap;E=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);t.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(t);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& +(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();E.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);E.multiply(G.projectionMatrix);E.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);n.setFromMatrix(q);a.setRenderTarget(F);a.clear();r.length=0;e(c,c,G);A=0;for(F=r.length;A 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); +w.compileShader(T);w.compileShader(P);w.attachShader(L,T);w.attachShader(L,P);w.linkProgram(L);F=L;v=w.getAttribLocation(F,"position");x=w.getAttribLocation(F,"uv");c=w.getUniformLocation(F,"uvOffset");d=w.getUniformLocation(F,"uvScale");e=w.getUniformLocation(F,"rotation");f=w.getUniformLocation(F,"scale");g=w.getUniformLocation(F,"color");h=w.getUniformLocation(F,"map");k=w.getUniformLocation(F,"opacity");p=w.getUniformLocation(F,"modelViewMatrix");n=w.getUniformLocation(F,"projectionMatrix");q= +w.getUniformLocation(F,"fogType");m=w.getUniformLocation(F,"fogDensity");s=w.getUniformLocation(F,"fogNear");t=w.getUniformLocation(F,"fogFar");r=w.getUniformLocation(F,"fogColor");u=w.getUniformLocation(F,"alphaTest");L=document.createElement("canvas");L.width=8;L.height=8;T=L.getContext("2d");T.fillStyle="white";T.fillRect(0,0,8,8);G=new THREE.Texture(L);G.needsUpdate=!0}w.useProgram(F);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, +y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(n,!1,K.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);T=L=0;(P=J.fog)?(w.uniform3f(r,P.color.r,P.color.g,P.color.b),P instanceof THREE.Fog?(w.uniform1f(s,P.near),w.uniform1f(t,P.far),w.uniform1i(q,1),T=L=1):P instanceof THREE.FogExp2&&(w.uniform1f(m,P.density),w.uniform1i(q,2),T=L=2)):(w.uniform1i(q,0),T=L=0);for(var P=0,N=b.length;P< +N;P++){var Q=b[P];Q._modelViewMatrix.multiplyMatrices(K.matrixWorldInverse,Q.matrixWorld);Q.z=-Q._modelViewMatrix.elements[14]}b.sort(C);for(var U=[],P=0,N=b.length;Pq-1?0:q-1,t=q+1>e-1?e-1:q+1,s=0>p-1?0:p-1,r=p+1>d-1?d-1:p+1,u=[],v=[0,0,h[4*(q*d+p)]/255*b];u.push([-1,0,h[4*(q*d+s)]/255*b]);u.push([-1,-1,h[4*(m*d+s)]/255*b]);u.push([0,-1,h[4*(m*d+p)]/255*b]);u.push([1,-1,h[4*(m*d+r)]/255*b]);u.push([1,0,h[4*(q*d+r)]/255*b]);u.push([1,1,h[4*(t*d+r)]/255*b]);u.push([0,1,h[4*(t*d+p)]/255* -b]);u.push([-1,1,h[4*(t*d+s)]/255*b]);m=[];s=u.length;for(t=0;tq-1?0:q-1,s=q+1>e-1?e-1:q+1,t=0>n-1?0:n-1,r=n+1>d-1?d-1:n+1,u=[],v=[0,0,h[4*(q*d+n)]/255*b];u.push([-1,0,h[4*(q*d+t)]/255*b]);u.push([-1,-1,h[4*(m*d+t)]/255*b]);u.push([0,-1,h[4*(m*d+n)]/255*b]);u.push([1,-1,h[4*(m*d+r)]/255*b]);u.push([1,0,h[4*(q*d+r)]/255*b]);u.push([1,1,h[4*(s*d+r)]/255*b]);u.push([0,1,h[4*(s*d+n)]/255* +b]);u.push([-1,1,h[4*(s*d+t)]/255*b]);m=[];t=u.length;for(s=0;se)return null;var f=[],g=[],h=[],k,n,p;if(0=q--){console.log("Warning, unable to triangulate polygon!");break}k=n;e<=k&&(k=0);n=k+1;e<=n&&(n=0);p=n+1;e<=p&&(p=0);var m;a:{var t=m=void 0,s=void 0,r=void 0,u=void 0,v=void 0,y=void 0,E=void 0,x=void 0, -t=a[g[k]].x,s=a[g[k]].y,r=a[g[n]].x,u=a[g[n]].y,v=a[g[p]].x,y=a[g[p]].y;if(1E-10>(r-t)*(y-s)-(u-s)*(v-t))m=!1;else{var O=void 0,z=void 0,F=void 0,D=void 0,A=void 0,w=void 0,B=void 0,K=void 0,L=void 0,H=void 0,L=K=B=x=E=void 0,O=v-r,z=y-u,F=t-v,D=s-y,A=r-t,w=u-s;for(m=0;me)return null;var f=[],g=[],h=[],k,p,n;if(0=q--){console.log("Warning, unable to triangulate polygon!");break}k=p;e<=k&&(k=0);p=k+1;e<=p&&(p=0);n=p+1;e<=n&&(n=0);var m;a:{var s=m=void 0,t=void 0,r=void 0,u=void 0,v=void 0,x=void 0,C=void 0,w=void 0, +s=a[g[k]].x,t=a[g[k]].y,r=a[g[p]].x,u=a[g[p]].y,v=a[g[n]].x,x=a[g[n]].y;if(1E-10>(r-s)*(x-t)-(u-t)*(v-s))m=!1;else{var y=void 0,A=void 0,F=void 0,G=void 0,E=void 0,z=void 0,M=void 0,J=void 0,K=void 0,L=void 0,K=J=M=w=C=void 0,y=v-r,A=x-u,F=s-v,G=t-x,E=r-s,z=u-t;for(m=0;m=b)return b=c[a]-b,a=this.curves[a],b=1-b/a.getLength(),a.getPointAt(b);a++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]}; THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length==this.curves.length)return this.cacheLengths;var a=[],b=0,c,d=this.curves.length;for(c=0;cb?b=h.x:h.xc?c=h.y:h.yd?d=h.z:h.zb?b=h.x:h.xc?c=h.y:h.yd?d=h.z:h.zMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; +THREE.Path.prototype.getPoints=function(a,b){if(this.useSpacedPoints)return console.log("tata"),this.getSpacedPoints(a,b);a=a||12;var c=[],d,e,f,g,h,k,p,n,q,m,s,t,r;d=0;for(e=this.actions.length;dMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cm&&(g=b[f],k=-k,h=b[e],m=-m),!(a.yh.y))if(a.y==g.y){if(a.x==g.x)return!0}else{e=m*(a.x-g.x)-k*(a.y-g.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<= -h.x))return!0}return d}var e=function(a){var b,c,d,e,f=[],g=new THREE.Path;b=0;for(c=a.length;bD||D>F)return[];k=n*p-k*q;if(0>k||k>F)return[]}else{if(0d?[]:k==d?g?[]:[f]:a<=d?[f,h]: -[f,n]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]);if(!d)return!1; -d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;cH){console.log("Infinite Loop! Holes left:"+ -n.length+", Probably Hole outside Shape!");break}for(q=w;qh;h++)n=k[h].x+":"+k[h].y, -n=p[n],void 0!==n&&(k[h]=n);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a, +THREE.Shape.Utils={triangulateShape:function(a,b){function c(a,b,c){return a.x!=b.x?a.xG||G>F)return[];k=n*p-k*q;if(0>k||k>F)return[]}else{if(0d?[]:k==d?f?[]:[g]:a<=d?[g,h]: +[g,n]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]);if(!d)return!1; +d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;cL){console.log("Infinite Loop! Holes left:"+ +n.length+", Probably Hole outside Shape!");break}for(q=z;qh;h++)p=k[h].x+":"+k[h].y, +p=n[p],void 0!==p&&(k[h]=p);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a, b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)};THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()}; THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve;THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b=new THREE.Vector2;b.x=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);return b}; THREE.QuadraticBezierCurve.prototype.getTangent=function(a){var b=new THREE.Vector2;b.x=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.y,this.v1.y,this.v2.y);return b.normalize()};THREE.CubicBezierCurve=function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d};THREE.CubicBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.CubicBezierCurve.prototype.constructor=THREE.CubicBezierCurve; @@ -693,12 +693,12 @@ THREE.Animation.prototype.play=function(a,b){this.currentTime=void 0!==a?a:0;thi THREE.Animation.prototype.reset=function(){for(var a=0,b=this.hierarchy.length;ad;d++){for(var e=this.keyTypes[d],f=this.data.hierarchy[a].keys[0],g=this.getNextKeyWith(e,a,1);g.timef.index;)f=g,g=this.getNextKeyWith(e,a,g.index+1);c.prevKey[e]=f;c.nextKey[e]=g}}}; THREE.Animation.prototype.resetBlendWeights=function(){for(var a=0,b=this.hierarchy.length;aa.length-2?q:q+1;c[3]=q>a.length-3?q:q+2;q=a[c[0]];t=a[c[1]];s=a[c[2]];r=a[c[3]];c=e*e;m=e*c;d[0]=f(q[0],t[0],s[0],r[0],e,c,m);d[1]=f(q[1],t[1],s[1],r[1],e,c,m);d[2]=f(q[2],t[2],s[2],r[2],e,c,m);return d},f=function(a,b,c,d,e,f,m){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*m+ -(-3*(b-c)-2*a-d)*f+a*e+b};return function(f){if(!1!==this.isPlaying&&(this.currentTime+=f*this.timeScale,0!==this.weight)){f=this.data.length;if(this.currentTime>f||0>this.currentTime)this.loop?(this.currentTime%=f,0>this.currentTime&&(this.currentTime+=f),this.reset()):this.stop();f=0;for(var h=this.hierarchy.length;fq;q++){var m=this.keyTypes[q],t=n.prevKey[m],s=n.nextKey[m];if(0this.timeScale&&t.time>=this.currentTime){t=this.data.hierarchy[f].keys[0];for(s=this.getNextKeyWith(m,f,1);s.timet.index;)t=s,s=this.getNextKeyWith(m,f,s.index+1);n.prevKey[m]=t;n.nextKey[m]=s}var r=(this.currentTime-t.time)/(s.time-t.time),u=t[m],v=s[m];0>r&&(r=0);1a.length-2?q:q+1;c[3]=q>a.length-3?q:q+2;q=a[c[0]];s=a[c[1]];t=a[c[2]];r=a[c[3]];c=e*e;m=e*c;d[0]=f(q[0],s[0],t[0],r[0],e,c,m);d[1]=f(q[1],s[1],t[1],r[1],e,c,m);d[2]=f(q[2],s[2],t[2],r[2],e,c,m);return d},f=function(a,b,c,d,e,f,m){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*m+ +(-3*(b-c)-2*a-d)*f+a*e+b};return function(f){if(!1!==this.isPlaying&&(this.currentTime+=f*this.timeScale,0!==this.weight)){f=this.data.length;if(this.currentTime>f||0>this.currentTime)this.loop?(this.currentTime%=f,0>this.currentTime&&(this.currentTime+=f),this.reset()):this.stop();f=0;for(var h=this.hierarchy.length;fq;q++){var m=this.keyTypes[q],s=p.prevKey[m],t=p.nextKey[m];if(0this.timeScale&&s.time>=this.currentTime){s=this.data.hierarchy[f].keys[0];for(t=this.getNextKeyWith(m,f,1);t.times.index;)s=t,t=this.getNextKeyWith(m,f,t.index+1);p.prevKey[m]=s;p.nextKey[m]=t}var r=(this.currentTime-s.time)/(t.time-s.time),u=s[m],v=t[m];0>r&&(r=0);1=this.currentTime?f.interpolate(g,this.currentTime):f.inter THREE.KeyFrameAnimation.prototype.getPrevKeyWith=function(a,b,c){b=this.data.hierarchy[b].keys;for(c=0<=c?c:c+b.length;0<=c;c--)if(b[c].hasTarget(a))return b[c];return b[b.length-1]};THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);a=this.duration/this.frames;var b=Math.floor(this.currentTime/a);b!=this.currentFrame&&(this.mesh.morphTargetInfluences[this.lastFrame]=0,this.mesh.morphTargetInfluences[this.currentFrame]= 1,this.mesh.morphTargetInfluences[b]=0,this.lastFrame=this.currentFrame,this.currentFrame=b);this.mesh.morphTargetInfluences[b]=this.currentTime%a/a;this.mesh.morphTargetInfluences[this.lastFrame]=1-this.mesh.morphTargetInfluences[b]}}}; -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,r){var u,v=h.widthSegments,y=h.heightSegments,E=e/2,x=f/2,O=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",y=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",v=h.depthSegments;var z=v+1,F=y+1,D=e/v,A=f/y,w=new THREE.Vector3;w[u]=0=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)== -Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(P=a.length;0<=--P;){c=P;d=P-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;ed&&(d=a.length-1);for(var e=0,f=s+2*n,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;cc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5, -a.y));return a.clone()}THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,n=0,p=a.length;nt&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));n=0;for(p=this.vertices.length;nc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5, +a.y));return a.clone()}THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,p=0,n=a.length;ps&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));p=0;for(n=this.vertices.length;ps;s++){d[0]=t[g[s]];d[1]=t[g[(s+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1],face1:q,face2:void 0},p++):e[r].face2=q}d=new Float32Array(6*p);f=0;for(r in e)if(g=e[r],void 0===g.face2|| -.9999>k[g.face1].normal.dot(k[g.face2].normal))p=n[g.vert1],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z,p=n[g.vert2],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype);THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper; +THREE.EdgesHelper=function(a,b){var c=void 0!==b?b:16777215,d=[0,0],e={},f=function(a,b){return a-b},g=["a","b","c"],h=new THREE.BufferGeometry,k=a.geometry.clone();k.mergeVertices();k.computeFaceNormals();for(var p=k.vertices,k=k.faces,n=0,q=0,m=k.length;qt;t++){d[0]=s[g[t]];d[1]=s[g[(t+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1],face1:q,face2:void 0},n++):e[r].face2=q}d=new Float32Array(6*n);f=0;for(r in e)if(g=e[r],void 0===g.face2|| +.9999>k[g.face1].normal.dot(k[g.face2].normal))n=p[g.vert1],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z,n=p[g.vert2],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype);THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper; THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=new THREE.Geometry;c=0;for(var e=this.object.geometry.faces.length;cr;r++){d[0]=s[g[r]];d[1]=s[g[(r+1)%3]];d.sort(f);var u=d.toString();void 0===e[u]&&(q[2*p]=d[0],q[2*p+1]=d[1],e[u]=!0,p++)}d=new Float32Array(6*p);m=0;for(t=p;mr;r++)p= -k[q[2*m+r]],g=6*m+3*r,d[g+0]=p.x,d[g+1]=p.y,d[g+2]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3))}else if(a.geometry instanceof THREE.BufferGeometry){if(void 0!==a.geometry.attributes.index){k=a.geometry.attributes.position.array;t=a.geometry.attributes.index.array;n=a.geometry.drawcalls;p=0;0===n.length&&(n=[{count:t.length,index:0,start:0}]);for(var q=new Uint32Array(2*t.length),s=0,v=n.length;sr;r++)d[0]= -g+t[m+r],d[1]=g+t[m+(r+1)%3],d.sort(f),u=d.toString(),void 0===e[u]&&(q[2*p]=d[0],q[2*p+1]=d[1],e[u]=!0,p++);d=new Float32Array(6*p);m=0;for(t=p;mr;r++)g=6*m+3*r,p=3*q[2*m+r],d[g+0]=k[p],d[g+1]=k[p+1],d[g+2]=k[p+2]}else for(k=a.geometry.attributes.position.array,p=k.length/3,q=p/3,d=new Float32Array(6*p),m=0,t=q;mr;r++)g=18*m+6*r,q=9*m+3*r,d[g+0]=k[q],d[g+1]=k[q+1],d[g+2]=k[q+2],p=9*m+(r+1)%3*3,d[g+3]=k[p],d[g+4]=k[p+1],d[g+5]=k[p+2];h.addAttribute("position",new THREE.BufferAttribute(d, +THREE.WireframeHelper=function(a,b){var c=void 0!==b?b:16777215,d=[0,0],e={},f=function(a,b){return a-b},g=["a","b","c"],h=new THREE.BufferGeometry;if(a.geometry instanceof THREE.Geometry){for(var k=a.geometry.vertices,p=a.geometry.faces,n=0,q=new Uint32Array(6*p.length),m=0,s=p.length;mr;r++){d[0]=t[g[r]];d[1]=t[g[(r+1)%3]];d.sort(f);var u=d.toString();void 0===e[u]&&(q[2*n]=d[0],q[2*n+1]=d[1],e[u]=!0,n++)}d=new Float32Array(6*n);m=0;for(s=n;mr;r++)n= +k[q[2*m+r]],g=6*m+3*r,d[g+0]=n.x,d[g+1]=n.y,d[g+2]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3))}else if(a.geometry instanceof THREE.BufferGeometry){if(void 0!==a.geometry.attributes.index){k=a.geometry.attributes.position.array;s=a.geometry.attributes.index.array;p=a.geometry.drawcalls;n=0;0===p.length&&(p=[{count:s.length,index:0,start:0}]);for(var q=new Uint32Array(2*s.length),t=0,v=p.length;tr;r++)d[0]= +g+s[m+r],d[1]=g+s[m+(r+1)%3],d.sort(f),u=d.toString(),void 0===e[u]&&(q[2*n]=d[0],q[2*n+1]=d[1],e[u]=!0,n++);d=new Float32Array(6*n);m=0;for(s=n;mr;r++)g=6*m+3*r,n=3*q[2*m+r],d[g+0]=k[n],d[g+1]=k[n+1],d[g+2]=k[n+2]}else for(k=a.geometry.attributes.position.array,n=k.length/3,q=n/3,d=new Float32Array(6*n),m=0,s=q;mr;r++)g=18*m+6*r,q=9*m+3*r,d[g+0]=k[q],d[g+1]=k[q+1],d[g+2]=k[q+2],n=9*m+(r+1)%3*3,d[g+3]=k[n],d[g+4]=k[n+1],d[g+5]=k[n+2];h.addAttribute("position",new THREE.BufferAttribute(d, 3))}THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.WireframeHelper.prototype=Object.create(THREE.Line.prototype);THREE.WireframeHelper.prototype.constructor=THREE.WireframeHelper;THREE.ImmediateRenderObject=function(){THREE.Object3D.call(this);this.render=function(a){}};THREE.ImmediateRenderObject.prototype=Object.create(THREE.Object3D.prototype);THREE.ImmediateRenderObject.prototype.constructor=THREE.ImmediateRenderObject; THREE.MorphBlendMesh=function(a,b){THREE.Mesh.call(this,a,b);this.animationsMap={};this.animationsList=[];var c=this.geometry.morphTargets.length;this.createAnimation("__default",0,c-1,c/1);this.setAnimationWeight("__default",1)};THREE.MorphBlendMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.MorphBlendMesh.prototype.constructor=THREE.MorphBlendMesh; THREE.MorphBlendMesh.prototype.createAnimation=function(a,b,c,d){b={startFrame:b,endFrame:c,length:c-b+1,fps:d,duration:(c-b)/d,lastFrame:0,currentFrame:0,active:!1,time:0,direction:1,weight:1,directionBackwards:!1,mirroredLoop:!1};this.animationsMap[a]=b;this.animationsList.push(b)}; From 04c5e95ec53d265817ef3c9fb2ceba8c156cba83 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 30 Jan 2015 01:26:22 +0100 Subject: [PATCH 080/333] Fixed yet more examples. --- examples/js/ShaderDeferred.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/js/ShaderDeferred.js b/examples/js/ShaderDeferred.js index 1b2db5b8e1f9a3..336cca21167835 100644 --- a/examples/js/ShaderDeferred.js +++ b/examples/js/ShaderDeferred.js @@ -147,6 +147,7 @@ THREE.ShaderDeferred = { "uniform float wrapAround;", "uniform float additiveSpecular;", + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "color_pars_fragment" ], THREE.ShaderChunk[ "map_pars_fragment" ], THREE.ShaderChunk[ "lightmap_pars_fragment" ], @@ -169,7 +170,6 @@ THREE.ShaderDeferred = { "#endif", - THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "specularmap_pars_fragment" ], @@ -305,6 +305,7 @@ THREE.ShaderDeferred = { vertexShader : [ + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "map_pars_vertex" ], THREE.ShaderChunk[ "lightmap_pars_vertex" ], THREE.ShaderChunk[ "color_pars_vertex" ], From 3bbf2ad987c6cc6b94034cbc9d431aa339790e25 Mon Sep 17 00:00:00 2001 From: tsone Date: Fri, 30 Jan 2015 16:44:09 +0800 Subject: [PATCH 081/333] WebGLRenderer: Added support for half-float textures (OES_texture_half_float). --- docs/api/constants/Textures.html | 1 + docs/api/renderers/WebGLRenderTarget.html | 2 +- src/Three.js | 1 + src/renderers/WebGLRenderer.js | 18 +++++++++++++++++- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/api/constants/Textures.html b/docs/api/constants/Textures.html index 4bc5587aa7a5fc..f62109b263016c 100644 --- a/docs/api/constants/Textures.html +++ b/docs/api/constants/Textures.html @@ -49,6 +49,7 @@

Data Types

THREE.UnsignedShortType
THREE.IntType
THREE.UnsignedIntType
+ THREE.HalfFloatType
THREE.FloatType
diff --git a/docs/api/renderers/WebGLRenderTarget.html b/docs/api/renderers/WebGLRenderTarget.html index af53625acae21e..8f6403412af5db 100644 --- a/docs/api/renderers/WebGLRenderTarget.html +++ b/docs/api/renderers/WebGLRenderTarget.html @@ -69,7 +69,7 @@

[property:number format]

[property:number type]

- The default is THREE.UnsignedByteType. Other valid types (as WebGL allows) are THREE.ByteType, THREE.ShortType, THREE.UnsignedShortType, THREE.IntType, THREE.UnsignedIntType, THREE.FloatType, THREE.UnsignedShort4444Type, THREE.UnsignedShort5551Type, and THREE.UnsignedShort565Type. + The default is THREE.UnsignedByteType. Other valid types (as WebGL allows) are THREE.ByteType, THREE.ShortType, THREE.UnsignedShortType, THREE.IntType, THREE.UnsignedIntType, THREE.HalfFloatType, THREE.FloatType, THREE.UnsignedShort4444Type, THREE.UnsignedShort5551Type, and THREE.UnsignedShort565Type.

[property:boolean depthBuffer]

diff --git a/src/Three.js b/src/Three.js index 632e7d3c47fb41..d52f9e0abe0017 100644 --- a/src/Three.js +++ b/src/Three.js @@ -149,6 +149,7 @@ THREE.UnsignedShortType = 1012; THREE.IntType = 1013; THREE.UnsignedIntType = 1014; THREE.FloatType = 1015; +THREE.HalfFloatType = 1025; // Pixel types diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 6422aa51ef411d..4d3764d6053db6 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -244,6 +244,8 @@ THREE.WebGLRenderer = function ( parameters ) { extensions.get( 'OES_texture_float' ); extensions.get( 'OES_texture_float_linear' ); + extensions.get( 'OES_texture_half_float' ); + extensions.get( 'OES_texture_half_float_linear' ); extensions.get( 'OES_standard_derivatives' ); if ( _logarithmicDepthBuffer ) { @@ -429,6 +431,12 @@ THREE.WebGLRenderer = function ( parameters ) { }; + this.supportsHalfFloatTextures = function () { + + return extensions.get( 'OES_texture_half_float' ); + + }; + this.supportsStandardDerivatives = function () { return extensions.get( 'OES_standard_derivatives' ); @@ -5661,7 +5669,7 @@ THREE.WebGLRenderer = function ( parameters ) { extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - if ( extension && texture.type !== THREE.FloatType ) { + if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) { if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) { @@ -6246,6 +6254,14 @@ THREE.WebGLRenderer = function ( parameters ) { if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT; if ( p === THREE.FloatType ) return _gl.FLOAT; + extension = extensions.get( 'OES_texture_half_float' ); + + if ( extension !== null ) { + + if ( p === THREE.HalfFloatType ) return extension.HALF_FLOAT_OES; + + } + if ( p === THREE.AlphaFormat ) return _gl.ALPHA; if ( p === THREE.RGBFormat ) return _gl.RGB; if ( p === THREE.RGBAFormat ) return _gl.RGBA; From 9520cb4522cfc4fb9f4cef7910fffacb464a5dba Mon Sep 17 00:00:00 2001 From: tsone Date: Fri, 30 Jan 2015 16:46:35 +0800 Subject: [PATCH 082/333] examples: webgl_shaders_ocean2: Added option to use half-float for simulation framebuffers. --- examples/js/Ocean.js | 7 +++-- examples/webgl_shaders_ocean2.html | 45 ++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/examples/js/Ocean.js b/examples/js/Ocean.js index efbbafe676af20..3a28ed5ecc12e8 100644 --- a/examples/js/Ocean.js +++ b/examples/js/Ocean.js @@ -41,6 +41,7 @@ this.matrixNeedsUpdate = false; // Setup framebuffer pipeline + var renderTargetType = optionalParameter(options.USE_HALF_FLOAT, false) ? THREE.HalfFloatType : THREE.FloatType; var LinearClampParams = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, @@ -50,7 +51,7 @@ stencilBuffer: false, depthBuffer: false, premultiplyAlpha: false, - type: THREE.FloatType + type: renderTargetType }; var NearestClampParams = { minFilter: THREE.NearestFilter, @@ -61,7 +62,7 @@ stencilBuffer: false, depthBuffer: false, premultiplyAlpha:false, - type: THREE.FloatType + type: renderTargetType }; var NearestRepeatParams = { minFilter: THREE.NearestFilter, @@ -72,7 +73,7 @@ stencilBuffer: false, depthBuffer: false, premultiplyAlpha: false, - type: THREE.FloatType + type: renderTargetType }; this.initialSpectrumFramebuffer = new THREE.WebGLRenderTarget(this.resolution, this.resolution, NearestRepeatParams); this.spectrumFramebuffer = new THREE.WebGLRenderTarget(this.resolution, this.resolution, NearestClampParams); diff --git a/examples/webgl_shaders_ocean2.html b/examples/webgl_shaders_ocean2.html index dcd1806d6041bd..02e294f875941b 100644 --- a/examples/webgl_shaders_ocean2.html +++ b/examples/webgl_shaders_ocean2.html @@ -7,20 +7,50 @@ body { margin: 0px; overflow: hidden; + font-family: Monospace; + text-align: center; } + #info { + color: #fff; + position: absolute; + top: 10px; + width: 100%; + } + a { + color: #09f; + } + #type-status { + font-weight: bold; + } + #stats { position: absolute; top:0; left: 0 } +
+ three.js - webgl ocean simulation
+ current simulation framebuffers type is
+ change type to +
+ - - - - -

[name]

- -
Euler Angles.

- - Euler angles describe a rotation transformation by rotating an object on its various axes in specified amounts per axis, and a specified axis order. - (More information on Wikipedia)
- -

Example

- - var a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); - var b = new THREE.Vector3( 1, 0, 1 ); - b.applyEuler(a); - - - -

Constructor

- - -

[name]( [page:Float x], [page:Float y], [page:Float z], [page:String order] )

-
- x -- [page:Float] the angle of the x axis in radians
- y -- [page:Float] the angle of the y axis in radians
- z -- [page:Float] the angle of the z axis in radians
- order -- [page:String] A string representing the order that the rotations are applied, defaults to 'XYZ' (must be upper case). -
-
- A euler angle for transforming -
- - -

Properties

- -

[property:Float x]

- -

[property:Float y]

- -

[property:Float z]

- -

[property:String order]

- - - -

Methods

- -

[method:Euler set]( [page:Float x], [page:Float y], [page:Float z], [page:String order] ) [page:Euler this]

-
- x -- [page:Float] Angle in x axis in radians
- y -- [page:Float] Angle in y axis in radians
- z -- [page:Float] Angle in z axis in radians
- order -- [page:string] Order of axes, defaults to 'XYZ' (must be upper case) -
-
- Sets the angles of this euler transform. -
- -

[method:Euler copy]( [page:Euler euler] ) [page:Euler this]

-
- Copies value of *euler* to this euler. -
- -

[method:Euler setFromRotationMatrix]( [page:Matrix4 m], [page:String order] ) [page:Euler this]

-
- m -- [page:Matrix4] assumes upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled)
- order -- [page:string] Order of axes, defaults to 'XYZ' (must be upper case) -
-
- Sets the angles of this euler transform from a pure rotation matrix based on the orientation specified by order. -
- -

[method:Euler setFromQuaternion]( [page:Quaternion q], [page:String order] ) [page:Euler this]

-
- q -- [page:Quaternion] quaternion must be normalized
- order -- [page:string] Order of axes, defaults to 'XYZ' (must be upper case) -
-
- Sets the angles of this euler transform from a normalized quaternion based on the orientation specified by order. -
- -

[method:Euler reorder]( [page:String newOrder] ) [page:Euler this]

-
- Resets the euler angle with a new order by creating a quaternion from this euler angle and then setting this euler angle with the quaternion and the new order.
- WARNING: this discards revolution information. -
- -

[method:Euler setFromVector3]([page:Vector3 vector], [page:String order]) [page:Euler this]

-
- vector -- [page:Vector3]. - order -- [page:string] Order of axes, defaults to 'XYZ' (must be upper case) -
-
- Optionally Vector3 to the XYZ parameters of Euler, and order to the Euler's order property. -
- -

[method:Vector3 toVector3]()

-
- Returns the Euler's XYZ properties as a Vector3. -
- -

[method:Euler fromArray]([page:Array array]) [page:Euler this]

-
- array -- [page:Array] of length 3 or 4. array[3] is an optional order argument. -
-
- Assigns this euler's x angle to array[0].
- Assigns this euler's y angle to array[1].
- Assigns this euler's z angle to array[2].
- Optionally assigns this euler's order to array[3]. -
- -

[method:Array toArray]()

-
- Returns an array [x, y, z, order]. -
- -

[method:Boolean equals]( [page:Euler euler] )

-
- Checks for strict equality of this euler and *euler*. -
- -

[method:Euler clone]()

-
- Returns a new euler created from this euler. -
- - - - -

Source

- - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] - + + + + + + + +

[name]

+ +
Euler Angles.

+ + Euler angles describe a rotation transformation by rotating an object on its various axes in specified amounts per axis, and a specified axis order. + (More information on Wikipedia)
+ +

Example

+ + var a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); + var b = new THREE.Vector3( 1, 0, 1 ); + b.applyEuler(a); + + + +

Constructor

+ + +

[name]( [page:Float x], [page:Float y], [page:Float z], [page:String order] )

+
+ x -- [page:Float] the angle of the x axis in radians
+ y -- [page:Float] the angle of the y axis in radians
+ z -- [page:Float] the angle of the z axis in radians
+ order -- [page:String] A string representing the order that the rotations are applied, defaults to 'XYZ' (must be upper case). +
+
+ A euler angle for transforming +
+ + +

Properties

+ +

[property:Float x]

+ +

[property:Float y]

+ +

[property:Float z]

+ +

[property:String order]

+ + + +

Methods

+ +

[method:Euler set]( [page:Float x], [page:Float y], [page:Float z], [page:String order] ) [page:Euler this]

+
+ x -- [page:Float] Angle in x axis in radians
+ y -- [page:Float] Angle in y axis in radians
+ z -- [page:Float] Angle in z axis in radians
+ order -- [page:string] Order of axes, defaults to 'XYZ' (must be upper case) +
+
+ Sets the angles of this euler transform. +
+ +

[method:Euler copy]( [page:Euler euler] ) [page:Euler this]

+
+ Copies value of *euler* to this euler. +
+ +

[method:Euler setFromRotationMatrix]( [page:Matrix4 m], [page:String order] ) [page:Euler this]

+
+ m -- [page:Matrix4] assumes upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled)
+ order -- [page:string] Order of axes, defaults to 'XYZ' (must be upper case) +
+
+ Sets the angles of this euler transform from a pure rotation matrix based on the orientation specified by order. +
+ +

[method:Euler setFromQuaternion]( [page:Quaternion q], [page:String order] ) [page:Euler this]

+
+ q -- [page:Quaternion] quaternion must be normalized
+ order -- [page:string] Order of axes, defaults to 'XYZ' (must be upper case) +
+
+ Sets the angles of this euler transform from a normalized quaternion based on the orientation specified by order. +
+ +

[method:Euler reorder]( [page:String newOrder] ) [page:Euler this]

+
+ Resets the euler angle with a new order by creating a quaternion from this euler angle and then setting this euler angle with the quaternion and the new order.
+ WARNING: this discards revolution information. +
+ +

[method:Euler setFromVector3]([page:Vector3 vector], [page:String order]) [page:Euler this]

+
+ vector -- [page:Vector3]. + order -- [page:string] Order of axes, defaults to 'XYZ' (must be upper case) +
+
+ Optionally Vector3 to the XYZ parameters of Euler, and order to the Euler's order property. +
+ +

[method:Vector3 toVector3]()

+
+ Returns the Euler's XYZ properties as a Vector3. +
+ +

[method:Euler fromArray]([page:Array array]) [page:Euler this]

+
+ array -- [page:Array] of length 3 or 4. array[3] is an optional order argument. +
+
+ Assigns this euler's x angle to array[0].
+ Assigns this euler's y angle to array[1].
+ Assigns this euler's z angle to array[2].
+ Optionally assigns this euler's order to array[3]. +
+ +

[method:Array toArray]( [page:Array array] )

+
+ array -- Optional array to store the euler. +
+
+ Returns an array [x, y, z, order] +
+ +

[method:Boolean equals]( [page:Euler euler] )

+
+ Checks for strict equality of this euler and *euler*. +
+ +

[method:Euler clone]()

+
+ Returns a new euler created from this euler. +
+ + + + +

Source

+ + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] + diff --git a/docs/api/math/Quaternion.html b/docs/api/math/Quaternion.html index 139194281fa13e..25735bfbe00454 100644 --- a/docs/api/math/Quaternion.html +++ b/docs/api/math/Quaternion.html @@ -131,15 +131,18 @@

[method:Quaternion slerp]( [page:Quaternion qa], [page:Quaternion qb], [page

[method:Quaternion slerp]([page:Quaternion qb], [page:float t])

qb -- Target quaternion rotation.
- t -- Normalized [0..1] interpolation factor. + t -- Normalized [0..1] interpolation factor.
Handles the spherical linear interpolation between this quaternion's configuration - and that of *qb*. *t* represents how close to the current (0) or target (1) rotation the - result should be. + and that of *qb*. *t* represents how close to the current (0) or target (1) rotation the + result should be.
-

.toArray() [page: Array]

+

[method:Array toArray]( [page:Array array] )

+
+ array -- Array to store the quaternion. +
Returns the numerical elements of this quaternion in an array of format (x, y, z, w).
@@ -155,7 +158,7 @@

[method:Boolean equals]([page:Quaternion v])

[method:Float lengthSq]()

- Calculates the squared length of the quaternion. + Calculates the squared length of the quaternion.

[method:Quaternion fromArray]([page:Array array])

diff --git a/docs/api/math/Vector2.html b/docs/api/math/Vector2.html index c09dec2c3049bf..f1bdc572cbf509 100644 --- a/docs/api/math/Vector2.html +++ b/docs/api/math/Vector2.html @@ -226,7 +226,10 @@

[method:Vector2 fromArray]([page:Array array]) [page:Vector2 this]

Sets this vector's x value to be array[0] and y value to be array[1]. -

[method:Array toArray]()

+

[method:Array toArray]( [page:Array array] )

+
+ array -- Optional array to store the vector. +
Returns an array [x, y].
diff --git a/docs/api/math/Vector3.html b/docs/api/math/Vector3.html index 0f5738b3d886a3..bc2d47a0770851 100644 --- a/docs/api/math/Vector3.html +++ b/docs/api/math/Vector3.html @@ -401,7 +401,10 @@

[method:Vector3 applyProjection]([page:Matrix4 m]) [page:Vector3 this]

Multiplies this vector and m, and divides by perspective. -

[method:Array toArray]()

+

[method:Array toArray]( [page:Array array] )

+
+ array -- Optional array to store the vector. +
Assigns this vector's x value to array[0].
Assigns this vector's y value to array[1].
diff --git a/docs/api/math/Vector4.html b/docs/api/math/Vector4.html index 5d0733cf82bbaf..a874c8964a2c70 100644 --- a/docs/api/math/Vector4.html +++ b/docs/api/math/Vector4.html @@ -186,7 +186,7 @@

[method:Vector4 max]([page:Vector4 v]) [page:Vector4 this]

v -- [page:Vector4]
- If this vector's x, y, z, or w value is greater than vector v's x, y, z, or w value, that value is replaced by the corresponding vector v value. + If this vector's x, y, z, or w value is greater than vector v's x, y, z, or w value, that value is replaced by the corresponding vector v value.

[method:Vector4 addScalar]([page:Float s]) [page:Vector4 this]

@@ -204,7 +204,7 @@

[method:Boolean equals]([page:Vector4 v])

Checks to see if this vector matches vector v.
- +

[method:Vector4 setAxisAngleFromRotationMatrix]([page:Matrix4 m]) [page:Vector4 this]

m -- [page:Matrix4] @@ -236,7 +236,7 @@

[method:Float getComponent]([page:Integer index])

Index 1: y
Index 2: z
Index 3: w
- +

[method:null setComponent]([page:Integer index], [page:Float value])

@@ -246,13 +246,13 @@

[method:null setComponent]([page:Integer index], [page:Float value])

Sets the value of the vector component x, y, or z by an index.

- + Index 0: x
Index 1: y
Index 2: z
Index 3: w
- +

[method:Vector4 fromArray]([page:Array array]) [page:Vector4 this]

array -- [page:Array] An array formatted [x, y, z, w] @@ -261,7 +261,10 @@

[method:Vector4 fromArray]([page:Array array]) [page:Vector4 this]

Sets the vector's components based on an array formatted like [x, y, z, w]
-

[method:Array toArray]()

+

[method:Array toArray]( [page:Array array] )

+
+ array -- Optional array to store the vector. +
Returns an array in the format [x, y, z, w]
From ae8f7595bd3a8d1526f5303810c447dc713c886b Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 2 Feb 2015 17:54:06 -0800 Subject: [PATCH 089/333] Simplified OrbitControls header. See 6f7299cd8f5d19ca0b0df8a7cedac2ef2be1382c. --- examples/js/controls/OrbitControls.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/js/controls/OrbitControls.js b/examples/js/controls/OrbitControls.js index 142459fbd2a16c..def12ad84f0615 100644 --- a/examples/js/controls/OrbitControls.js +++ b/examples/js/controls/OrbitControls.js @@ -14,12 +14,6 @@ // Orbit - left mouse / touch: one finger move // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish // Pan - right mouse, or arrow keys / touch: three finter swipe -// -// This is a drop-in replacement for (most) TrackballControls used in examples. -// That is, include this js file and wherever you see: -// controls = new THREE.OrbitControls( camera ); -// controls.target.z = 150; -// Simple substitute "OrbitControls" and the control should work as-is. THREE.OrbitControls = function ( object, domElement ) { From 6551bbaca7c8c6d5601a549661991f8b73649ffe Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 2 Feb 2015 19:18:11 -0800 Subject: [PATCH 090/333] Editor: Improved outliner. Dragging a parent as a child of a child breaks things though :( --- editor/js/Editor.js | 10 ++++++---- editor/js/libs/ui.three.js | 12 ++++++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/editor/js/Editor.js b/editor/js/Editor.js index 75c20b6f5770ca..f2cf486c4f6534 100644 --- a/editor/js/Editor.js +++ b/editor/js/Editor.js @@ -319,7 +319,7 @@ Editor.prototype = { // - parent: function ( object, parent, after ) { + parent: function ( object, parent, before ) { if ( parent === undefined ) { @@ -329,10 +329,12 @@ Editor.prototype = { parent.add( object ); - if ( after !== undefined ) { + // sort children array - var index = parent.children.indexOf( after ); - parent.children.splice( index + 1, 0, object ); + if ( before !== undefined ) { + + var index = parent.children.indexOf( before ); + parent.children.splice( index, 0, object ); parent.children.pop(); } diff --git a/editor/js/libs/ui.three.js b/editor/js/libs/ui.three.js index 71cea8cfdfef21..a5a7b3272c6fcb 100644 --- a/editor/js/libs/ui.three.js +++ b/editor/js/libs/ui.three.js @@ -155,9 +155,17 @@ UI.Outliner = function ( editor ) { var item = event.item; var object = scene.getObjectById( item.value ); - var prevObject = scene.getObjectById( item.previousSibling.value ); - editor.parent( object, prevObject.parent, prevObject ); + if ( item.nextSibling === null ) { + + editor.parent( object, editor.scene ); + + } else { + + var nextObject = scene.getObjectById( item.nextSibling.value ); + editor.parent( object, nextObject.parent, nextObject ); + + } } } ); From d3be2c6443b53a9c85db10df60781e7887f14536 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 2 Feb 2015 19:36:45 -0800 Subject: [PATCH 091/333] Updated builds. --- build/three.js | 22 +++++- build/three.min.js | 192 ++++++++++++++++++++++----------------------- 2 files changed, 114 insertions(+), 100 deletions(-) diff --git a/build/three.js b/build/three.js index 92cb48568ac8fc..4e159f1a99b770 100644 --- a/build/three.js +++ b/build/three.js @@ -151,6 +151,7 @@ THREE.UnsignedShortType = 1012; THREE.IntType = 1013; THREE.UnsignedIntType = 1014; THREE.FloatType = 1015; +THREE.HalfFloatType = 1025; // Pixel types @@ -17757,6 +17758,8 @@ THREE.WebGLRenderer = function ( parameters ) { extensions.get( 'OES_texture_float' ); extensions.get( 'OES_texture_float_linear' ); + extensions.get( 'OES_texture_half_float' ); + extensions.get( 'OES_texture_half_float_linear' ); extensions.get( 'OES_standard_derivatives' ); if ( _logarithmicDepthBuffer ) { @@ -17942,6 +17945,12 @@ THREE.WebGLRenderer = function ( parameters ) { }; + this.supportsHalfFloatTextures = function () { + + return extensions.get( 'OES_texture_half_float' ); + + }; + this.supportsStandardDerivatives = function () { return extensions.get( 'OES_standard_derivatives' ); @@ -23174,7 +23183,7 @@ THREE.WebGLRenderer = function ( parameters ) { extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - if ( extension && texture.type !== THREE.FloatType ) { + if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) { if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) { @@ -23759,6 +23768,14 @@ THREE.WebGLRenderer = function ( parameters ) { if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT; if ( p === THREE.FloatType ) return _gl.FLOAT; + extension = extensions.get( 'OES_texture_half_float' ); + + if ( extension !== null ) { + + if ( p === THREE.HalfFloatType ) return extension.HALF_FLOAT_OES; + + } + if ( p === THREE.AlphaFormat ) return _gl.ALPHA; if ( p === THREE.RGBFormat ) return _gl.RGB; if ( p === THREE.RGBAFormat ) return _gl.RGBA; @@ -27053,12 +27070,10 @@ THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) { if ( comparison < 0 ) { low = i + 1; - continue; } else if ( comparison > 0 ) { high = i - 1; - continue; } else { @@ -27282,7 +27297,6 @@ THREE.CurvePath.prototype.getPoint = function( t ) { return curve.getPointAt( u ); - break; } i ++; diff --git a/build/three.min.js b/build/three.min.js index f37fc0b0344a83..58ac2b4e9ac3b2 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -2,8 +2,8 @@ 'use strict';var THREE={REVISION:"71dev"};"object"===typeof module&&(module.exports=THREE);void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){if(0===b)this.r=this.g=this.b=c;else{var d=function(a,b,c){0>c&&(c+=1);1h&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(n={id:mc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m, +h=$.get("OES_element_index_uint")?4294967296:65535,k,e={},m=b.morphTargets.length,p=b.morphNormals.length,n,q={},s=[],t=0,u=b.faces.length;th&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(n={id:mc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m, numMorphNormals:p},q[k]=n,s.push(n)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=s;b.groupsNeedUpdate=!1}f=ib[b.id];g=0;for(d=f.length;gV;V++)ra=M[V],Va[Ya]=ra.x,Va[Ya+1]=ra.y,Va[Ya+2]=ra.z,Ya+=3;else for(V=0;3>V;V++)Va[Ya]=Q.x,Va[Ya+1]=Q.y,Va[Ya+2]=Q.z,Ya+=3;l.bindBuffer(l.ARRAY_BUFFER, -u.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Va,C)}if(Bb&&lb){y=0;for(z=Y.length;yV;V++)na=T[V],Qa[rb]=na.x,Qa[rb+1]=na.y,rb+=2;0V;V++)cb=R[V],sb[xa]=cb.x,sb[xa+1]=cb.y,xa+=2;0V;V++)ra=M[V],Va[Ya]=ra.x,Va[Ya+1]=ra.y,Va[Ya+2]=ra.z,Ya+=3;else for(V=0;3>V;V++)Va[Ya]=Q.x,Va[Ya+1]= +Q.y,Va[Ya+2]=Q.z,Ya+=3;l.bindBuffer(l.ARRAY_BUFFER,u.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Va,C)}if(Bb&&lb){y=0;for(z=Y.length;yV;V++)na=T[V],Ra[rb]=na.x,Ra[rb+1]=na.y,rb+=2;0V;V++)cb=R[V],sb[xa]=cb.x,sb[xa+1]=cb.y,xa+=2;0=sc&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Kb+=1;return a}function A(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function F(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a){a*=Q;a!==tc&&(l.lineWidth(a), tc=a)}function E(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function z(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,T(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,T(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,T(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,T(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&& b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,L(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,L(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+ -b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height); -console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function J(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, +b.sourceFile+" )"));(c=$.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height, +0,0,d.width,d.height);console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function J(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function K(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function L(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? l.NEAREST:l.LINEAR}function T(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a=== THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT; -if(a===THREE.FloatType)return l.FLOAT;if(a===THREE.AlphaFormat)return l.ALPHA;if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a=== -THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE; -b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; -if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var P=void 0!==a.canvas?a.canvas:document.createElement("canvas"),N=void 0!==a.context?a.context:null,Q=1,U=void 0!==a.precision?a.precision:"highp", -I=void 0!==a.alpha?a.alpha:!1,na=void 0!==a.depth?a.depth:!0,ca=void 0!==a.stencil?a.stencil:!0,sa=void 0!==a.antialias?a.antialias:!1,R=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,xa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,ra=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ja=new THREE.Color(0),wa=0,ya=[],za={},La=[],Sa=[],Ra=[],Ea=[],qb=[];this.domElement=P;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor= -this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,cb=[],Wb=null,ob=null,Bb=-1,Ka="",Fb=null,Kb=0,pb=-1,Nb=-1,Xb=-1,Ob=-1,Yb=-1,Zb=-1,ec=-1,fc=-1,gc= --1,hc=-1,ic=-1,uc=null,vc=null,wc=null,tc=null,gb=0,db=0,hb=P.width,Pa=P.height,xc=0,yc=0,ub=new Uint8Array(16),Qa=new Uint8Array(16),vb=new THREE.Frustum,wb=new THREE.Matrix4;new THREE.Matrix4;var Ca=new THREE.Vector3,ma=new THREE.Vector3,Mb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[], -groundColors:[],positions:[]}},l;try{var zc={alpha:I,depth:na,stencil:ca,antialias:sa,premultipliedAlpha:R,preserveDrawingBuffer:xa};l=N||P.getContext("webgl",zc)||P.getContext("experimental-webgl",zc);if(null===l){if(null!==P.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}P.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();za={}},!1)}catch(Hc){console.error(Hc)}void 0===l.getShaderPrecisionFormat&& -(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_standard_derivatives");ra&&aa.get("EXT_frag_depth");var jc=function(a,b,c,d){!0===R&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND); -l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(gb,db,hb,Pa);jc(ja.r,ja.g,ja.b,wa)},Ac=function(){Fb=Wb=null;Nb=pb=ic=hc=Xb=-1;Ka="";Bb=-1;Mb=!0;for(var a=0;a -b;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), -c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&& -n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]= -l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: -l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),z(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER, -l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=hb,a=Pa,d=gb,e=db);b!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),ob=b);xc=c;yc=a};this.readRenderTargetPixels= -function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== -l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,ob)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; -this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +if(a===THREE.FloatType)return l.FLOAT;b=$.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return l.ALPHA;if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT; +if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a===THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR; +if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE;b=$.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=$.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; +if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=$.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var P=void 0!==a.canvas?a.canvas:document.createElement("canvas"),N=void 0!== +a.context?a.context:null,Q=1,U=void 0!==a.precision?a.precision:"highp",I=void 0!==a.alpha?a.alpha:!1,na=void 0!==a.depth?a.depth:!0,ca=void 0!==a.stencil?a.stencil:!0,sa=void 0!==a.antialias?a.antialias:!1,R=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,xa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,ra=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ja=new THREE.Color(0),wa=0,ya=[],za={},Ma=[],Fa=[],Sa=[],Ea=[],qb=[];this.domElement=P;this.context=null;this.sortObjects= +this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,cb=[],Wb=null,ob=null,Bb=-1,La="", +Fb=null,Kb=0,pb=-1,Nb=-1,Xb=-1,Ob=-1,Yb=-1,Zb=-1,ec=-1,fc=-1,gc=-1,hc=-1,ic=-1,uc=null,vc=null,wc=null,tc=null,gb=0,db=0,hb=P.width,Qa=P.height,xc=0,yc=0,ub=new Uint8Array(16),Ra=new Uint8Array(16),vb=new THREE.Frustum,wb=new THREE.Matrix4;new THREE.Matrix4;var Ca=new THREE.Vector3,ma=new THREE.Vector3,Mb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[], +anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},l;try{var zc={alpha:I,depth:na,stencil:ca,antialias:sa,premultipliedAlpha:R,preserveDrawingBuffer:xa};l=N||P.getContext("webgl",zc)||P.getContext("experimental-webgl",zc);if(null===l){if(null!==P.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}P.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();za={}}, +!1)}catch(Hc){console.error(Hc)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var $=new THREE.WebGLExtensions(l);$.get("OES_texture_float");$.get("OES_texture_float_linear");$.get("OES_texture_half_float");$.get("OES_texture_half_float_linear");$.get("OES_standard_derivatives");ra&&$.get("EXT_frag_depth");var jc=function(a,b,c,d){!0===R&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1); +l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND);l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(gb,db,hb,Qa);jc(ja.r,ja.g,ja.b,wa)},Ac=function(){Fb=Wb=null;Nb=pb=ic=hc=Xb=-1;La="";Bb=-1;Mb=!0;for(var a=0;ab;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b= +"__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0, +h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),z(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture, +0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a? +(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=hb,a=Qa,d=gb,e=db);b!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),ob=b);xc=c;yc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); +else{var g=!1;a.__webglFramebuffer!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)===l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,ob)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}; +this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; From b4ef5e760237814e4638622731f3c6d9ba4529fc Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Feb 2015 15:41:59 -0800 Subject: [PATCH 092/333] SoftwareRenderer: Support material map change. Fixes #6018. --- examples/js/renderers/SoftwareRenderer.js | 29 ++++++++--------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/examples/js/renderers/SoftwareRenderer.js b/examples/js/renderers/SoftwareRenderer.js index 5529bb2ad4943d..e3e2f207b2ab61 100644 --- a/examples/js/renderers/SoftwareRenderer.js +++ b/examples/js/renderers/SoftwareRenderer.js @@ -14,6 +14,7 @@ THREE.SoftwareRenderer = function ( parameters ) { var canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ); + var context = canvas.getContext( '2d', { alpha: parameters.alpha === true } ); @@ -371,8 +372,9 @@ THREE.SoftwareRenderer = function ( parameters ) { var colorOffset = offset * 4; - if ( material.needsUpdate && !material.texture.data ) { + if ( material.map.needsUpdate === true ) { material.texture.CreateFromImage( material.map.image ); + material.map.needsUpdate = false; } if ( !material.texture.data ) @@ -410,8 +412,9 @@ THREE.SoftwareRenderer = function ( parameters ) { var colorOffset = offset * 4; - if ( material.map.needsUpdate && !material.texture.data ) { + if ( material.map.needsUpdate === true ) { material.texture.CreateFromImage( material.map.image ); + material.map.needsUpdate = false; } if ( !material.texture.data ) @@ -454,7 +457,7 @@ THREE.SoftwareRenderer = function ( parameters ) { var id = material.id; var shader = shaders[ id ]; - if ( shaders[ id ] === undefined ) { + if ( shaders[ id ] === undefined || material.needsUpdate === true ) { if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.MeshLambertMaterial || @@ -537,6 +540,8 @@ THREE.SoftwareRenderer = function ( parameters ) { shaders[ id ] = shader; + material.needsUpdate = false; + } return shader; @@ -1093,7 +1098,7 @@ THREE.SoftwareRenderer.Texture = function() { this.CreateFromImage = function( image ) { - if( !image || image.width <=0 || image.height <=0 ) + if( !image || image.width <= 0 || image.height <= 0 ) return; var isCanvasClean = false; @@ -1142,21 +1147,7 @@ THREE.SoftwareRenderer.Texture = function() { catch(e) { return; } - - var size = data.length; - this.data = new Uint8Array(size); - var alpha; - for(var i=0, j=0; i Date: Wed, 4 Feb 2015 16:00:25 -0800 Subject: [PATCH 093/333] Math: Added nextPowerOfTwo method. --- src/math/Math.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/math/Math.js b/src/math/Math.js index 0af95b4de05cde..40a9bf9c672ff7 100644 --- a/src/math/Math.js +++ b/src/math/Math.js @@ -150,6 +150,20 @@ THREE.Math = { return ( value & ( value - 1 ) ) === 0 && value !== 0; + }, + + nextPowerOfTwo: function ( value ) { + + value --; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value ++; + + return value; + } }; From c0a1a364781bcb7538699043adcda92cc61ab66c Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Feb 2015 16:03:15 -0800 Subject: [PATCH 094/333] SoftwareRenderer: Use Math.nextPowerOfTwo. --- examples/js/renderers/SoftwareRenderer.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/examples/js/renderers/SoftwareRenderer.js b/examples/js/renderers/SoftwareRenderer.js index e3e2f207b2ab61..856ca78dbf6336 100644 --- a/examples/js/renderers/SoftwareRenderer.js +++ b/examples/js/renderers/SoftwareRenderer.js @@ -1117,18 +1117,7 @@ THREE.SoftwareRenderer.Texture = function() { } var dim = image.width > image.height ? image.width : image.height; - if(dim <= 32) - dim = 32; - else if(dim <= 64) - dim = 64; - else if(dim <= 128) - dim = 128; - else if(dim <= 256) - dim = 256; - else if(dim <= 512) - dim = 512; - else - dim = 1024; + dim = THREE.Math.nextPowerOfTwo( dim ); if(canvas.width != dim || canvas.height != dim) { canvas.width = canvas.height = dim; From 90918361c7cd37b806992838460b13d9bd0c4e88 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Feb 2015 16:17:39 -0800 Subject: [PATCH 095/333] SoftwareRenderer: Simplified code. --- examples/js/renderers/SoftwareRenderer.js | 51 +++++------------------ 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/examples/js/renderers/SoftwareRenderer.js b/examples/js/renderers/SoftwareRenderer.js index 856ca78dbf6336..cd9a36073fe8ae 100644 --- a/examples/js/renderers/SoftwareRenderer.js +++ b/examples/js/renderers/SoftwareRenderer.js @@ -301,6 +301,7 @@ THREE.SoftwareRenderer = function ( parameters ) { } function getPalette( material, bSimulateSpecular ) { + var i = 0, j = 0; var diffuseR = material.color.r * 255; var diffuseG = material.color.g * 255; var diffuseB = material.color.b * 255; @@ -308,58 +309,26 @@ THREE.SoftwareRenderer = function ( parameters ) { if ( bSimulateSpecular ) { - var i = 0, j = 0; while(i < 204) { - var r = i * diffuseR / 204; - var g = i * diffuseG / 204; - var b = i * diffuseB / 204; - if(r > 255) - r = 255; - if(g > 255) - g = 255; - if(b > 255) - b = 255; - - palette[j++] = r; - palette[j++] = g; - palette[j++] = b; + palette[j++] = Math.min( i * diffuseR / 204, 255 ); + palette[j++] = Math.min( i * diffuseG / 204, 255 ); + palette[j++] = Math.min( i * diffuseB / 204, 255 ); ++i; } while(i < 256) { // plus specular highlight - var r = diffuseR + (i - 204) * (255 - diffuseR) / 82; - var g = diffuseG + (i - 204) * (255 - diffuseG) / 82; - var b = diffuseB + (i - 204) * (255 - diffuseB) / 82; - if(r > 255) - r = 255; - if(g > 255) - g = 255; - if(b > 255) - b = 255; - - palette[j++] = r; - palette[j++] = g; - palette[j++] = b; + palette[j++] = Math.min( diffuseR + (i - 204) * (255 - diffuseR) / 82, 255 ); + palette[j++] = Math.min( diffuseG + (i - 204) * (255 - diffuseG) / 82, 255 ); + palette[j++] = Math.min( diffuseB + (i - 204) * (255 - diffuseB) / 82, 255 ); ++i; } } else { - var i = 0, j = 0; while(i < 256) { - var r = i * diffuseR / 255; - var g = i * diffuseG / 255; - var b = i * diffuseB / 255; - if(r > 255) - r = 255; - if(g > 255) - g = 255; - if(b > 255) - b = 255; - - palette[j++] = r; - palette[j++] = g; - palette[j++] = b; + palette[j++] = Math.min( i * diffuseR / 255, 255 ); + palette[j++] = Math.min( i * diffuseG / 255, 255 ); + palette[j++] = Math.min( i * diffuseB / 255, 255 ); ++i; } From 7f1069069d1a9a901344debd9addca1a17e2f843 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Feb 2015 16:54:53 -0800 Subject: [PATCH 096/333] Material: Added needsUpdate getter/setter. --- src/materials/Material.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/materials/Material.js b/src/materials/Material.js index 6ebf17702299c8..ebb1b5fb0dbae5 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -39,7 +39,7 @@ THREE.Material = function () { this.visible = true; - this.needsUpdate = true; + this._needsUpdate = true; }; @@ -47,6 +47,20 @@ THREE.Material.prototype = { constructor: THREE.Material, + get needsUpdate () { + + return this._needsUpdate; + + }, + + set needsUpdate ( value ) { + + if ( value === true ) this.update(); + + this._needsUpdate = value; + + }, + setValues: function ( values ) { if ( values === undefined ) return; @@ -198,6 +212,12 @@ THREE.Material.prototype = { }, + update: function () { + + this.dispatchEvent( { type: 'update' } ); + + }, + dispose: function () { this.dispatchEvent( { type: 'dispose' } ); From 72d38a502a16f11722fdc0b7c726279f5e503b78 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Feb 2015 16:56:55 -0800 Subject: [PATCH 097/333] SoftwareRenderer: Simplified Texture logic and using material/texture update events. --- examples/js/renderers/SoftwareRenderer.js | 101 +++++++++++----------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/examples/js/renderers/SoftwareRenderer.js b/examples/js/renderers/SoftwareRenderer.js index cd9a36073fe8ae..26b9368d2191cb 100644 --- a/examples/js/renderers/SoftwareRenderer.js +++ b/examples/js/renderers/SoftwareRenderer.js @@ -20,6 +20,7 @@ THREE.SoftwareRenderer = function ( parameters ) { } ); var shaders = {}; + var textures = {}; var canvasWidth, canvasHeight; var canvasWBlocks, canvasHBlocks; @@ -341,18 +342,15 @@ THREE.SoftwareRenderer = function ( parameters ) { var colorOffset = offset * 4; - if ( material.map.needsUpdate === true ) { - material.texture.CreateFromImage( material.map.image ); - material.map.needsUpdate = false; - } + var texture = textures[ material.map.id ]; - if ( !material.texture.data ) + if ( !texture.data ) return; - var tdim = material.texture.width; + var tdim = texture.width; var isTransparent = material.transparent; var tbound = tdim - 1; - var tdata = material.texture.data; + var tdata = texture.data; var tIndex = (((v * tdim) & tbound) * tdim + ((u * tdim) & tbound)) * 4; if ( !isTransparent ) { @@ -381,19 +379,16 @@ THREE.SoftwareRenderer = function ( parameters ) { var colorOffset = offset * 4; - if ( material.map.needsUpdate === true ) { - material.texture.CreateFromImage( material.map.image ); - material.map.needsUpdate = false; - } + var texture = textures[ material.map.id ]; - if ( !material.texture.data ) + if ( !texture.data ) return; - var tdim = material.texture.width; + var tdim = texture.width; var isTransparent = material.transparent; var cIndex = (n > 0 ? (~~n) : 0) * 3; var tbound = tdim - 1; - var tdata = material.texture.data; + var tdata = texture.data; var tIndex = (((v * tdim) & tbound) * tdim + ((u * tdim) & tbound)) * 4; if ( !isTransparent ) { @@ -421,12 +416,24 @@ THREE.SoftwareRenderer = function ( parameters ) { } + function onMaterialUpdate ( event ) { + + var material = event.target; + + material.removeEventListener( 'update', onMaterialUpdate ); + + delete shaders[ material.id ]; + + } + function getMaterialShader( material ) { var id = material.id; var shader = shaders[ id ]; - if ( shaders[ id ] === undefined || material.needsUpdate === true ) { + if ( shaders[ id ] === undefined ) { + + material.addEventListener( 'update', onMaterialUpdate ); if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.MeshLambertMaterial || @@ -451,7 +458,15 @@ THREE.SoftwareRenderer = function ( parameters ) { if ( material.map ) { var texture = new THREE.SoftwareRenderer.Texture(); - material.texture = texture; + texture.fromImage( material.map.image ); + + material.map.addEventListener( 'update', function ( event ) { + + texture.fromImage( event.target.image ); + + } ); + + textures[ material.map.id ] = texture; if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.SpriteMaterial ) { @@ -509,8 +524,6 @@ THREE.SoftwareRenderer = function ( parameters ) { shaders[ id ] = shader; - material.needsUpdate = false; - } return shader; @@ -1063,51 +1076,37 @@ THREE.SoftwareRenderer = function ( parameters ) { }; THREE.SoftwareRenderer.Texture = function() { - var canvas = null; - this.CreateFromImage = function( image ) { + var canvas; + + this.fromImage = function( image ) { if( !image || image.width <= 0 || image.height <= 0 ) return; - var isCanvasClean = false; - var canvas = THREE.SoftwareRenderer.Texture.canvas; - if ( !canvas ) { - - try { + if ( canvas === undefined ) { - canvas = document.createElement('canvas'); - THREE.SoftwareRenderer.Texture.canvas = canvas; - isCanvasClean = true; - } catch( e ) { - return; - } + canvas = document.createElement( 'canvas' ); } - var dim = image.width > image.height ? image.width : image.height; - dim = THREE.Math.nextPowerOfTwo( dim ); + var size = image.width > image.height ? image.width : image.height; + size = THREE.Math.nextPowerOfTwo( size ); - if(canvas.width != dim || canvas.height != dim) { - canvas.width = canvas.height = dim; - isCanvasClean = true; + if ( canvas.width != size || canvas.height != size) { + canvas.width = size; + canvas.height = size; } - var data; - try { - var ctx = canvas.getContext('2d'); - if(!isCanvasClean) - ctx.clearRect(0, 0, dim, dim); - ctx.drawImage(image, 0, 0, dim, dim); - var imgData = ctx.getImageData(0, 0, dim, dim); - data = imgData.data; - } - catch(e) { - return; - } - this.data = data; - this.width = dim; - this.height = dim; + var ctx = canvas.getContext('2d'); + ctx.clearRect( 0, 0, size, size ); + ctx.drawImage( image, 0, 0, size, size ); + + var imgData = ctx.getImageData( 0, 0, size, size ); + + this.data = imgData.data; + this.width = size; + this.height = size; this.srcUrl = image.src; }; }; From ebbc2ed88187dbc6dbb3d3edfb77a3fb2388abf7 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Feb 2015 16:59:41 -0800 Subject: [PATCH 098/333] Updated builds. --- build/three.js | 36 +++++++++++++++++++++++++++++++++++- build/three.min.js | 18 +++++++++--------- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/build/three.js b/build/three.js index 4e159f1a99b770..f26837c546e8dc 100644 --- a/build/three.js +++ b/build/three.js @@ -6686,6 +6686,20 @@ THREE.Math = { return ( value & ( value - 1 ) ) === 0 && value !== 0; + }, + + nextPowerOfTwo: function ( value ) { + + value --; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value ++; + + return value; + } }; @@ -13243,7 +13257,7 @@ THREE.Material = function () { this.visible = true; - this.needsUpdate = true; + this._needsUpdate = true; }; @@ -13251,6 +13265,20 @@ THREE.Material.prototype = { constructor: THREE.Material, + get needsUpdate () { + + return this._needsUpdate; + + }, + + set needsUpdate ( value ) { + + if ( value === true ) this.update(); + + this._needsUpdate = value; + + }, + setValues: function ( values ) { if ( values === undefined ) return; @@ -13402,6 +13430,12 @@ THREE.Material.prototype = { }, + update: function () { + + this.dispatchEvent( { type: 'update' } ); + + }, + dispose: function () { this.dispatchEvent( { type: 'dispose' } ); diff --git a/build/three.min.js b/build/three.min.js index 58ac2b4e9ac3b2..aa270b4643cbc0 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -138,7 +138,7 @@ coplanarPoint:function(a){return(a||new THREE.Vector3).copy(this.normal).multipl a.constant==this.constant},clone:function(){return(new THREE.Plane).copy(this)}}; THREE.Math={generateUUID:function(){var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d;return function(){for(var e=0;36>e;e++)8==e||13==e||18==e||23==e?b[e]="-":14==e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19==e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return a=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){return(65280*Math.random()+255*Math.random())/65535},randInt:function(a,b){return Math.floor(this.randFloat(a,b))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a= -180/Math.PI;return function(b){return b*a}}(),isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a}}; +180/Math.PI;return function(b){return b*a}}(),isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}}; THREE.Spline=function(a){function b(a,b,c,d,e,f,g){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,f,g,h,k,p,n,q,m;this.initFromArray=function(a){this.points=[];for(var b=0;bthis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ 2;p=this.points[c[0]];n=this.points[c[1]];q=this.points[c[2]];m=this.points[c[3]];h=g*g;k=g*h;d.x=b(p.x,n.x,q.x,m.x,g,h,k);d.y=b(p.y,n.y,q.y,m.y,g,h,k);d.z=b(p.z,n.z,q.z,m.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;athis.opacity&&(a.opacity=this.opacity);!1!== -this.transparent&&(a.transparent=this.transparent);!1!==this.wireframe&&(a.wireframe=this.wireframe);return a},clone:function(a){void 0===a&&(a=new THREE.Material);a.name=this.name;a.side=this.side;a.opacity=this.opacity;a.transparent=this.transparent;a.blending=this.blending;a.blendSrc=this.blendSrc;a.blendDst=this.blendDst;a.blendEquation=this.blendEquation;a.blendSrcAlpha=this.blendSrcAlpha;a.blendDstAlpha=this.blendDstAlpha;a.blendEquationAlpha=this.blendEquationAlpha;a.depthTest=this.depthTest; -a.depthWrite=this.depthWrite;a.polygonOffset=this.polygonOffset;a.polygonOffsetFactor=this.polygonOffsetFactor;a.polygonOffsetUnits=this.polygonOffsetUnits;a.alphaTest=this.alphaTest;a.overdraw=this.overdraw;a.visible=this.visible;return a},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Material.prototype);THREE.MaterialIdCount=0; -THREE.LineBasicMaterial=function(a){THREE.Material.call(this);this.type="LineBasicMaterial";this.color=new THREE.Color(16777215);this.linewidth=1;this.linejoin=this.linecap="round";this.vertexColors=THREE.NoColors;this.fog=!0;this.setValues(a)};THREE.LineBasicMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineBasicMaterial.prototype.constructor=THREE.LineBasicMaterial; +this.alphaTest=this.polygonOffsetUnits=this.polygonOffsetFactor=0;this._needsUpdate=this.visible=!0}; +THREE.Material.prototype={constructor:THREE.Material,get needsUpdate(){return this._needsUpdate},set needsUpdate(a){!0===a&&this.update();this._needsUpdate=a},setValues:function(a){if(void 0!==a)for(var b in a){var c=a[b];if(void 0===c)console.warn("THREE.Material: '"+b+"' parameter is undefined.");else if(b in this){var d=this[b];d instanceof THREE.Color?d.set(c):d instanceof THREE.Vector3&&c instanceof THREE.Vector3?d.copy(c):this[b]="overdraw"==b?Number(c):c}}},toJSON:function(){var a={metadata:{version:4.2, +type:"material",generator:"MaterialExporter"},uuid:this.uuid,type:this.type};""!==this.name&&(a.name=this.name);this instanceof THREE.MeshBasicMaterial?(a.color=this.color.getHex(),this.vertexColors!==THREE.NoColors&&(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshLambertMaterial?(a.color=this.color.getHex(),a.emissive=this.emissive.getHex(),this.vertexColors!==THREE.NoColors&& +(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshPhongMaterial?(a.color=this.color.getHex(),a.emissive=this.emissive.getHex(),a.specular=this.specular.getHex(),a.shininess=this.shininess,this.vertexColors!==THREE.NoColors&&(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof +THREE.MeshNormalMaterial?(this.shading!==THREE.FlatShading&&(a.shading=this.shading),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshDepthMaterial?(this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.ShaderMaterial?(a.uniforms=this.uniforms,a.vertexShader=this.vertexShader,a.fragmentShader=this.fragmentShader):this instanceof +THREE.SpriteMaterial&&(a.color=this.color.getHex());1>this.opacity&&(a.opacity=this.opacity);!1!==this.transparent&&(a.transparent=this.transparent);!1!==this.wireframe&&(a.wireframe=this.wireframe);return a},clone:function(a){void 0===a&&(a=new THREE.Material);a.name=this.name;a.side=this.side;a.opacity=this.opacity;a.transparent=this.transparent;a.blending=this.blending;a.blendSrc=this.blendSrc;a.blendDst=this.blendDst;a.blendEquation=this.blendEquation;a.blendSrcAlpha=this.blendSrcAlpha;a.blendDstAlpha= +this.blendDstAlpha;a.blendEquationAlpha=this.blendEquationAlpha;a.depthTest=this.depthTest;a.depthWrite=this.depthWrite;a.polygonOffset=this.polygonOffset;a.polygonOffsetFactor=this.polygonOffsetFactor;a.polygonOffsetUnits=this.polygonOffsetUnits;a.alphaTest=this.alphaTest;a.overdraw=this.overdraw;a.visible=this.visible;return a},update:function(){this.dispatchEvent({type:"update"})},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Material.prototype); +THREE.MaterialIdCount=0;THREE.LineBasicMaterial=function(a){THREE.Material.call(this);this.type="LineBasicMaterial";this.color=new THREE.Color(16777215);this.linewidth=1;this.linejoin=this.linecap="round";this.vertexColors=THREE.NoColors;this.fog=!0;this.setValues(a)};THREE.LineBasicMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineBasicMaterial.prototype.constructor=THREE.LineBasicMaterial; THREE.LineBasicMaterial.prototype.clone=function(){var a=new THREE.LineBasicMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.linewidth=this.linewidth;a.linecap=this.linecap;a.linejoin=this.linejoin;a.vertexColors=this.vertexColors;a.fog=this.fog;return a}; THREE.LineDashedMaterial=function(a){THREE.Material.call(this);this.type="LineDashedMaterial";this.color=new THREE.Color(16777215);this.scale=this.linewidth=1;this.dashSize=3;this.gapSize=1;this.vertexColors=!1;this.fog=!0;this.setValues(a)};THREE.LineDashedMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineDashedMaterial.prototype.constructor=THREE.LineDashedMaterial; THREE.LineDashedMaterial.prototype.clone=function(){var a=new THREE.LineDashedMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.linewidth=this.linewidth;a.scale=this.scale;a.dashSize=this.dashSize;a.gapSize=this.gapSize;a.vertexColors=this.vertexColors;a.fog=this.fog;return a}; From f7ed3e53fd506216ac5bf3d12d7a837d05ab00f6 Mon Sep 17 00:00:00 2001 From: Jesper Oskarsson Date: Fri, 6 Feb 2015 22:45:56 +0100 Subject: [PATCH 099/333] Fix in Raycaster example Changed from incorrectly iterating over the keys to over the actual intersection points in the array. --- docs/api/core/Raycaster.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/core/Raycaster.html b/docs/api/core/Raycaster.html index b06160765f0b13..d8ee4bd979795d 100644 --- a/docs/api/core/Raycaster.html +++ b/docs/api/core/Raycaster.html @@ -36,9 +36,9 @@

Example

// calculate objects intersecting the picking ray var intersects = raycaster.intersectObjects( scene.children ); - for ( var intersect in intersects ) { + for ( var i = 0; i < intersects.length; i++ ) { - intersect.object.material.color = new THREE.Color( 0xff0000 ); + intersects[i].object.material.color = new THREE.Color( 0xff0000 ); } From 8b4e8874ed1f8974377a8986d4a2e15f0d0bff5f Mon Sep 17 00:00:00 2001 From: Jesper Oskarsson Date: Sat, 7 Feb 2015 00:49:58 +0100 Subject: [PATCH 100/333] Fixed formatting --- docs/api/core/Raycaster.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/core/Raycaster.html b/docs/api/core/Raycaster.html index d8ee4bd979795d..b99e2500692718 100644 --- a/docs/api/core/Raycaster.html +++ b/docs/api/core/Raycaster.html @@ -38,7 +38,7 @@

Example

for ( var i = 0; i < intersects.length; i++ ) { - intersects[i].object.material.color = new THREE.Color( 0xff0000 ); + intersects[ i ].object.material.color = new THREE.Color( 0xff0000 ); } From cfe5dc14ab7b4ed94f4ba364241d1f04618bc608 Mon Sep 17 00:00:00 2001 From: Jesper Oskarsson Date: Sat, 7 Feb 2015 03:39:54 +0100 Subject: [PATCH 101/333] Update Raycaster.html --- docs/api/core/Raycaster.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/core/Raycaster.html b/docs/api/core/Raycaster.html index b99e2500692718..de44936c5bba1a 100644 --- a/docs/api/core/Raycaster.html +++ b/docs/api/core/Raycaster.html @@ -38,7 +38,7 @@

Example

for ( var i = 0; i < intersects.length; i++ ) { - intersects[ i ].object.material.color = new THREE.Color( 0xff0000 ); + intersects[ i ].object.material.color.set( 0xff0000 ); } From 0a2a0a066cdc653fa21d4e5b96c54615160af967 Mon Sep 17 00:00:00 2001 From: Jesper Oskarsson Date: Sat, 7 Feb 2015 03:42:09 +0100 Subject: [PATCH 102/333] Added missing semicolons --- docs/api/core/Raycaster.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/core/Raycaster.html b/docs/api/core/Raycaster.html index de44936c5bba1a..ce6b442c41308b 100644 --- a/docs/api/core/Raycaster.html +++ b/docs/api/core/Raycaster.html @@ -23,8 +23,8 @@

Example

// calculate mouse position in normalized device coordinates // (-1 to +1) for both components - mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1 - mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1 + mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; + mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; } From 87312c640f5f95eb0e691db928963a9dc87c8817 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 6 Feb 2015 19:36:42 -0800 Subject: [PATCH 103/333] UI: Removed THREE dependency. --- editor/js/libs/ui.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/editor/js/libs/ui.js b/editor/js/libs/ui.js index 73a59328d15bea..2e6637969c684c 100644 --- a/editor/js/libs/ui.js +++ b/editor/js/libs/ui.js @@ -640,8 +640,8 @@ UI.Number = function ( number ) { var distance = 0; var onMouseDownValue = 0; - var pointer = new THREE.Vector2(); - var prevPointer = new THREE.Vector2(); + var pointer = [ 0, 0 ]; + var prevPointer = [ 0, 0 ]; var onMouseDown = function ( event ) { @@ -651,7 +651,7 @@ UI.Number = function ( number ) { onMouseDownValue = parseFloat( dom.value ); - prevPointer.set( event.clientX, event.clientY ); + prevPointer = [ event.clientX, event.clientY ]; document.addEventListener( 'mousemove', onMouseMove, false ); document.addEventListener( 'mouseup', onMouseUp, false ); @@ -662,9 +662,9 @@ UI.Number = function ( number ) { var currentValue = dom.value; - pointer.set( event.clientX, event.clientY ); + pointer = [ event.clientX, event.clientY ]; - distance += ( pointer.x - prevPointer.x ) - ( pointer.y - prevPointer.y ); + distance += ( pointer[ 0 ] - prevPointer[ 0 ] ) - ( pointer[ 1 ] - prevPointer[ 1 ] ); var number = onMouseDownValue + ( distance / ( event.shiftKey ? 5 : 50 ) ) * scope.step; @@ -672,7 +672,7 @@ UI.Number = function ( number ) { if ( currentValue !== dom.value ) dom.dispatchEvent( changeEvent ); - prevPointer.set( event.clientX, event.clientY ); + prevPointer = [ event.clientX, event.clientY ]; }; @@ -804,8 +804,8 @@ UI.Integer = function ( number ) { var distance = 0; var onMouseDownValue = 0; - var pointer = new THREE.Vector2(); - var prevPointer = new THREE.Vector2(); + var pointer = [ 0, 0 ]; + var prevPointer = [ 0, 0 ]; var onMouseDown = function ( event ) { @@ -815,7 +815,7 @@ UI.Integer = function ( number ) { onMouseDownValue = parseFloat( dom.value ); - prevPointer.set( event.clientX, event.clientY ); + prevPointer = [ event.clientX, event.clientY ]; document.addEventListener( 'mousemove', onMouseMove, false ); document.addEventListener( 'mouseup', onMouseUp, false ); @@ -826,9 +826,9 @@ UI.Integer = function ( number ) { var currentValue = dom.value; - pointer.set( event.clientX, event.clientY ); + pointer = [ event.clientX, event.clientY ]; - distance += ( pointer.x - prevPointer.x ) - ( pointer.y - prevPointer.y ); + distance += ( pointer[ 0 ] - prevPointer[ 0 ] ) - ( pointer[ 1 ] - prevPointer[ 1 ] ); var number = onMouseDownValue + ( distance / ( event.shiftKey ? 5 : 50 ) ) * scope.step; @@ -836,7 +836,7 @@ UI.Integer = function ( number ) { if ( currentValue !== dom.value ) dom.dispatchEvent( changeEvent ); - prevPointer.set( event.clientX, event.clientY ); + prevPointer = [ event.clientX, event.clientY ]; }; From 4263f38cdcdfb4f922d664868f6c954df0cdd168 Mon Sep 17 00:00:00 2001 From: Mauricio Date: Sat, 7 Feb 2015 15:11:00 +0100 Subject: [PATCH 104/333] Update CylinderGeometry.html just a Typo correction Line:43 --- docs/api/extras/geometries/CylinderGeometry.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/extras/geometries/CylinderGeometry.html b/docs/api/extras/geometries/CylinderGeometry.html index 51e6803ca3c282..992859f42651e3 100644 --- a/docs/api/extras/geometries/CylinderGeometry.html +++ b/docs/api/extras/geometries/CylinderGeometry.html @@ -40,7 +40,7 @@

[name]([page:Float radiusTop], [page:Float radiusBottom], [page:Float height

Properties

- Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry. + Each of the constructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
From bd9c4662e07e554ccb2c7595bf6f0f4c147011b7 Mon Sep 17 00:00:00 2001 From: dubejf Date: Sun, 8 Feb 2015 11:29:41 -0500 Subject: [PATCH 105/333] Update EdgesHelper.js to support BufferGeometry --- src/extras/helpers/EdgesHelper.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/extras/helpers/EdgesHelper.js b/src/extras/helpers/EdgesHelper.js index a5925655ee2957..252fc7e09ef1cf 100644 --- a/src/extras/helpers/EdgesHelper.js +++ b/src/extras/helpers/EdgesHelper.js @@ -12,7 +12,17 @@ THREE.EdgesHelper = function ( object, hex ) { var keys = [ 'a', 'b', 'c' ]; var geometry = new THREE.BufferGeometry(); - var geometry2 = object.geometry.clone(); + var geometry2; + if ( object.geometry instanceof THREE.BufferGeometry ) { + + geometry2 = new THREE.Geometry(); + geometry2.fromBufferGeometry( object.geometry ); + + } else { + + geometry2 = object.geometry.clone(); + + } geometry2.mergeVertices(); geometry2.computeFaceNormals(); From 854688f16b262206926ee134dc4647778757e971 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Sun, 8 Feb 2015 18:56:48 +0200 Subject: [PATCH 106/333] Small fixes on texture loading. Special thanks to @spinchristopher --- src/loaders/ObjectLoader.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 78e6f53b053a3c..a4a5f3e6e3b9aa 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -50,12 +50,15 @@ THREE.ObjectLoader.prototype = { var geometries, materials, images, textures; var self = this; + self.manager.itemStart(json.object.uuid); var manager = new THREE.LoadingManager( function() { textures = self.parseTextures( json.textures, images ); materials = self.parseMaterials( json.materials, textures ); onLoad( self.parseObject( json.object, geometries, materials ) ); + // report back to parent manager + self.manager.itemEnd(json.object.uuid); } ); @@ -263,13 +266,13 @@ THREE.ObjectLoader.prototype = { var url = self.texturePath + data.url; self.manager.itemStart( url ); - loader.load( url, function ( image ) { + loader.load( url, function ( uuid, url, image ) { self.manager.itemEnd( url ); - images[ data.uuid ] = image; + images[ uuid ] = image; - } ); + }.bind( null, data.uuid, url ) ); } From 91a9b614847bba8e0e0c36ab026c22244b178763 Mon Sep 17 00:00:00 2001 From: repsac Date: Sun, 8 Feb 2015 15:53:12 -0800 Subject: [PATCH 107/333] Added utility functions to generate ID using a base name Abstracted uuid creation logic from base classes Improved the layout of controls in the export panel Added option for indenting the JSON output (space saver) Animation option is now an enum that requires a user to select between POSE and REST Abstracted animation logic into a new module reducing the size of mesh.py Improved indexing speeds for vertex colours and normal vectors Node uuid is now based on name and will be persistent ver multiple exports Empty arrays will no longer assign None to key values Copying files will no longer remove the destination, additionally destinations are tested to see if the same as the source --- .../blender/addons/io_three/__init__.py | 145 +++-- .../blender/addons/io_three/constants.py | 11 +- .../addons/io_three/exporter/api/animation.py | 476 +++++++++++++++ .../addons/io_three/exporter/api/mesh.py | 558 ++++++------------ .../addons/io_three/exporter/base_classes.py | 11 +- .../addons/io_three/exporter/geometry.py | 31 +- .../blender/addons/io_three/exporter/io.py | 23 +- .../blender/addons/io_three/exporter/scene.py | 8 +- .../addons/io_three/exporter/utilities.py | 3 + .../tests/scripts/test_geometry_normals.bash | 2 +- .../tests/scripts/test_scene_instancing.bash | 2 +- 11 files changed, 806 insertions(+), 464 deletions(-) create mode 100644 utils/exporters/blender/addons/io_three/exporter/api/animation.py diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 0018f682d661df..6639a4db83be0d 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -18,6 +18,7 @@ import os import json +import logging import bpy from bpy_extras.io_utils import ExportHelper @@ -30,6 +31,10 @@ from . import constants +logging.basicConfig( + format='%(levelname)s:THREE:%(message)s', + level=logging.DEBUG) + SETTINGS_FILE_EXPORT = 'three_settings_export.js' @@ -221,10 +226,11 @@ def save_settings_export(properties): constants.PRECISION: properties.option_round_value, constants.LOGGING: properties.option_logging, constants.COMPRESSION: properties.option_compression, + constants.INDENT: properties.option_indent, constants.COPY_TEXTURES: properties.option_copy_textures, constants.SCENE: properties.option_export_scene, - constants.EMBED_GEOMETRY: properties.option_embed_geometry, + #constants.EMBED_GEOMETRY: properties.option_embed_geometry, constants.EMBED_ANIMATION: properties.option_embed_animation, constants.LIGHTS: properties.option_lights, constants.CAMERAS: properties.option_cameras, @@ -237,6 +243,7 @@ def save_settings_export(properties): } fname = get_settings_fullpath() + logging.debug('Saving settings to %s', fname) with open(fname, 'w') as stream: json.dump(settings, stream) @@ -249,8 +256,11 @@ def restore_settings_export(properties): fname = get_settings_fullpath() if os.path.exists(fname) and os.access(fname, os.R_OK): - f = open(fname, 'r') - settings = json.load(f) + logging.debug('Settings cache found %s', fname) + with open(fname, 'r') as fs: + settings = json.load(fs) + else: + logging.debug('No settings file found, using defaults.') ## Geometry { properties.option_vertices = settings.get( @@ -328,6 +338,10 @@ def restore_settings_export(properties): constants.COMPRESSION, constants.NONE) + properties.option_indent = settings.get( + constants.INDENT, + constants.EXPORT_OPTIONS[constants.INDENT]) + properties.option_copy_textures = settings.get( constants.COPY_TEXTURES, constants.EXPORT_OPTIONS[constants.COPY_TEXTURES]) @@ -342,9 +356,9 @@ def restore_settings_export(properties): constants.SCENE, constants.EXPORT_OPTIONS[constants.SCENE]) - properties.option_embed_geometry = settings.get( - constants.EMBED_GEOMETRY, - constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY]) + #properties.option_embed_geometry = settings.get( + # constants.EMBED_GEOMETRY, + # constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY]) properties.option_lights = settings.get( constants.LIGHTS, @@ -385,6 +399,15 @@ def compression_types(): return types +def animation_options(): + anim = [ + (constants.OFF, constants.OFF.title(), constants.OFF), + (constants.POSE, constants.POSE.title(), constants.POSE), + (constants.REST, constants.REST.title(), constants.REST) + ] + + return anim + class ExportThree(bpy.types.Operator, ExportHelper): bl_idname='export.three' @@ -408,7 +431,7 @@ class ExportThree(bpy.types.Operator, ExportHelper): default=constants.EXPORT_OPTIONS[constants.NORMALS]) option_colors = BoolProperty( - name='Colors', + name='Vertex Colors', description='Export vertex colors', default=constants.EXPORT_OPTIONS[constants.COLORS]) @@ -476,7 +499,7 @@ class ExportThree(bpy.types.Operator, ExportHelper): (constants.CRITICAL, constants.CRITICAL, constants.CRITICAL)] option_logging = EnumProperty( - name='Logging', + name='', description = 'Logging verbosity level', items=logging_types, default=constants.DEBUG) @@ -491,11 +514,13 @@ class ExportThree(bpy.types.Operator, ExportHelper): name='Scene', description='Export scene', default=constants.EXPORT_OPTIONS[constants.SCENE]) - - option_embed_geometry = BoolProperty( - name='Embed geometry', - description='Embed geometry', - default=constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY]) + + #@TODO: removing this option since the ObjectLoader doesn't have + # support for handling external geometry data + #option_embed_geometry = BoolProperty( + # name='Embed geometry', + # description='Embed geometry', + # default=constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY]) option_embed_animation = BoolProperty( name='Embed animation', @@ -522,10 +547,11 @@ class ExportThree(bpy.types.Operator, ExportHelper): description='Export animation (morphs)', default=constants.EXPORT_OPTIONS[constants.MORPH_TARGETS]) - option_animation_skeletal = BoolProperty( - name='Skeletal animation', + option_animation_skeletal = EnumProperty( + name='', description='Export animation (skeletal)', - default=constants.EXPORT_OPTIONS[constants.ANIMATION]) + items=animation_options(), + default=constants.OFF) option_frame_index_as_time = BoolProperty( name='Frame index as time', @@ -541,8 +567,13 @@ class ExportThree(bpy.types.Operator, ExportHelper): soft_max=1000, default=1) + option_indent = BoolProperty( + name='Indent JSON', + description='Disable this to reduce the file size', + default=constants.EXPORT_OPTIONS[constants.INDENT]) + option_compression = EnumProperty( - name='Compression', + name='', description = 'Compression options', items=compression_types(), default=constants.NONE) @@ -585,7 +616,7 @@ def draw(self, context): ## Geometry { row = layout.row() - row.label(text='Geometry:') + row.label(text='GEOMETRY:') row = layout.row() row.prop(self.properties, 'option_vertices') @@ -593,6 +624,7 @@ def draw(self, context): row = layout.row() row.prop(self.properties, 'option_normals') + row.prop(self.properties, 'option_uv_coords') row = layout.row() row.prop(self.properties, 'option_bones') @@ -601,69 +633,66 @@ def draw(self, context): row = layout.row() row.prop(self.properties, 'option_geometry_type') - row = layout.row() - row.prop(self.properties, 'option_influences') ## } layout.separator() ## Materials { row = layout.row() - row.label(text='Materials:') - - row = layout.row() - row.prop(self.properties, 'option_materials') - row.prop(self.properties, 'option_uv_coords') + row.label(text='- Shading:') row = layout.row() row.prop(self.properties, 'option_face_materials') - row.prop(self.properties, 'option_maps') row = layout.row() row.prop(self.properties, 'option_colors') + + row = layout.row() row.prop(self.properties, 'option_mix_colors') ## } layout.separator() - ## Settings { + ## Animation { row = layout.row() - row.label(text='Settings:') + row.label(text='- Animation:') row = layout.row() - row.prop(self.properties, 'option_scale') - - row = layout.row() - row = layout.row() - row.prop(self.properties, 'option_round_off') + row.prop(self.properties, 'option_animation_morph') + row = layout.row() - row.prop(self.properties, 'option_round_value') + row.label(text='Skeletal animations:') row = layout.row() + row.prop(self.properties, 'option_animation_skeletal') + + layout.row() row = layout.row() - row.prop(self.properties, 'option_logging') + row.prop(self.properties, 'option_influences') row = layout.row() - row.prop(self.properties, 'option_compression') + row.prop(self.properties, 'option_frame_step') row = layout.row() - row.prop(self.properties, 'option_copy_textures') + row.prop(self.properties, 'option_frame_index_as_time') row = layout.row() row.prop(self.properties, 'option_embed_animation') + ## } layout.separator() ## Scene { row = layout.row() - row.label(text='Scene:') + row.label(text='SCENE:') row = layout.row() row.prop(self.properties, 'option_export_scene') + row.prop(self.properties, 'option_materials') - row = layout.row() - row.prop(self.properties, 'option_embed_geometry') + #row = layout.row() + #row.prop(self.properties, 'option_embed_geometry') row = layout.row() row.prop(self.properties, 'option_lights') @@ -672,20 +701,44 @@ def draw(self, context): layout.separator() - ## Animation { + ## Settings { row = layout.row() - row.label(text='Animation:') + row.label(text='SETTINGS:') row = layout.row() - row.prop(self.properties, 'option_animation_morph') + row.prop(self.properties, 'option_maps') + row = layout.row() - row.prop(self.properties, 'option_animation_skeletal') + row.prop(self.properties, 'option_copy_textures') + row = layout.row() - row.prop(self.properties, 'option_frame_step') + row.prop(self.properties, 'option_scale') + + layout.row() row = layout.row() - row.prop(self.properties, 'option_frame_index_as_time') + row.prop(self.properties, 'option_round_off') + row = layout.row() + row.prop(self.properties, 'option_round_value') + + layout.row() + row = layout.row() + row.label(text='Logging verbosity:') + + row = layout.row() + row.prop(self.properties, 'option_logging') + + row = layout.row() + row.label(text='File compression format:') + + row = layout.row() + row.prop(self.properties, 'option_compression') + + row = layout.row() + row.prop(self.properties, 'option_indent') ## } + + def menu_func_export(self, context): default_path = bpy.data.filepath.replace('.blend', constants.EXTENSION) text = 'Three.js (%s)' % constants.EXTENSION diff --git a/utils/exporters/blender/addons/io_three/constants.py b/utils/exporters/blender/addons/io_three/constants.py index dcf1c2f2eece4b..b183cf0c54d2fd 100644 --- a/utils/exporters/blender/addons/io_three/constants.py +++ b/utils/exporters/blender/addons/io_three/constants.py @@ -34,6 +34,7 @@ JSON = 'json' EXTENSION = '.%s' % JSON +INDENT = 'indent' MATERIALS = 'materials' @@ -52,6 +53,8 @@ FRAME_INDEX_AS_TIME = 'frameIndexAsTime' ANIMATION = 'animations' MORPH_TARGETS = 'morphTargets' +POSE = 'pose' +REST = 'rest' SKIN_INDICES = 'skinIndices' SKIN_WEIGHTS = 'skinWeights' LOGGING = 'logging' @@ -65,6 +68,7 @@ DEFAULT_PRECISION = 6 EMBED_GEOMETRY = 'embedGeometry' EMBED_ANIMATION = 'embedAnimation' +OFF = 'off' GLOBAL = 'global' BUFFER_GEOMETRY = 'BufferGeometry' @@ -95,11 +99,11 @@ SCALE: 1, FRAME_STEP: 1, FRAME_INDEX_AS_TIME: False, - SCENE: True, + SCENE: False, MIX_COLORS: False, COMPRESSION: None, MAPS: False, - ANIMATION: False, + ANIMATION: OFF, BONES: False, SKINNING: False, MORPH_TARGETS: False, @@ -112,7 +116,8 @@ EMBED_GEOMETRY: True, EMBED_ANIMATION: True, GEOMETRY_TYPE: GEOMETRY, - INFLUENCES_PER_VERTEX: 2 + INFLUENCES_PER_VERTEX: 2, + INDENT: True } diff --git a/utils/exporters/blender/addons/io_three/exporter/api/animation.py b/utils/exporters/blender/addons/io_three/exporter/api/animation.py new file mode 100644 index 00000000000000..13af9003945092 --- /dev/null +++ b/utils/exporters/blender/addons/io_three/exporter/api/animation.py @@ -0,0 +1,476 @@ +import mathutils +from bpy import data, context +from .. import constants, logger, utilities + + +def pose_animation(armature, options): + logger.debug('animation.pose_animation %s', armature) + func = _parse_pose_action + return _parse_action(func, armature, options) + + +def rest_animation(armature, options): + logger.debug('animation.rest_animation %s', armature) + func = _parse_rest_action + return _parse_action(func, armature, options) + + +def _parse_action(func, armature, options): + animations = [] + logger.info('Parsing %d actions', len(data.actions)) + round_off, round_val = utilities.rounding(options) + for action in data.actions: + logger.info('Parsing action %s', action.name) + animation = func(action, armature, options, round_off, round_val) + animations.append(animation) + return animations + + +def _parse_rest_action(action, armature, options, round_off, round_val): + end_frame = action.frame_range[1] + start_frame = action.frame_range[0] + frame_length = end_frame - start_frame + l,r,s = armature.matrix_world.decompose() + rotation_matrix = r.to_matrix() + hierarchy = [] + parent_index = -1 + frame_step = options.get(constants.FRAME_STEP, 1) + fps = context.scene.render.fps + + start = int(start_frame) + end = int(end_frame / frame_step) + 1 + + for bone in armature.data.bones: + # I believe this was meant to skip control bones, may + # not be useful. needs more testing + if bone.use_deform is False: + logger.info('Skipping animation data for bone %s', bone.name) + continue + + logger.info('Parsing animation data for bone %s', bone.name) + + keys = [] + for frame in range(start, end): + computed_frame = frame * frame_step + pos, pchange = _position(bone, computed_frame, + action, armature.matrix_world) + rot, rchange = _rotation(bone, computed_frame, + action, rotation_matrix) + + # flip y and z + px, py, pz = pos.x, pos.z, -pos.y + rx, ry, rz, rw = rot.x, rot.z, -rot.y, rot.w + + if frame == start_frame: + + time = (frame * frame_step - start_frame) / fps + #@TODO: missing scale values + keyframe = { + constants.TIME: time, + constants.POS: [px, py, pz], + constants.ROT: [rx, ry, rz, rw], + constants.SCL: [1, 1, 1] + } + keys.append(keyframe) + + # END-FRAME: needs pos, rot and scl attributes + # with animation length (required frame) + + elif frame == end_frame / frame_step: + + time = frame_length / fps + keyframe = { + constants.TIME: time, + constants.POS: [px, py, pz], + constants.ROT: [rx, ry, rz, rw], + constants.SCL: [1, 1, 1] + } + keys.append(keyframe) + + # MIDDLE-FRAME: needs only one of the attributes, + # can be an empty frame (optional frame) + + elif pchange == True or rchange == True: + + time = (frame * frame_step - start_frame) / fps + + if pchange == True and rchange == True: + keyframe = { + constants.TIME: time, + constants.POS: [px, py, pz], + constants.ROT: [rx, ry, rz, rw] + } + elif pchange == True: + keyframe = { + constants.TIME: time, + constants.POS: [px, py, pz] + } + elif rchange == True: + keyframe = { + constants.TIME: time, + constants.ROT: [rx, ry, rz, rw] + } + + keys.append(keyframe) + + hierarchy.append({ + constants.KEYS: keys, + constants.PARENT: parent_index + }) + parent_index += 1 + + animation = { + constants.HIERARCHY: hierarchy, + constants.LENGTH:frame_length / fps, + constants.FPS: fps, + constants.NAME: action.name + } + + return animation + + +def _parse_pose_action(action, armature, options, round_off, round_val): + #@TODO: this seems to fail in batch mode meaning the + # user has to have th GUI open. need to improve + # this logic to allow batch processing, if Blender + # chooses to behave.... + current_context = context.area.type + context.area.type = 'DOPESHEET_EDITOR' + context.space_data.mode = 'ACTION' + context.area.spaces.active.action = action + + armature_matrix = armature.matrix_world + fps = context.scene.render.fps + + end_frame = action.frame_range[1] + start_frame = action.frame_range[0] + frame_length = end_frame - start_frame + + frame_step = options.get(constants.FRAME_STEP, 1) + used_frames = int(frame_length / frame_step) + 1 + + keys = [] + channels_location = [] + channels_rotation = [] + channels_scale = [] + + for pose_bone in armature.pose.bones: + logger.info('Processing channels for %s', + pose_bone.bone.name) + keys.append([]) + channels_location.append( + _find_channels(action, + pose_bone.bone, + 'location')) + channels_rotation.append( + _find_channels(action, + pose_bone.bone, + 'rotation_quaternion')) + channels_rotation.append( + _find_channels(action, + pose_bone.bone, + 'rotation_euler')) + channels_scale.append( + _find_channels(action, + pose_bone.bone, + 'scale')) + + frame_step = options[constants.FRAME_STEP] + frame_index_as_time = options[constants.FRAME_INDEX_AS_TIME] + for frame_index in range(0, used_frames): + if frame_index == used_frames - 1: + frame = end_frame + else: + frame = start_frame + frame_index * frame_step + + logger.info('Processing frame %d', frame) + + time = frame - start_frame + if frame_index_as_time is False: + time = time / fps + + context.scene.frame_set(frame) + + bone_index = 0 + + def has_keyframe_at(channels, frame): + def find_keyframe_at(channel, frame): + for keyframe in channel.keyframe_points: + if keyframe.co[0] == frame: + return keyframe + return None + + for channel in channels: + if not find_keyframe_at(channel, frame) is None: + return True + return False + + for pose_bone in armature.pose.bones: + + logger.info('Processing bone %s', pose_bone.bone.name) + if pose_bone.parent is None: + bone_matrix = armature_matrix * pose_bone.matrix + else: + parent_matrix = armature_matrix * pose_bone.parent.matrix + bone_matrix = armature_matrix * pose_bone.matrix + bone_matrix = parent_matrix.inverted() * bone_matrix + + pos, rot, scl = bone_matrix.decompose() + + pchange = True or has_keyframe_at( + channels_location[bone_index], frame) + rchange = True or has_keyframe_at( + channels_rotation[bone_index], frame) + schange = True or has_keyframe_at( + channels_scale[bone_index], frame) + + if round_off: + pos = ( + utilities.round_off(pos.x, round_val), + utilities.round_off(pos.z, round_val), + -utilities.round_off(pos.y, round_val) + ) + rot = ( + utilities.round_off(rot.x, round_val), + utilities.round_off(rot.z, round_val), + -utilities.round_off(rot.y, round_val), + utilities.round_off(rot.w, round_val) + ) + scl = ( + utilities.round_off(scl.x, round_val), + utilities.round_off(scl.z, round_val), + utilities.round_off(scl.y, round_val) + ) + else: + pos = (pos.x, pos.z, -pos.y) + rot = (rot.x, rot.z, -rot.y, rot.w) + scl = (scl.x, scl.z, scl.y) + + keyframe = {constants.TIME: time} + if frame == start_frame or frame == end_frame: + keyframe.update({ + constants.POS: pos, + constants.ROT: rot, + constants.SCL: scl + }) + elif any([pchange, rchange, schange]): + if pchange is True: + keyframe[constants.POS] = pos + if rchange is True: + keyframe[constants.ROT] = rot + if schange is True: + keyframe[constants.SCL] = scl + + if len(keyframe.keys()) > 1: + logger.info('Recording keyframe data for %s %s', + pose_bone.bone.name, str(keyframe)) + keys[bone_index].append(keyframe) + else: + logger.info('No anim data to record for %s', + pose_bone.bone.name) + + bone_index += 1 + + hierarchy = [] + bone_index = 0 + for pose_bone in armature.pose.bones: + hierarchy.append({ + constants.PARENT: bone_index - 1, + constants.KEYS: keys[bone_index] + }) + bone_index += 1 + + if frame_index_as_time is False: + frame_length = frame_length / fps + + context.scene.frame_set(start_frame) + context.area.type = current_context + + animation = { + constants.HIERARCHY: hierarchy, + constants.LENGTH:frame_length, + constants.FPS: fps, + constants.NAME: action.name + } + + return animation + + +def _find_channels(action, bone, channel_type): + result = [] + + if len(action.groups): + + group_index = -1 + for index, group in enumerate(action.groups): + if group.name == bone.name: + group_index = index + #@TODO: break? + + if group_index > -1: + for channel in action.groups[group_index].channels: + if channel_type in channel.data_path: + result.append(channel) + + else: + bone_label = '"%s"' % bone.name + for channel in action.fcurves: + data_path = [bone_label in channel.data_path, + channel_type in channel.data_path] + if all(data_path): + result.append(channel) + + return result + + +def _position(bone, frame, action, armature_matrix): + + position = mathutils.Vector((0,0,0)) + change = False + + ngroups = len(action.groups) + + if ngroups > 0: + + index = 0 + + for i in range(ngroups): + if action.groups[i].name == bone.name: + index = i + + for channel in action.groups[index].channels: + if "location" in channel.data_path: + has_changed = _handle_position_channel( + channel, frame, position) + change = change or has_changed + + else: + + bone_label = '"%s"' % bone.name + + for channel in action.fcurves: + data_path = channel.data_path + if bone_label in data_path and \ + "location" in data_path: + has_changed = _handle_position_channel( + channel, frame, position) + change = change or has_changed + + position = position * bone.matrix_local.inverted() + + if bone.parent is None: + + position.x += bone.head.x + position.y += bone.head.y + position.z += bone.head.z + + else: + + parent = bone.parent + + parent_matrix = parent.matrix_local.inverted() + diff = parent.tail_local - parent.head_local + + position.x += (bone.head * parent_matrix).x + diff.x + position.y += (bone.head * parent_matrix).y + diff.y + position.z += (bone.head * parent_matrix).z + diff.z + + return armature_matrix*position, change + + +def _rotation(bone, frame, action, armature_matrix): + + # TODO: calculate rotation also from rotation_euler channels + + rotation = mathutils.Vector((0,0,0,1)) + + change = False + + ngroups = len(action.groups) + + # animation grouped by bones + + if ngroups > 0: + + index = -1 + + for i in range(ngroups): + if action.groups[i].name == bone.name: + index = i + + if index > -1: + for channel in action.groups[index].channels: + if "quaternion" in channel.data_path: + has_changed = _handle_rotation_channel( + channel, frame, rotation) + change = change or has_changed + + # animation in raw fcurves + + else: + + bone_label = '"%s"' % bone.name + + for channel in action.fcurves: + data_path = channel.data_path + if bone_label in data_path and \ + "quaternion" in data_path: + has_changed = _handle_rotation_channel( + channel, frame, rotation) + change = change or has_changed + + rot3 = rotation.to_3d() + rotation.xyz = rot3 * bone.matrix_local.inverted() + rotation.xyz = armature_matrix * rotation.xyz + + return rotation, change + + +def _handle_rotation_channel(channel, frame, rotation): + + change = False + + if channel.array_index in [0, 1, 2, 3]: + + for keyframe in channel.keyframe_points: + if keyframe.co[0] == frame: + change = True + + value = channel.evaluate(frame) + + if channel.array_index == 1: + rotation.x = value + + elif channel.array_index == 2: + rotation.y = value + + elif channel.array_index == 3: + rotation.z = value + + elif channel.array_index == 0: + rotation.w = value + + return change + + +def _handle_position_channel(channel, frame, position): + + change = False + + if channel.array_index in [0, 1, 2]: + for keyframe in channel.keyframe_points: + if keyframe.co[0] == frame: + change = True + + value = channel.evaluate(frame) + + if channel.array_index == 0: + position.x = value + + if channel.array_index == 1: + position.y = value + + if channel.array_index == 2: + position.z = value + + return change diff --git a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py index a75fc90496bd1e..269c0ee7a1c505 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py @@ -1,7 +1,6 @@ import operator -import mathutils from bpy import data, types, context -from . import material, texture +from . import material, texture, animation from . import object as object_ from .. import constants, utilities, logger, exceptions @@ -21,64 +20,57 @@ def inner(name, *args, **kwargs): @_mesh -def animation(mesh, options): +def skeletal_animation(mesh, options): logger.debug('mesh.animation(%s, %s)', mesh, options) armature = _armature(mesh) - animations = [] - if armature: - for action in data.actions: - logger.info('Processing action %s', action.name) - animations.append( - _skeletal_animations(action, armature, options)) - else: - logger.warning('No armature found') + + if not armature: + logger.warning('No armature found (%s)', mesh) + return [] + + anim_type = options.get(constants.ANIMATION) + #pose_position = armature.data.pose_position + dispatch = { + constants.POSE: animation.pose_animation, + constants.REST: animation.rest_animation + } + + func = dispatch[anim_type] + #armature.data.pose_position = anim_type.upper() + animations = func(armature, options) + #armature.data.pose_position = pose_position return animations @_mesh -def bones(mesh): +def bones(mesh, options): logger.debug('mesh.bones(%s)', mesh) armature = _armature(mesh) - bones = [] - bone_map = {} if not armature: - return bones, bone_map + return [], {} - bone_count = 0 - - armature_matrix = armature.matrix_world - for bone_count, pose_bone in enumerate(armature.pose.bones): - armature_bone = pose_bone.bone - bone_index = None - - if armature_bone.parent is None: - bone_matrix = armature_matrix * armature_bone.matrix_local - bone_index = -1 - else: - parent_bone = armature_bone.parent - parent_matrix = armature_matrix * parent_bone.matrix_local - bone_matrix = armature_matrix * armature_bone.matrix_local - bone_matrix = parent_matrix.inverted() * bone_matrix - bone_index = index = 0 - - for pose_parent in armature.pose.bones: - armature_parent = pose_parent.bone.name - if armature_parent == parent_bone.name: - bone_index = index - index += 1 - - bone_map[bone_count] = bone_count + round_off, round_val = utilities.rounding(options) + anim_type = options.get(constants.ANIMATION) + #pose_position = armature.data.pose_position + + if anim_type == constants.OFF: + logger.info('Animation type not set, defaulting '\ + 'to using REST position for the armature.') + func = _rest_bones + #armature.data.pose_position = 'REST' + else: + dispatch = { + constants.REST: _rest_bones, + constants.POSE: _pose_bones + } + logger.info('Using %s for the armature', anim_type) + func = dispatch[anim_type] + #armature.data.pose_position = anim_type.upper() - pos, rot, scl = bone_matrix.decompose() - bones.append({ - constants.PARENT: bone_index, - constants.NAME: armature_bone.name, - constants.POS: (pos.x, pos.z, -pos.y), - constants.ROTQ: (rot.x, rot.z, -rot.y, rot.w), - 'scl': (scl.x, scl.z, scl.y) - }) + bones, bone_map = func(armature, round_off, round_val) + #armature.data.pose_position = pose_position return (bones, bone_map) @@ -146,6 +138,7 @@ def buffer_uv(mesh, options): return uvs_ + @_mesh def faces(mesh, options): logger.debug('mesh.faces(%s, %s)', mesh, options) @@ -154,7 +147,6 @@ def faces(mesh, options): logger.info('Has UVs = %s', vertex_uv) logger.info('Has vertex colours = %s', has_colors) - round_off, round_val = utilities.rounding(options) if round_off: logger.debug('Rounding off of vectors set to %s', round_off) @@ -172,7 +164,19 @@ def faces(mesh, options): vertex_normals = _normals(mesh, options) if opt_normals else None vertex_colours = vertex_colors(mesh) if opt_colours else None - face_data = [] + faces_data = [] + + colour_indices = {} + if vertex_colours: + logger.debug('Indexing colours') + for index, colour in enumerate(vertex_colours): + colour_indices[str(colour)] = index + + normal_indices = {} + if vertex_normals: + logger.debug('Indexing normals') + for index, normal in enumerate(vertex_normals): + normal_indices[str(normal)] = index logger.info('Parsing %d faces', len(mesh.tessfaces)) for face in mesh.tessfaces: @@ -187,20 +191,21 @@ def faces(mesh, options): mask = { constants.QUAD: vert_count is 4, constants.MATERIALS: materials, - constants.UVS: opt_uvs, - constants.NORMALS: opt_normals, - constants.COLORS: opt_colours + constants.UVS: False, + constants.NORMALS: False, + constants.COLORS: False } - face_data.append(utilities.bit_mask(mask)) + face_data = [] face_data.extend([v for v in face.vertices]) if mask[constants.MATERIALS]: face_data.append(face.material_index) - if mask[constants.UVS] and uv_layers: - + #@TODO: this needs the same optimization as what + # was done for colours and normals + if uv_layers: for index, uv_layer in enumerate(uv_layers): layer = mesh.tessface_uv_textures[index] @@ -209,34 +214,38 @@ def faces(mesh, options): if round_off: uv = utilities.round_off(uv, round_val) face_data.append(uv_layer.index(uv)) + mask[constants.UVS] = True - if mask[constants.NORMALS] and vertex_normals: + if vertex_normals: for vertex in face.vertices: normal = mesh.vertices[vertex].normal normal = (normal.x, normal.y, normal.z) if round_off: normal = utilities.round_off(normal, round_val) - face_data.append(vertex_normals.index(normal)) + face_data.append(normal_indices[str(normal)]) + mask[constants.NORMALS] = True - if mask[constants.COLORS]: + if vertex_colours: colours = mesh.tessface_vertex_colors.active.data[face.index] for each in (colours.color1, colours.color2, colours.color3): each = utilities.rgb2int(each) - face_data.append(vertex_colours.index(each)) + face_data.append(colour_indices[str(each)]) + mask[constants.COLORS] = True if mask[constants.QUAD]: colour = utilities.rgb2int(colours.color4) - face_data.append(vertex_colours.index(colour)) + face_data.append(colour_indices[str(colour)]) + + face_data.insert(0, utilities.bit_mask(mask)) + faces_data.extend(face_data) - return face_data + return faces_data @_mesh def morph_targets(mesh, options): logger.debug('mesh.morph_targets(%s, %s)', mesh, options) - #@TODO: consider an attribute for the meshes for determining - # morphs, which would save on so much overhead obj = object_.objects_using_mesh(mesh)[0] original_frame = context.scene.frame_current frame_step = options.get(constants.FRAME_STEP, 1) @@ -244,6 +253,8 @@ def morph_targets(mesh, options): context.scene.frame_end+1, frame_step) morphs = [] + round_off, round_val = utilities.rounding(options) + for frame in scene_frames: logger.info('Processing data at frame %d', frame) context.scene.frame_set(frame, 0.0) @@ -251,8 +262,14 @@ def morph_targets(mesh, options): vertices = object_.extract_mesh(obj, options).vertices[:] for vertex in vertices: - vectors = [round(vertex.co.x, 6), round(vertex.co.y, 6), - round(vertex.co.z, 6)] + if round_off: + vectors = [ + utilities.round_off(vertex.co.x, round_val), + utilities.round_off(vertex.co.y, round_val), + utilities.round_off(vertex.co.z, round_val) + ] + else: + vectors = [vertex.co.x, vertex.co.y, vertex.co.z] morphs[-1].extend(vectors) context.scene.frame_set(original_frame, 0.0) @@ -589,6 +606,7 @@ def _normals(mesh, options): vectors = [] round_off, round_val = utilities.rounding(options) + vectors_ = {} for face in mesh.tessfaces: for vertex_index in face.vertices: @@ -597,8 +615,12 @@ def _normals(mesh, options): if round_off: vector = utilities.round_off(vector, round_val) - if vector not in vectors: + str_vec = str(vector) + try: + vectors_[str_vec] + except KeyError: vectors.append(vector) + vectors_[str_vec] = True return vectors @@ -668,330 +690,118 @@ def _skinning_data(mesh, bone_map, influences, array_index): return manifest -def _find_channels(action, bone, channel_type): - result = [] - - if len(action.groups): - - group_index = -1 - for index, group in enumerate(action.groups): - if group.name == bone.name: - group_index = index - #@TODO: break? - - if group_index > -1: - for channel in action.groups[group_index].channels: - if channel_type in channel.data_path: - result.append(channel) - - else: - bone_label = '"%s"' % bone.name - for channel in action.fcurves: - data_path = [bone_label in channel.data_path, - channel_type in channel.data_path] - if all(data_path): - result.append(channel) - - return result - +def _pose_bones(armature, round_off, round_val): + bones = [] + bone_map = {} + bone_count = 0 -def _skeletal_animations(action, armature, options): - try: - current_context = context.area.type - except AttributeError: - logger.warning('No context, possibly running in batch mode') - else: - context.area.type = 'DOPESHEET_EDITOR' - context.space_data.mode = 'ACTION' - context.area.spaces.active.action = action - armature_matrix = armature.matrix_world - fps = context.scene.render.fps - - end_frame = action.frame_range[1] - start_frame = action.frame_range[0] - frame_length = end_frame - start_frame + for bone_count, pose_bone in enumerate(armature.pose.bones): + armature_bone = pose_bone.bone + bone_index = None - frame_step = options.get(constants.FRAME_STEP, 1) - used_frames = int(frame_length / frame_step) + 1 - - keys = [] - channels_location = [] - channels_rotation = [] - channels_scale = [] - - for pose_bone in armature.pose.bones: - logger.info('Processing channels for %s', - pose_bone.bone.name) - keys.append([]) - channels_location.append( - _find_channels(action, - pose_bone.bone, - 'location')) - channels_rotation.append( - _find_channels(action, - pose_bone.bone, - 'rotation_quaternion')) - channels_rotation.append( - _find_channels(action, - pose_bone.bone, - 'rotation_euler')) - channels_scale.append( - _find_channels(action, - pose_bone.bone, - 'scale')) - - frame_step = options[constants.FRAME_STEP] - frame_index_as_time = options[constants.FRAME_INDEX_AS_TIME] - for frame_index in range(0, used_frames): - if frame_index == used_frames - 1: - frame = end_frame + if armature_bone.parent is None: + bone_matrix = armature_matrix * armature_bone.matrix_local + bone_index = -1 else: - frame = start_frame + frame_index * frame_step - - logger.info('Processing frame %d', frame) - - time = frame - start_frame - if frame_index_as_time is False: - time = time / fps - - context.scene.frame_set(frame) - - bone_index = 0 - - def has_keyframe_at(channels, frame): - def find_keyframe_at(channel, frame): - for keyframe in channel.keyframe_points: - if keyframe.co[0] == frame: - return keyframe - return None + parent_bone = armature_bone.parent + parent_matrix = armature_matrix * parent_bone.matrix_local + bone_matrix = armature_matrix * armature_bone.matrix_local + bone_matrix = parent_matrix.inverted() * bone_matrix + bone_index = index = 0 - for channel in channels: - if not find_keyframe_at(channel, frame) is None: - return True - return False + for pose_parent in armature.pose.bones: + armature_parent = pose_parent.bone.name + if armature_parent == parent_bone.name: + bone_index = index + index += 1 - for pose_bone in armature.pose.bones: - logger.info('Processing bone %s', pose_bone.bone.name) - if pose_bone.parent is None: - bone_matrix = armature_matrix * pose_bone.matrix - else: - parent_matrix = armature_matrix * pose_bone.parent.matrix - bone_matrix = armature_matrix * pose_bone.matrix - bone_matrix = parent_matrix.inverted() * bone_matrix - - pos, rot, scl = bone_matrix.decompose() - - pchange = True or has_keyframe_at( - channels_location[bone_index], frame) - rchange = True or has_keyframe_at( - channels_rotation[bone_index], frame) - schange = True or has_keyframe_at( - channels_scale[bone_index], frame) - - px, py, pz = pos.x, pos.z, -pos.y - rx, ry, rz, rw = rot.x, rot.z, -rot.y, rot.w - sx, sy, sz = scl.x, scl.z, scl.y - - keyframe = {constants.TIME: time} - if frame == start_frame or frame == end_frame: - keyframe.update({ - constants.POS: [px, py, pz], - constants.ROT: [rx, ry, rz, rw], - constants.SCL: [sx, sy, sz] - }) - elif any([pchange, rchange, schange]): - if pchange is True: - keyframe[constants.POS] = [px, py, pz] - if rchange is True: - keyframe[constants.ROT] = [rx, ry, rz, rw] - if schange is True: - keyframe[constants.SCL] = [sx, sy, sz] - - if len(keyframe.keys()) > 1: - logger.info('Recording keyframe data for %s %s', - pose_bone.bone.name, str(keyframe)) - keys[bone_index].append(keyframe) - else: - logger.info('No anim data to record for %s', - pose_bone.bone.name) + bone_map[bone_count] = bone_count - bone_index += 1 - - hierarchy = [] - bone_index = 0 - for pose_bone in armature.pose.bones: - hierarchy.append({ - constants.PARENT: bone_index - 1, - constants.KEYS: keys[bone_index] + pos, rot, scl = bone_matrix.decompose() + if round_off: + pos = ( + utilities.round_off(pos.x, round_val), + utilities.round_off(pos.z, round_val), + -utilities.round_off(pos.y, round_val) + ) + rot = ( + utilities.round_off(rot.x, round_val), + utilities.round_off(rot.z, round_val), + -utilities.round_off(rot.y, round_val), + utilities.round_off(rot.w, round_val) + ) + scl = ( + utilities.round_off(scl.x, round_val), + utilities.round_off(scl.z, round_val), + utilities.round_off(scl.y, round_val) + ) + else: + pos = (pos.x, pos.z, -pos.y) + rot = (rot.x, rot.z, -rot.y, rot.w) + scl = (scl.x, scl.z, scl.y) + bones.append({ + constants.PARENT: bone_index, + constants.NAME: armature_bone.name, + constants.POS: pos, + constants.ROTQ: rot, + constants.SCL: scl }) - bone_index += 1 - - if frame_index_as_time is False: - frame_length = frame_length / fps - - context.scene.frame_set(start_frame) - if context.area: - context.area.type = current_context - - animation = { - constants.HIERARCHY: hierarchy, - constants.LENGTH:frame_length, - constants.FPS: fps, - constants.NAME: action.name - } - - return animation - - -def _position(bone, frame, action, armature_matrix): - - position = mathutils.Vector((0,0,0)) - change = False - - ngroups = len(action.groups) - - if ngroups > 0: - - index = 0 - - for i in range(ngroups): - if action.groups[i].name == bone.name: - index = i - - for channel in action.groups[index].channels: - if "location" in channel.data_path: - has_changed = _handle_position_channel( - channel, frame, position) - change = change or has_changed - - else: - - bone_label = '"%s"' % bone.name - - for channel in action.fcurves: - data_path = channel.data_path - if bone_label in data_path and \ - "location" in data_path: - has_changed = _handle_position_channel( - channel, frame, position) - change = change or has_changed - - position = position * bone.matrix_local.inverted() - - if bone.parent is None: - - position.x += bone.head.x - position.y += bone.head.y - position.z += bone.head.z - - else: - - parent = bone.parent - - parent_matrix = parent.matrix_local.inverted() - diff = parent.tail_local - parent.head_local - - position.x += (bone.head * parent_matrix).x + diff.x - position.y += (bone.head * parent_matrix).y + diff.y - position.z += (bone.head * parent_matrix).z + diff.z - return armature_matrix*position, change + return bones, bone_map -def _rotation(bone, frame, action, armature_matrix): - - # TODO: calculate rotation also from rotation_euler channels - - rotation = mathutils.Vector((0,0,0,1)) - - change = False - - ngroups = len(action.groups) - - # animation grouped by bones - - if ngroups > 0: - - index = -1 - - for i in range(ngroups): - if action.groups[i].name == bone.name: - index = i - - if index > -1: - for channel in action.groups[index].channels: - if "quaternion" in channel.data_path: - has_changed = _handle_rotation_channel( - channel, frame, rotation) - change = change or has_changed - - # animation in raw fcurves - - else: - - bone_label = '"%s"' % bone.name - - for channel in action.fcurves: - data_path = channel.data_path - if bone_label in data_path and \ - "quaternion" in data_path: - has_changed = _handle_rotation_channel( - channel, frame, rotation) - change = change or has_changed - - rot3 = rotation.to_3d() - rotation.xyz = rot3 * bone.matrix_local.inverted() - rotation.xyz = armature_matrix * rotation.xyz - - return rotation, change - - -def _handle_rotation_channel(channel, frame, rotation): - - change = False - - if channel.array_index in [0, 1, 2, 3]: - - for keyframe in channel.keyframe_points: - if keyframe.co[0] == frame: - change = True - - value = channel.evaluate(frame) - - if channel.array_index == 1: - rotation.x = value - - elif channel.array_index == 2: - rotation.y = value - - elif channel.array_index == 3: - rotation.z = value - - elif channel.array_index == 0: - rotation.w = value - - return change - +def _rest_bones(armature, round_off, round_val): + bones = [] + bone_map = {} + bone_count = 0 + bone_index_rel = 0 -def _handle_position_channel(channel, frame, position): + for bone in armature.data.bones: + logger.info('Parsing bone %s', bone.name) - change = False + if not bone.use_deform: + logger.debug('Ignoring bone %s at: %d', + bone.name, bone_index_rel) + continue - if channel.array_index in [0, 1, 2]: - for keyframe in channel.keyframe_points: - if keyframe.co[0] == frame: - change = True + if bone.parent is None: + bone_pos = bone.head_local + bone_index = -1 + else: + bone_pos = bone.head_local - bone.parent.head_local + bone_index = 0 + index = 0 + for parent in armature.data.bones: + if parent.name == bone.parent.name: + bone_index = bone_map.get(index) + index += 1 - value = channel.evaluate(frame) + bone_world_pos = armature.matrix_world * bone_pos + if round_off: + x_axis = utilities.round_off(bone_world_pos.x, round_val) + y_axis = utilities.round_off(bone_world_pos.z, round_val) + z_axis = -utilities.round_off(bone_world_pos.y, round_val) + else: + x_axis = bone_world_pos.x + y_axis = bone_world_pos.z + z_axis = -bone_world_pos.y + + logger.debug('Adding bone %s at: %s, %s', + bone.name, bone_index, bone_index_rel) + bone_map[bone_count] = bone_index_rel + bone_index_rel += 1 + #@TODO: the rotq probably should not have these + # hard coded values + bones.append({ + constants.PARENT: bone_index, + constants.NAME: bone.name, + constants.POS: (x_axis, y_axis, z_axis), + constants.ROTQ: (0,0,0,1) + }) - if channel.array_index == 0: - position.x = value + bone_count += 1 - if channel.array_index == 1: - position.y = value + return (bones, bone_map) - if channel.array_index == 2: - position.z = value - return change diff --git a/utils/exporters/blender/addons/io_three/exporter/base_classes.py b/utils/exporters/blender/addons/io_three/exporter/base_classes.py index 984785d7f3842a..5a9a7019a14b3d 100644 --- a/utils/exporters/blender/addons/io_three/exporter/base_classes.py +++ b/utils/exporters/blender/addons/io_three/exporter/base_classes.py @@ -1,4 +1,4 @@ -import uuid +from . import utilities from .. import constants, exceptions @@ -55,8 +55,11 @@ class BaseNode(BaseClass): def __init__(self, node, parent, type): BaseClass.__init__(self, parent=parent, type=type) self.__node = node - if node is not None: + if node is None: + self[constants.UUID] = utilities.id() + else: self[constants.NAME] = node + self[constants.UUID] = utilities.id_from_name(node) if isinstance(parent, BaseScene): scene = parent @@ -66,9 +69,7 @@ def __init__(self, node, parent, type): scene = None self.__scene = scene - - self[constants.UUID] = str(uuid.uuid4()).upper() - + @property def node(self): return self.__node diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index 563cdf1973ff96..8ba14e1a59b13b 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -292,7 +292,7 @@ def __parse_buffer_geometry(self): if not option: continue - array = func(self.node, self.options) + array = func(self.node, self.options) or [] if not array: logger.warning('No array could be made for %s', key) continue @@ -307,37 +307,38 @@ def __parse_geometry(self): if self.options.get(constants.VERTICES): logger.info('Parsing %s', constants.VERTICES) self[constants.VERTICES] = api.mesh.vertices( - self.node, self.options) - - if self.options.get(constants.FACES): - logger.info('Parsing %s', constants.FACES) - self[constants.FACES] = api.mesh.faces( - self.node, self.options) + self.node, self.options) or [] if self.options.get(constants.NORMALS): logger.info('Parsing %s', constants.NORMALS) self[constants.NORMALS] = api.mesh.normals( - self.node, self.options) + self.node, self.options) or [] if self.options.get(constants.COLORS): logger.info('Parsing %s', constants.COLORS) self[constants.COLORS] = api.mesh.vertex_colors( - self.node) + self.node) or [] if self.options.get(constants.FACE_MATERIALS): logger.info('Parsing %s', constants.FACE_MATERIALS) self[constants.MATERIALS] = api.mesh.materials( - self.node, self.options) + self.node, self.options) or [] if self.options.get(constants.UVS): logger.info('Parsing %s', constants.UVS) self[constants.UVS] = api.mesh.uvs( - self.node, self.options) + self.node, self.options) or [] - if self.options.get(constants.ANIMATION): + if self.options.get(constants.FACES): + logger.info('Parsing %s', constants.FACES) + self[constants.FACES] = api.mesh.faces( + self.node, self.options) or [] + + no_anim = (None, False, constants.OFF) + if self.options.get(constants.ANIMATION) not in no_anim: logger.info('Parsing %s', constants.ANIMATION) - self[constants.ANIMATION] = api.mesh.animation( - self.node, self.options) + self[constants.ANIMATION] = api.mesh.skeletal_animation( + self.node, self.options) or [] #@TODO: considering making bones data implied when # querying skinning data @@ -345,7 +346,7 @@ def __parse_geometry(self): bone_map = {} if self.options.get(constants.BONES): logger.info('Parsing %s', constants.BONES) - bones, bone_map = api.mesh.bones(self.node) + bones, bone_map = api.mesh.bones(self.node, self.options) self[constants.BONES] = bones if self.options.get(constants.SKINNING): diff --git a/utils/exporters/blender/addons/io_three/exporter/io.py b/utils/exporters/blender/addons/io_three/exporter/io.py index e547b282087dc4..bc582cf1e57666 100644 --- a/utils/exporters/blender/addons/io_three/exporter/io.py +++ b/utils/exporters/blender/addons/io_three/exporter/io.py @@ -1,7 +1,5 @@ import os -import sys import shutil -import traceback from .. import constants, logger from . import _json @@ -18,21 +16,8 @@ def copy(src, dst): file_name = os.path.basename(src) dst = os.path.join(dst, file_name) - if os.path.exists(dst): - - logger.info('Destination file exists, attempting to remove %s', dst) - try: - os.remove(dst) - except: - logger.error('Failed to remove destination file') - info = sys.exc_info() - trace = traceback.format_exception( - info[0], info[1], info[2].tb_next) - trace = ''.join(trace) - logger.error(trace) - raise - - shutil.copy(src, dst) + if src != dst: + shutil.copy(src, dst) def dump(filepath, data, options=None): @@ -57,8 +42,10 @@ def dump(filepath, data, options=None): else: _json.ROUND = None + indent = options.get(constants.INDENT, True) + indent = 4 if indent else None logger.info('Dumping to JSON') - func = lambda x,y: _json.json.dump(x, y, indent=4) + func = lambda x,y: _json.json.dump(x, y, indent=indent) mode = 'w' logger.info('Writing to %s', filepath) diff --git a/utils/exporters/blender/addons/io_three/exporter/scene.py b/utils/exporters/blender/addons/io_three/exporter/scene.py index cb182a8b401afb..512cf967503077 100644 --- a/utils/exporters/blender/addons/io_three/exporter/scene.py +++ b/utils/exporters/blender/addons/io_three/exporter/scene.py @@ -6,6 +6,7 @@ material, geometry, object, + utilities, io, api ) @@ -74,7 +75,7 @@ def write(self): data = {} embed_anim = self.options.get(constants.EMBED_ANIMATION, True) - embed = self.options[constants.EMBED_GEOMETRY] + embed = self.options.get(constants.EMBED_GEOMETRY, True) compression = self.options.get(constants.COMPRESSION) extension = constants.EXTENSIONS.get(compression, @@ -167,8 +168,13 @@ def __parse_materials(self): def __parse_objects(self): logger.debug('Scene().__parse_objects()') + try: + scene_name = self[constants.METADATA][constants.SOURCE_FILE] + except KeyError: + scene_name = constants.SCENE self[constants.OBJECT] = object.Object(None, parent=self) self[constants.OBJECT][constants.TYPE] = constants.SCENE.title() + self[constants.UUID] = utilities.id_from_name(scene_name) objects = [] for node in api.object.nodes(self.valid_types, self.options): diff --git a/utils/exporters/blender/addons/io_three/exporter/utilities.py b/utils/exporters/blender/addons/io_three/exporter/utilities.py index 7bf5238617fd33..021a8b31cc5d95 100644 --- a/utils/exporters/blender/addons/io_three/exporter/utilities.py +++ b/utils/exporters/blender/addons/io_three/exporter/utilities.py @@ -28,6 +28,9 @@ def hash(value): def id(): return str(uuid.uuid4()).upper() +def id_from_name(name): + return str(uuid.uuid3(uuid.NAMESPACE_DNS, name)).upper() + def rgb2int(rgb): is_tuple = isinstance(rgb, tuple) diff --git a/utils/exporters/blender/tests/scripts/test_geometry_normals.bash b/utils/exporters/blender/tests/scripts/test_geometry_normals.bash index 03d9b08b3dbcfb..89b923b96b8d56 100755 --- a/utils/exporters/blender/tests/scripts/test_geometry_normals.bash +++ b/utils/exporters/blender/tests/scripts/test_geometry_normals.bash @@ -4,5 +4,5 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source "$DIR/setup_test_env.bash" blender --background $BLEND/torusA.blend --python $PYSCRIPT -- \ - $JSON --vertices --faces --normals + $JSON --vertices --faces --normals --indent makereview $@ --tag $(tagname) diff --git a/utils/exporters/blender/tests/scripts/test_scene_instancing.bash b/utils/exporters/blender/tests/scripts/test_scene_instancing.bash index 4e6cbed83ac8b5..5e93d6e1d0dfda 100755 --- a/utils/exporters/blender/tests/scripts/test_scene_instancing.bash +++ b/utils/exporters/blender/tests/scripts/test_scene_instancing.bash @@ -5,5 +5,5 @@ source "$DIR/setup_test_env.bash" blender --background $BLEND/scene_instancing.blend --python $PYSCRIPT -- \ $JSON --vertices --faces --scene --materials --enablePrecision \ - --precision 4 --embedGeometry + --precision 4 --embedGeometry --indent makereview $@ --tag $(tagname) From 44b89989625616636c5ecd340b6515c95331b87f Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Feb 2015 08:58:28 -0800 Subject: [PATCH 108/333] APP: Added event.delta. --- editor/examples/arkanoid.app.json | 9 +++++---- editor/examples/pong.app.json | 8 ++++---- editor/js/Sidebar.Script.js | 2 +- editor/js/libs/app.js | 7 +++++-- 4 files changed, 15 insertions(+), 11 deletions(-) mode change 100644 => 100755 editor/examples/arkanoid.app.json mode change 100644 => 100755 editor/examples/pong.app.json diff --git a/editor/examples/arkanoid.app.json b/editor/examples/arkanoid.app.json old mode 100644 new mode 100755 index 84d6e41f1091d5..b643cba08c2e34 --- a/editor/examples/arkanoid.app.json +++ b/editor/examples/arkanoid.app.json @@ -6,7 +6,7 @@ "generator": "ObjectExporter" }, "object": { - "uuid": "A32F9E56-4DDC-442E-8A0D-F23B9E93EEA9", + "uuid": "8EFB9C06-6312-4975-B04A-C9E4549BE348", "type": "PerspectiveCamera", "name": "Camera", "fov": 50, @@ -107,7 +107,7 @@ "name": "Ground", "geometry": "8F05A1F2-3877-478B-8DFC-F572AC61AB3A", "material": "2F69AF3A-DDF5-4BBA-87B5-80159F90DDBF", - "matrix": [1,0,0,0,0,0.0007962886593304574,-0.9999997019767761,0,0,0.9999997019767761,0.0007962886593304574,0,0,0,0,1] + "matrix": [1,0,0,0,0,0.000796250649727881,-0.9999997019767761,0,0,0.9999997019767761,0.000796250649727881,0,0,0,0,1] }, { "uuid": "6EE2E764-43E0-48E0-85F2-E0C8823C20DC", @@ -148,6 +148,7 @@ "color": 16777215, "intensity": 1, "distance": 0, + "decay": 1, "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,-116.54356384277344,69.48957061767578,-206.8248291015625,1] }] } @@ -161,7 +162,7 @@ "31517222-A9A7-4EAF-B5F6-60751C0BABA3": [ { "name": "Game Logic", - "source": "var ball = this.getObjectByName( 'Ball' );\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = - 0.5;\ndirection.normalize();\n\nvar speed = new THREE.Vector3();\n\n//\n\nvar group = new THREE.Group();\nthis.add( group );\n\nvar paddle = this.getObjectByName( 'Paddle' );\ngroup.add( paddle );\n\nvar brick = this.getObjectByName( 'Brick' );\n\nfor ( var j = 0; j < 8; j ++ ) {\n\n\tvar material = new THREE.MeshPhongMaterial( { color: Math.random() * 0xffffff } );\n\n\tfor ( var i = 0; i < 12; i ++ ) {\n\t\t\n\t\tvar object = brick.clone();\n\t\tobject.material = material;\n\t\tobject.position.x = i * 22 - 120;\n\t\tobject.position.z = j * 14 - 120;\n\t\tgroup.add( object );\n\t\t\n\t}\n\t\n}\n\nbrick.visible = false;\n\n//\n\nvar raycaster = new THREE.Raycaster();\n\nfunction update( event ) {\n\t\n\tif ( ball.position.x < - 150 || ball.position.x > 150 ) direction.x = - direction.x;\n\tif ( ball.position.z < - 200 || ball.position.z > 200 ) direction.z = - direction.z;\n\n\tball.position.add( speed.copy( direction ).multiplyScalar( 4 ) );\n\t\n\traycaster.set( ball.position, direction );\n\t\n\tvar intersections = raycaster.intersectObjects( group.children );\n\t\n\tif ( intersections.length > 0 ) {\n\t\n\t\tvar intersection = intersections[ 0 ];\n\t\t\n\t\tif ( intersection.distance < 5 ) {\n\t\t\t\n\t\t\tif ( intersection.object !== paddle ) {\n\n\t\t\t\tgroup.remove( intersection.object );\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tdirection.reflect( intersection.face.normal );\n\t\t\t\n\t\t}\n\t\t\n\t}\n\n}" + "source": "var ball = this.getObjectByName( 'Ball' );\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = - 0.5;\ndirection.normalize();\n\nvar speed = new THREE.Vector3();\n\n//\n\nvar group = new THREE.Group();\nthis.add( group );\n\nvar paddle = this.getObjectByName( 'Paddle' );\ngroup.add( paddle );\n\nvar brick = this.getObjectByName( 'Brick' );\n\nfor ( var j = 0; j < 8; j ++ ) {\n\n\tvar material = new THREE.MeshPhongMaterial( { color: Math.random() * 0xffffff } );\n\n\tfor ( var i = 0; i < 12; i ++ ) {\n\t\t\n\t\tvar object = brick.clone();\n\t\tobject.material = material;\n\t\tobject.position.x = i * 22 - 120;\n\t\tobject.position.z = j * 14 - 120;\n\t\tgroup.add( object );\n\t\t\n\t}\n\t\n}\n\nbrick.visible = false;\n\n//\n\nvar raycaster = new THREE.Raycaster();\n\nfunction update( event ) {\n\t\n\tif ( ball.position.x < - 150 || ball.position.x > 150 ) direction.x = - direction.x;\n\tif ( ball.position.z < - 200 || ball.position.z > 200 ) direction.z = - direction.z;\n\n\tball.position.add( speed.copy( direction ).multiplyScalar( event.delta / 4 ) );\n\t\n\traycaster.set( ball.position, direction );\n\t\n\tvar intersections = raycaster.intersectObjects( group.children );\n\t\n\tif ( intersections.length > 0 ) {\n\t\n\t\tvar intersection = intersections[ 0 ];\n\t\t\n\t\tif ( intersection.distance < 5 ) {\n\t\t\t\n\t\t\tif ( intersection.object !== paddle ) {\n\n\t\t\t\tgroup.remove( intersection.object );\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tdirection.reflect( intersection.face.normal );\n\t\t\t\n\t\t}\n\t\t\n\t}\n\n}" }] } -} +} \ No newline at end of file diff --git a/editor/examples/pong.app.json b/editor/examples/pong.app.json old mode 100644 new mode 100755 index 69cd7a762bb027..fd04fc724049eb --- a/editor/examples/pong.app.json +++ b/editor/examples/pong.app.json @@ -6,7 +6,7 @@ "generator": "ObjectExporter" }, "object": { - "uuid": "E5C76691-3D55-4E26-862E-24BADC21F4D7", + "uuid": "8EFB9C06-6312-4975-B04A-C9E4549BE348", "type": "PerspectiveCamera", "name": "Camera", "fov": 50, @@ -88,7 +88,7 @@ "name": "Ground", "geometry": "77B20ED1-2871-4B14-A652-8F823B2A817E", "material": "7EDF7C08-6325-418A-BBAB-89341C694730", - "matrix": [1,0,0,0,0,0.0007961748051457107,-0.9999997019767761,0,0,0.9999997019767761,0.0007961748051457107,0,0,-10,0,1] + "matrix": [1,0,0,0,0,0.0007960614748299122,-0.9999997019767761,0,0,0.9999997019767761,0.0007960614748299122,0,0,-10,0,1] }, { "uuid": "CE13E58A-4E8B-4F72-9E2E-7DE57C58F989", @@ -128,7 +128,7 @@ "31517222-A9A7-4EAF-B5F6-60751C0BABA3": [ { "name": "Game logic", - "source": "var ball = this.getObjectByName( 'Ball' );\n\nvar position = ball.position;\n\nvar velocity = new THREE.Vector3();\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = Math.random() - 0.5;\ndirection.normalize();\n\nvar pad1 = this.getObjectByName( 'Pad 1' );\nvar pad2 = this.getObjectByName( 'Pad 2' );\n\nvar raycaster = new THREE.Raycaster();\nvar objects = [ pad1, pad2 ];\n\n//\n\nfunction mousemove( event ) {\n\n\tpad1.position.z = ( event.clientX / player.width ) * 300 - 150;\n\tpad2.position.z = - pad1.position.z;\n\n}\n\nfunction update( event ) {\n\n\tif ( position.x < -300 || position.x > 300 ) {\n\t\t\n\t\tdirection.x = - direction.x;\n\t\t\n\t}\n\n\tif ( position.z < -200 || position.z > 200 ) {\n\t\t\n\t\tdirection.z = - direction.z;\n\t\t\n\t}\n\t\n\traycaster.set( position, direction );\n\t\n\tvar intersections = raycaster.intersectObjects( objects );\n\t\n\tif ( intersections.length > 0 ) {\n\n\t\tvar intersection = intersections[ 0 ];\n\t\t\n\t\tif ( intersection.distance < 10 ) {\n\t\t\t\n\t\t\tdirection.reflect( intersection.face.normal );\n\t\t\t\n\t\t}\n\t\t\n\t}\n\n\tposition.add( velocity.copy( direction ).multiplyScalar( 8 ) );\n\n}" + "source": "var ball = this.getObjectByName( 'Ball' );\n\nvar position = ball.position;\n\nvar velocity = new THREE.Vector3();\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = Math.random() - 0.5;\ndirection.normalize();\n\nvar pad1 = this.getObjectByName( 'Pad 1' );\nvar pad2 = this.getObjectByName( 'Pad 2' );\n\nvar raycaster = new THREE.Raycaster();\nvar objects = [ pad1, pad2 ];\n\n//\n\nfunction mousemove( event ) {\n\n\tpad1.position.z = ( event.clientX / player.width ) * 300 - 150;\n\tpad2.position.z = - pad1.position.z;\n\n}\n\nfunction update( event ) {\n\n\tif ( position.x < -300 || position.x > 300 ) {\n\t\t\n\t\tdirection.x = - direction.x;\n\t\t\n\t}\n\n\tif ( position.z < -200 || position.z > 200 ) {\n\t\t\n\t\tdirection.z = - direction.z;\n\t\t\n\t}\n\t\n\traycaster.set( position, direction );\n\t\n\tvar intersections = raycaster.intersectObjects( objects );\n\t\n\tif ( intersections.length > 0 ) {\n\n\t\tvar intersection = intersections[ 0 ];\n\t\t\n\t\tif ( intersection.distance < 10 ) {\n\t\t\t\n\t\t\tdirection.reflect( intersection.face.normal );\n\t\t\t\n\t\t}\n\t\t\n\t}\n\n\tposition.add( velocity.copy( direction ).multiplyScalar( event.delta / 2 ) );\n\n}" }] } -} +} \ No newline at end of file diff --git a/editor/js/Sidebar.Script.js b/editor/js/Sidebar.Script.js index 92b7cda5b22249..dc7e5acae92d87 100644 --- a/editor/js/Sidebar.Script.js +++ b/editor/js/Sidebar.Script.js @@ -84,7 +84,7 @@ Sidebar.Script = function ( editor ) { } ); scriptsContainer.add( remove ); - + scriptsContainer.add( new UI.Break() ); } )( object, scripts[ i ] ) diff --git a/editor/js/libs/app.js b/editor/js/libs/app.js index 8c73e54c0735e9..c4c4d5bda0e935 100644 --- a/editor/js/libs/app.js +++ b/editor/js/libs/app.js @@ -102,16 +102,18 @@ var APP = { }; - var request; + var prevTime, request; var animate = function ( time ) { request = requestAnimationFrame( animate ); - dispatch( events.update, { time: time } ); + dispatch( events.update, { time: time, delta: time - prevTime } ); renderer.render( scene, camera ); + prevTime = time; + }; this.play = function () { @@ -126,6 +128,7 @@ var APP = { document.addEventListener( 'touchmove', onDocumentTouchMove ); request = requestAnimationFrame( animate ); + prevTime = performance.now(); }; From 632854fae084cee0310537dd11ad9e5285ff5ecb Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Feb 2015 10:06:04 -0800 Subject: [PATCH 109/333] Editor: Renamed setObjectName to nameObject. --- editor/js/Editor.js | 2 +- editor/js/Sidebar.Object3D.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/js/Editor.js b/editor/js/Editor.js index f2cf486c4f6534..d5572760df4ea2 100644 --- a/editor/js/Editor.js +++ b/editor/js/Editor.js @@ -155,7 +155,7 @@ Editor.prototype = { }, - setObjectName: function ( object, name ) { + nameObject: function ( object, name ) { object.name = name; this.signals.sceneGraphChanged.dispatch(); diff --git a/editor/js/Sidebar.Object3D.js b/editor/js/Sidebar.Object3D.js index 9c390a88d175b2..2fc12b39448d47 100644 --- a/editor/js/Sidebar.Object3D.js +++ b/editor/js/Sidebar.Object3D.js @@ -81,7 +81,7 @@ Sidebar.Object3D = function ( editor ) { var objectNameRow = new UI.Panel(); var objectName = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () { - editor.setObjectName( editor.selected, objectName.getValue() ); + editor.nameObject( editor.selected, objectName.getValue() ); } ); From 70544e278708a290118dfcccf7a552a085e5ccc7 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Feb 2015 10:08:44 -0800 Subject: [PATCH 110/333] Editor: Renamed parent() to moveObject(). --- editor/js/Editor.js | 50 +++++++++++++++++------------------ editor/js/Sidebar.Object3D.js | 2 +- editor/js/libs/ui.three.js | 4 +-- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/editor/js/Editor.js b/editor/js/Editor.js index d5572760df4ea2..d5a45fa20601e9 100644 --- a/editor/js/Editor.js +++ b/editor/js/Editor.js @@ -155,6 +155,30 @@ Editor.prototype = { }, + moveObject: function ( object, parent, before ) { + + if ( parent === undefined ) { + + parent = this.scene; + + } + + parent.add( object ); + + // sort children array + + if ( before !== undefined ) { + + var index = parent.children.indexOf( before ); + parent.children.splice( index, 0, object ); + parent.children.pop(); + + } + + this.signals.sceneGraphChanged.dispatch(); + + }, + nameObject: function ( object, name ) { object.name = name; @@ -319,32 +343,6 @@ Editor.prototype = { // - parent: function ( object, parent, before ) { - - if ( parent === undefined ) { - - parent = this.scene; - - } - - parent.add( object ); - - // sort children array - - if ( before !== undefined ) { - - var index = parent.children.indexOf( before ); - parent.children.splice( index, 0, object ); - parent.children.pop(); - - } - - this.signals.sceneGraphChanged.dispatch(); - - }, - - // - select: function ( object ) { if ( this.selected === object ) return; diff --git a/editor/js/Sidebar.Object3D.js b/editor/js/Sidebar.Object3D.js index 2fc12b39448d47..a8405a5a38e766 100644 --- a/editor/js/Sidebar.Object3D.js +++ b/editor/js/Sidebar.Object3D.js @@ -343,7 +343,7 @@ Sidebar.Object3D = function ( editor ) { if ( object.parent.id !== newParentId && object.id !== newParentId ) { - editor.parent( object, editor.scene.getObjectById( newParentId ) ); + editor.moveObject( object, editor.scene.getObjectById( newParentId ) ); } diff --git a/editor/js/libs/ui.three.js b/editor/js/libs/ui.three.js index a5a7b3272c6fcb..0d2842d1c187b9 100644 --- a/editor/js/libs/ui.three.js +++ b/editor/js/libs/ui.three.js @@ -158,12 +158,12 @@ UI.Outliner = function ( editor ) { if ( item.nextSibling === null ) { - editor.parent( object, editor.scene ); + editor.moveObject( object, editor.scene ); } else { var nextObject = scene.getObjectById( item.nextSibling.value ); - editor.parent( object, nextObject.parent, nextObject ); + editor.moveObject( object, nextObject.parent, nextObject ); } From 8ff2776e28bfedb4415197ea4ca39b67a63818d9 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Feb 2015 10:09:39 -0800 Subject: [PATCH 111/333] Editor: Fixed objectActions on OSX. --- editor/js/Sidebar.Object3D.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/editor/js/Sidebar.Object3D.js b/editor/js/Sidebar.Object3D.js index a8405a5a38e766..b2b0394e3b942f 100644 --- a/editor/js/Sidebar.Object3D.js +++ b/editor/js/Sidebar.Object3D.js @@ -29,7 +29,10 @@ Sidebar.Object3D = function ( editor ) { } ); objectActions.onClick( function ( event ) { - event.stopPropagation(); + event.stopPropagation(); // Avoid panel collapsing + + } ); + objectActions.onChange( function ( event ) { var object = editor.selected; From d93bddce95760e3a1289706c9225bf3b22d5ed2e Mon Sep 17 00:00:00 2001 From: repsac Date: Mon, 9 Feb 2015 16:28:43 -0800 Subject: [PATCH 112/333] Scenes support object hierarchies Fixed an issue were rotations were being recorded as Euler and not as Quaternion Fixed an issue were duplicate geometries were being recorded to the scene --- .../addons/io_three/exporter/api/object.py | 91 +++++++++++-------- .../addons/io_three/exporter/object.py | 10 +- .../blender/addons/io_three/exporter/scene.py | 8 +- 3 files changed, 63 insertions(+), 46 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/object.py b/utils/exporters/blender/addons/io_three/exporter/api/object.py index 4c4716e58095ee..2429ea6369fadd 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/object.py @@ -46,14 +46,16 @@ def inner(name, *args, **kwargs): return inner -def assemblies(valid_types): +def assemblies(valid_types, options): logger.debug('object.assemblies(%s)', valid_types) for obj in data.objects: - if not obj.parent and obj.type in valid_types: - yield obj.name - elif obj.parent and not obj.parent.parent \ - and obj.parent.type == ARMATURE: + + # rigged assets are parented under armature nodes + if obj.parent and obj.parent.type != ARMATURE: + continue + if obj.parent and obj.parent.type == ARMATURE: logger.info('Has armature parent %s', obj.name) + if _valid_node(obj, valid_types, options): yield obj.name @@ -152,38 +154,15 @@ def node_type(obj): def nodes(valid_types, options): - visible_layers = _visible_scene_layers() for obj in data.objects: - # skip objects that are not on visible layers - if not _on_visible_layer(obj, visible_layers): - continue - try: - export = obj.THREE_export - except AttributeError: - export = True - - mesh_node = mesh(obj, options) - is_mesh = obj.type == MESH - - # skip objects that a mesh could not be resolved - if is_mesh and not mesh_node: - continue - - # secondary test; if a mesh node was resolved but no - # faces are detected then bow out - if is_mesh: - mesh_node = data.meshes[mesh_node] - if len(mesh_node.tessfaces) is 0: - continue - - if obj.type in valid_types and export: + if _valid_node(obj, valid_types, options): yield obj.name - @_object def position(obj, options): logger.debug('object.position(%s)', obj) - vector = _matrix(obj)[0] + parent = obj.parent is None + vector = _decompose_matrix(obj, local=not parent)[0] vector = (vector.x, vector.y, vector.z) round_off, round_val = utilities.rounding(options) @@ -206,8 +185,8 @@ def receive_shadow(obj): @_object def rotation(obj, options): logger.debug('object.rotation(%s)', obj) - vector = _matrix(obj)[1].to_euler(ZYX) - vector = (vector.x, vector.y, vector.z) + vector = _decompose_matrix(obj)[1] + vector = (vector.x, vector.y, vector.z, vector.w) round_off, round_val = utilities.rounding(options) if round_off: @@ -219,7 +198,7 @@ def rotation(obj, options): @_object def scale(obj, options): logger.debug('object.scale(%s)', obj) - vector = _matrix(obj)[2] + vector = _decompose_matrix(obj)[2] vector = (vector.x, vector.y, vector.z) round_off, round_val = utilities.rounding(options) @@ -381,8 +360,11 @@ def extracted_meshes(): return [key for key in _MESH_MAP.keys()] -def _matrix(obj): - matrix = ROTATE_X_PI2 * obj.matrix_world +def _decompose_matrix(obj, local=False): + if local: + matrix = ROTATE_X_PI2 * obj.matrix_local + else: + matrix = ROTATE_X_PI2 * obj.matrix_world return matrix.decompose() @@ -401,3 +383,40 @@ def _visible_scene_layers(): for index, layer in enumerate(context.scene.layers): if layer: visible_layers.append(index) return visible_layers + + +def _valid_node(obj, valid_types, options): + if obj.type not in valid_types: + return False + + # skip objects that are not on visible layers + visible_layers = _visible_scene_layers() + if not _on_visible_layer(obj, visible_layers): + return False + + try: + export = obj.THREE_export + except AttributeError: + export = True + if not export: + return False + + mesh_node = mesh(obj, options) + is_mesh = obj.type == MESH + + # skip objects that a mesh could not be resolved + if is_mesh and not mesh_node: + return False + + # secondary test; if a mesh node was resolved but no + # faces are detected then bow out + if is_mesh: + mesh_node = data.meshes[mesh_node] + if len(mesh_node.tessfaces) is 0: + return False + + # if we get this far assume that the mesh is valid + return True + + + diff --git a/utils/exporters/blender/addons/io_three/exporter/object.py b/utils/exporters/blender/addons/io_three/exporter/object.py index 1f43024a353574..ba9a5f2d86eac1 100644 --- a/utils/exporters/blender/addons/io_three/exporter/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/object.py @@ -105,11 +105,11 @@ def __node_setup(self): elif self[constants.TYPE] in lights: self.__init_light() - #for child in api.object.children(self.node, self.scene.valid_types): - # if not self.get(constants.CHILDREN): - # self[constants.CHILDREN] = [Object(child, parent=self)] - # else: - # self[constants.CHILDREN].append(Object(child, parent=self)) + for child in api.object.children(self.node, self.scene.valid_types): + if not self.get(constants.CHILDREN): + self[constants.CHILDREN] = [Object(child, parent=self)] + else: + self[constants.CHILDREN].append(Object(child, parent=self)) def __root_setup(self): logger.debug('Object().__root_setup()') diff --git a/utils/exporters/blender/addons/io_three/exporter/scene.py b/utils/exporters/blender/addons/io_three/exporter/scene.py index 512cf967503077..39986dfbc7ae6c 100644 --- a/utils/exporters/blender/addons/io_three/exporter/scene.py +++ b/utils/exporters/blender/addons/io_three/exporter/scene.py @@ -91,13 +91,11 @@ def write(self): if not embed_anim: geometry.write_animation(export_dir) + geom_data = geometry.copy() if embed: - for each in value: - geometries.append(each.copy()) + geometries.append(geom_data) continue - geom_data = geometry.copy() - geo_type = geom_data[constants.TYPE].lower() if geo_type == constants.GEOMETRY.lower(): geom_data.pop(constants.DATA) @@ -177,7 +175,7 @@ def __parse_objects(self): self[constants.UUID] = utilities.id_from_name(scene_name) objects = [] - for node in api.object.nodes(self.valid_types, self.options): + for node in api.object.assemblies(self.valid_types, self.options): logger.info('Parsing object %s', node) obj = object.Object(node, parent=self[constants.OBJECT]) objects.append(obj) From 8e328ff4bb6f406807be58cb4eaaa27f6730e265 Mon Sep 17 00:00:00 2001 From: repsac Date: Mon, 9 Feb 2015 20:52:48 -0800 Subject: [PATCH 113/333] MeshBasicMaterials no longer get emissive and ambient values Added a test scene for scenes with children --- .../blender/addons/io_three/__init__.py | 2 +- .../addons/io_three/exporter/api/object.py | 1 - .../addons/io_three/exporter/material.py | 11 ++++++----- .../blender/tests/blend/scene_children.blend | Bin 0 -> 449252 bytes .../blender/tests/scripts/js/review.js | 4 ++++ .../tests/scripts/test_scene_children.bash | 9 +++++++++ 6 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 utils/exporters/blender/tests/blend/scene_children.blend create mode 100755 utils/exporters/blender/tests/scripts/test_scene_children.bash diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 6639a4db83be0d..9b904ba042a4cb 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -41,7 +41,7 @@ bl_info = { 'name': 'Three.js Format', 'author': 'repsac, mrdoob, yomotsu, mpk, jpweeks', - 'version': (1, 1, 1), + 'version': (1, 2, 1), 'blender': (2, 7, 3), 'location': 'File > Import-Export', 'description': 'Export Three.js formatted JSON files.', diff --git a/utils/exporters/blender/addons/io_three/exporter/api/object.py b/utils/exporters/blender/addons/io_three/exporter/api/object.py index 2429ea6369fadd..e104422bf2317a 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/object.py @@ -17,7 +17,6 @@ PERSP, ORTHO, RENDER, - ZYX, NO_SHADOW ) diff --git a/utils/exporters/blender/addons/io_three/exporter/material.py b/utils/exporters/blender/addons/io_three/exporter/material.py index 122b410ffc2337..46b001d00202ad 100644 --- a/utils/exporters/blender/addons/io_three/exporter/material.py +++ b/utils/exporters/blender/addons/io_three/exporter/material.py @@ -26,14 +26,15 @@ def __common_attributes(self): shader_type = api.material.type(self.node) self[constants.TYPE] = dispatch[shader_type] - ambient = api.material.ambient_color(self.node) - self[constants.AMBIENT] = utilities.rgb2int(ambient) - diffuse = api.material.diffuse_color(self.node) self[constants.COLOR] = utilities.rgb2int(diffuse) - emissive = api.material.emissive_color(self.node) - self[constants.EMISSIVE] = utilities.rgb2int(emissive) + if self[constants.TYPE] != constants.THREE_BASIC: + ambient = api.material.ambient_color(self.node) + self[constants.AMBIENT] = utilities.rgb2int(ambient) + + emissive = api.material.emissive_color(self.node) + self[constants.EMISSIVE] = utilities.rgb2int(emissive) vertex_color = api.material.use_vertex_colors(self.node) self[constants.VERTEX_COLORS] = vertex_color diff --git a/utils/exporters/blender/tests/blend/scene_children.blend b/utils/exporters/blender/tests/blend/scene_children.blend new file mode 100644 index 0000000000000000000000000000000000000000..5d857d8b0db436642f0873f38a4005d362253e73 GIT binary patch literal 449252 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�bq>C~Y|7^6v`m+4B zn$wQMZ_C;OVNNjSDIm|?0-e$L+L=6d_Uh?(%Jm1Fp^h%lcUK^PYP)BNb1s%gfB!Zu zu9VR|T;<_B{(pkzBNs5Wud8$}g5I4@e3vxu{0sXf;BuZ700VIl4@DpWib64$e#o85 z|AM&7D(+s*7&T}GU3SPIiSMA}b}_D7)_Ri@cp=OrC_%hrNP&`23R0moq`C1{8O(Gj z3mTuCr~b;}o&n{d0#wAW63oM|GWIGwR|U<{s$s7VH9+6_nl57%sExf2VWfMpE@me7 zdQjhe$Z9}2vRr?B-4MS<&=|iam`yR8VP->fXaPCU5^~*XR=QVq=>n9#y)3I0?yZT_ zfI4o&b6W_5bb{+$ZpU*U>OBv$J#--Ka_YS!&z*P<)3!I#I?#PX?4fYO!KD;MEYb0Su0rO#NH11g3z^*b+#hj+_%-5!q2kGFL zfq6IXGjYGi_1ELIC(1cU@B1+eKm8w&WHdJ0z)DFZ?Ox_y{O$vVor0-!{X2d1?>tX- z`6!b9*dJOYp6H=A$rV?3wwK0QwSC*Vo!Pl4{HUBfr&Y22P6 z>>PNO=Yl{#`g*^7&tZQa_ZQq=W-jK7@DjX?`(olwL&m(g>u6I7@7K#K_`S;S_nOM7X|MBM&U3FbZxGhc*8nffo9;l9h^A_8#9&u@@ZTHlkH1COx8WU_ z?+)TO9YnZ6gkwB~TlCyT*cwc2D{tr;p`6KlGyg?;S{r+xaACA-J7~)O!0lr`#Qkz! z`k9X?=K}Xy^D*w95OyJa>JBg~69$__?)9c28nf9gBhC5fbGX5%B`)^*m+1V6yK)?& z)>vyjZ9?z)XXN4EuoOOrFJKvR)rTFXd|&eX6~z|X|j8NiL?{1;?ygiY>zeyw+`&93@4&JL5Ot)M)G3A@dG z*Gh}|tN&}uOvKOgc4QX*9|Y=~ci^@YcEN79k+lc*B5xn0@U7dAsdx4O{s-Y#IOL|V zXAtdk(7{JOkHArg?mg%o3!|M}zvnUBlL)V|-Eqor0vRXalsnXWuTJyanLH-5%2&jy zX#GZb&C?3-|J@y8Ub6FPTlv&NKEI#Z1$X6;bB1td-C@kp6lRz?=W1p;oN&Vl$2Srg z=LsX-Ac`}AoedY*Ex=#DH5vnGFBjZ=a}hazk&pNA*urMYCFJ|-_kP^k@#hJx?~&$` z{3@Za6$mMxq!YT_hT=k`3PteKd)0`(HX*c}wAi8Lz(+Cs)V8`u){PRe7YE7F{91F^ zV2Bkmo^4DATnIrDlz=>I1@|3TlL%#4DG_TqPF4*j-OmwaS`&hgcw?De4mWC7YssIyU~ zVQ4hJ?`YzVCa&fV+_fQ2*T80G)vnc;u$sFx!ITckrli>nvO})bJfs_`V~9H@mafMB z8sn?&Z%G(yn2DMVrjgYmB<=Qk)*7_$A4b!C!hg9jWhJaR~aaV-* z-4*^8#+HTUN8=Qhc`IdA7@b8ZEcZ6A9KL%rf6@4oJ)X86jrVu|!t!q~lxM$;twVQQ zQSR2E30IUOTJF}NiM)SGi*b=x50heceJ8_c`uEGgn29>kT=GlCtZ2-NxywyszOeV3 z=|2Ma^4dkhd-s9y(>hk3_n!j(pa0ZY`gvY{rp4^-J^S>S-Ot~Qn0+#BAZ*kIwhI_M7ra39D!F$f03^>70WfuZ;fgM7jb$F4PI u|Nq_S9pWrAZX;n7jD|5Vmhi!1(f@hE`VsHaO>i@e3$^c-7p5b;;_pAWY5c4J literal 0 HcmV?d00001 diff --git a/utils/exporters/blender/tests/scripts/js/review.js b/utils/exporters/blender/tests/scripts/js/review.js index d541aa1ddeddce..b48530c08fd9a6 100644 --- a/utils/exporters/blender/tests/scripts/js/review.js +++ b/utils/exporters/blender/tests/scripts/js/review.js @@ -99,6 +99,10 @@ function loadObject( data ) { camera = scene.children[ i ]; var container = document.getElementById( 'viewport' ); + + orbit = new THREE.OrbitControls( camera, container ); + orbit.addEventListener( 'change', render ); + var aspect = container.offsetWidth / container.offsetHeight; camera.aspect = aspect; camera.updateProjectionMatrix(); diff --git a/utils/exporters/blender/tests/scripts/test_scene_children.bash b/utils/exporters/blender/tests/scripts/test_scene_children.bash new file mode 100755 index 00000000000000..f51c718e694be8 --- /dev/null +++ b/utils/exporters/blender/tests/scripts/test_scene_children.bash @@ -0,0 +1,9 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$DIR/setup_test_env.bash" + +blender --background $BLEND/scene_children.blend \ + --python $PYSCRIPT -- $JSON --vertices --faces --scene \ + --cameras --materials --embedGeometry --lights --cameras +makereview $@ --tag $(tagname) From ae907ebbc966b6c1d1af351ea5c837d501410686 Mon Sep 17 00:00:00 2001 From: repsac Date: Tue, 10 Feb 2015 11:19:20 -0800 Subject: [PATCH 114/333] PEP8 formatting and cleanup on the root exporter package (pylint was not happy) this does not cover the scope of the api/ package --- .../blender/addons/io_three/__init__.py | 460 +++++++++++------- .../addons/io_three/exporter/base_classes.py | 85 +++- .../addons/io_three/exporter/geometry.py | 224 ++++++--- .../blender/addons/io_three/exporter/image.py | 25 +- .../blender/addons/io_three/exporter/io.py | 53 +- .../addons/io_three/exporter/material.py | 47 +- .../addons/io_three/exporter/object.py | 73 +-- .../blender/addons/io_three/exporter/scene.py | 174 ++++--- .../addons/io_three/exporter/texture.py | 9 +- .../addons/io_three/exporter/utilities.py | 56 ++- .../blender/addons/io_three/logger.py | 7 + 11 files changed, 808 insertions(+), 405 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 9b904ba042a4cb..3d162ec217480e 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -39,132 +39,177 @@ bl_info = { - 'name': 'Three.js Format', - 'author': 'repsac, mrdoob, yomotsu, mpk, jpweeks', + 'name': "Three.js Format", + 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", 'version': (1, 2, 1), 'blender': (2, 7, 3), - 'location': 'File > Import-Export', - 'description': 'Export Three.js formatted JSON files.', - 'warning': '', - 'wiki_url': 'https://github.com/mrdoob/three.js/tree/'\ - 'master/utils/exporters/blender', - 'tracker_url': 'https://github.com/mrdoob/three.js/issues', + 'location': "File > Import-Export", + 'description': "Export Three.js formatted JSON files.", + 'warning': "Importer not included.", + 'wiki_url': "https://github.com/mrdoob/three.js/tree/"\ + "master/utils/exporters/blender", + 'tracker_url': "https://github.com/mrdoob/three.js/issues", 'category': 'Import-Export' } def _geometry_types(): - types = [ - (constants.GLOBAL, constants.GLOBAL.title(), - constants.GLOBAL), - (constants.GEOMETRY, constants.GEOMETRY.title(), - constants.GEOMETRY), - (constants.BUFFER_GEOMETRY, constants.BUFFER_GEOMETRY, - constants.BUFFER_GEOMETRY), - ] + """The valid geometry types that are supported by Three.js + + :return: list of tuples + + """ + keys = (constants.GLOBAL, + constants.GEOMETRY, + constants.BUFFER_GEOMETRY) + types = [] + for key in keys: + types.append((key, key.title(), key)) return types bpy.types.Mesh.THREE_geometry_type = EnumProperty( - name='Geometry type', - description='Geometry type', + name="Geometry type", + description="Geometry type", items=_geometry_types(), default=constants.GLOBAL) -class MESH_PT_hello(bpy.types.Panel): +class ThreeMesh(bpy.types.Panel): + """Creates custom properties on a mesh node""" bl_label = 'THREE' bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = 'data' - + def draw(self, context): + """ + + :param context: + + """ row = self.layout.row() if context.mesh: - row.prop(context.mesh, 'THREE_geometry_type', text='Type') + row.prop(context.mesh, + 'THREE_geometry_type', + text="Type") def _blending_types(index): - types = ( - constants.BLENDING_TYPES.NONE, - constants.BLENDING_TYPES.NORMAL, - constants.BLENDING_TYPES.ADDITIVE, - constants.BLENDING_TYPES.SUBTRACTIVE, - constants.BLENDING_TYPES.MULTIPLY, - constants.BLENDING_TYPES.CUSTOM) + """Supported blending types for Three.js + + :param index: + :type index: int + :returns: tuple if types (str, str, str) + + """ + types = (constants.BLENDING_TYPES.NONE, + constants.BLENDING_TYPES.NORMAL, + constants.BLENDING_TYPES.ADDITIVE, + constants.BLENDING_TYPES.SUBTRACTIVE, + constants.BLENDING_TYPES.MULTIPLY, + constants.BLENDING_TYPES.CUSTOM) return (types[index], types[index], types[index]) bpy.types.Material.THREE_blending_type = EnumProperty( - name='Blending type', - description='Blending type', - items=[_blending_types(x) for x in range(5)], + name="Blending type", + description="Blending type", + items=[_blending_types(x) for x in range(5)], default=constants.BLENDING_TYPES.NORMAL) bpy.types.Material.THREE_depth_write = BoolProperty(default=True) bpy.types.Material.THREE_depth_test = BoolProperty(default=True) -class MATERIAL_PT_hello(bpy.types.Panel): +class ThreeMaterial(bpy.types.Panel): + """Adds custom properties to the Materials of an object""" bl_label = 'THREE' bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = 'material' - + def draw(self, context): + """ + + :param context: + + """ layout = self.layout mat = context.material - + if mat is not None: row = layout.row() - row.label(text='Selected material: %s' % mat.name ) + row.label(text="Selected material: %s" % mat.name) row = layout.row() - row.prop(mat, 'THREE_blending_type', - text='Blending type' ) + row.prop(mat, 'THREE_blending_type', + text="Blending type") row = layout.row() - row.prop(mat, 'THREE_depth_write', - text='Enable depth writing' ) + row.prop(mat, 'THREE_depth_write', + text="Enable depth writing") row = layout.row() - row.prop(mat, 'THREE_depth_test', - text='Enable depth testing' ) + row.prop(mat, 'THREE_depth_test', + text="Enable depth testing") def _mag_filters(index): + """Three.js mag filters + + :param index: + :type index: int + :returns: tuple with the filter values + + """ types = (constants.LINEAR_FILTERS.LINEAR, - constants.NEAREST_FILTERS.NEAREST) + constants.NEAREST_FILTERS.NEAREST) return (types[index], types[index], types[index]) bpy.types.Texture.THREE_mag_filter = EnumProperty( - name='Mag Filter', - items = [_mag_filters(x) for x in range(2)], + name="Mag Filter", + items=[_mag_filters(x) for x in range(2)], default=constants.LINEAR_FILTERS.LINEAR) def _min_filters(index): + """Three.js min filters + + :param index: + :type index: int + :returns: tuple with the filter values + + """ types = (constants.LINEAR_FILTERS.LINEAR, - constants.LINEAR_FILTERS.MIP_MAP_NEAREST, - constants.LINEAR_FILTERS.MIP_MAP_LINEAR, - constants.NEAREST_FILTERS.NEAREST, - constants.NEAREST_FILTERS.MIP_MAP_NEAREST, - constants.NEAREST_FILTERS.MIP_MAP_LINEAR) + constants.LINEAR_FILTERS.MIP_MAP_NEAREST, + constants.LINEAR_FILTERS.MIP_MAP_LINEAR, + constants.NEAREST_FILTERS.NEAREST, + constants.NEAREST_FILTERS.MIP_MAP_NEAREST, + constants.NEAREST_FILTERS.MIP_MAP_LINEAR) return (types[index], types[index], types[index]) bpy.types.Texture.THREE_min_filter = EnumProperty( - name='Min Filter', - items = [_min_filters(x) for x in range(6)], + name="Min Filter", + items=[_min_filters(x) for x in range(6)], default=constants.LINEAR_FILTERS.MIP_MAP_LINEAR) def _mapping(index): + """Three.js texture mappings types + + :param index: + :type index: int + :returns: tuple with the mapping values + + """ types = (constants.MAPPING_TYPES.UV, - constants.MAPPING_TYPES.CUBE_REFLECTION, - constants.MAPPING_TYPES.CUBE_REFRACTION, - constants.MAPPING_TYPES.SPHERICAL_REFLECTION) + constants.MAPPING_TYPES.CUBE_REFLECTION, + constants.MAPPING_TYPES.CUBE_REFRACTION, + constants.MAPPING_TYPES.SPHERICAL_REFLECTION) return (types[index], types[index], types[index]) bpy.types.Texture.THREE_mapping = EnumProperty( - name='Mapping', - items = [_mapping(x) for x in range(4)], + name="Mapping", + items=[_mapping(x) for x in range(4)], default=constants.MAPPING_TYPES.UV) -class TEXTURE_PT_hello(bpy.types.Panel): +class ThreeTexture(bpy.types.Panel): + """Adds custom properties to a texture""" bl_label = 'THREE' bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' @@ -172,28 +217,39 @@ class TEXTURE_PT_hello(bpy.types.Panel): #@TODO: possible to make cycles compatible? def draw(self, context): + """ + + :param context: + + """ layout = self.layout tex = context.texture if tex is not None: row = layout.row() - row.prop(tex, 'THREE_mapping', text='Mapping') + row.prop(tex, 'THREE_mapping', text="Mapping") row = layout.row() - row.prop(tex, 'THREE_mag_filter', text='Mag Filter') + row.prop(tex, 'THREE_mag_filter', text="Mag Filter") row = layout.row() - row.prop(tex, 'THREE_min_filter', text='Min Filter') + row.prop(tex, 'THREE_min_filter', text="Min Filter") bpy.types.Object.THREE_export = bpy.props.BoolProperty(default=True) -class OBJECT_PT_hello(bpy.types.Panel): +class ThreeObject(bpy.types.Panel): + """Adds custom properties to an object""" bl_label = 'THREE' bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = 'object' def draw(self, context): + """ + + :param context: + + """ layout = self.layout obj = context.object @@ -201,11 +257,22 @@ def draw(self, context): row.prop(obj, 'THREE_export', text='Export') def get_settings_fullpath(): + """ + + :returns: Full path to the settings file (temp directory) + + """ return os.path.join(bpy.app.tempdir, SETTINGS_FILE_EXPORT) def save_settings_export(properties): + """Save the current export settings to disk. + + :param properties: + :returns: settings + :rtype: dict + """ settings = { constants.VERTICES: properties.option_vertices, constants.FACES: properties.option_faces, @@ -243,7 +310,7 @@ def save_settings_export(properties): } fname = get_settings_fullpath() - logging.debug('Saving settings to %s', fname) + logging.debug("Saving settings to %s", fname) with open(fname, 'w') as stream: json.dump(settings, stream) @@ -251,35 +318,42 @@ def save_settings_export(properties): def restore_settings_export(properties): + """Restore the settings (if settings file is found on disk) + If not found thend default to paramgers defined in + constants.EXPORT_OPTIONS + + :param properties: + + """ settings = {} fname = get_settings_fullpath() if os.path.exists(fname) and os.access(fname, os.R_OK): - logging.debug('Settings cache found %s', fname) + logging.debug("Settings cache found %s", fname) with open(fname, 'r') as fs: settings = json.load(fs) else: - logging.debug('No settings file found, using defaults.') + logging.debug("No settings file found, using defaults.") ## Geometry { properties.option_vertices = settings.get( - constants.VERTICES, + constants.VERTICES, constants.EXPORT_OPTIONS[constants.VERTICES]) properties.option_faces = settings.get( - constants.FACES, + constants.FACES, constants.EXPORT_OPTIONS[constants.FACES]) properties.option_normals = settings.get( - constants.NORMALS, + constants.NORMALS, constants.EXPORT_OPTIONS[constants.NORMALS]) properties.option_skinning = settings.get( - constants.SKINNING, + constants.SKINNING, constants.EXPORT_OPTIONS[constants.SKINNING]) properties.option_bones = settings.get( - constants.BONES, + constants.BONES, constants.EXPORT_OPTIONS[constants.BONES]) properties.option_influences = settings.get( @@ -293,49 +367,49 @@ def restore_settings_export(properties): ## Materials { properties.option_materials = settings.get( - constants.MATERIALS, + constants.MATERIALS, constants.EXPORT_OPTIONS[constants.MATERIALS]) properties.option_uv_coords = settings.get( - constants.UVS, + constants.UVS, constants.EXPORT_OPTIONS[constants.UVS]) properties.option_face_materials = settings.get( - constants.FACE_MATERIALS, + constants.FACE_MATERIALS, constants.EXPORT_OPTIONS[constants.FACE_MATERIALS]) properties.option_maps = settings.get( - constants.MAPS, + constants.MAPS, constants.EXPORT_OPTIONS[constants.MAPS]) properties.option_colors = settings.get( - constants.COLORS, + constants.COLORS, constants.EXPORT_OPTIONS[constants.COLORS]) properties.option_mix_colors = settings.get( - constants.MIX_COLORS, + constants.MIX_COLORS, constants.EXPORT_OPTIONS[constants.MIX_COLORS]) ## } ## Settings { properties.option_scale = settings.get( - constants.SCALE, + constants.SCALE, constants.EXPORT_OPTIONS[constants.SCALE]) properties.option_round_off = settings.get( - constants.ENABLE_PRECISION, + constants.ENABLE_PRECISION, constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION]) properties.option_round_value = settings.get( - constants.PRECISION, + constants.PRECISION, constants.EXPORT_OPTIONS[constants.PRECISION]) properties.option_logging = settings.get( - constants.LOGGING, + constants.LOGGING, constants.EXPORT_OPTIONS[constants.LOGGING]) properties.option_compression = settings.get( - constants.COMPRESSION, + constants.COMPRESSION, constants.NONE) properties.option_indent = settings.get( @@ -343,43 +417,43 @@ def restore_settings_export(properties): constants.EXPORT_OPTIONS[constants.INDENT]) properties.option_copy_textures = settings.get( - constants.COPY_TEXTURES, + constants.COPY_TEXTURES, constants.EXPORT_OPTIONS[constants.COPY_TEXTURES]) properties.option_embed_animation = settings.get( - constants.EMBED_ANIMATION, + constants.EMBED_ANIMATION, constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION]) ## } ## Scene { properties.option_export_scene = settings.get( - constants.SCENE, + constants.SCENE, constants.EXPORT_OPTIONS[constants.SCENE]) #properties.option_embed_geometry = settings.get( - # constants.EMBED_GEOMETRY, + # constants.EMBED_GEOMETRY, # constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY]) properties.option_lights = settings.get( - constants.LIGHTS, + constants.LIGHTS, constants.EXPORT_OPTIONS[constants.LIGHTS]) properties.option_cameras = settings.get( - constants.CAMERAS, + constants.CAMERAS, constants.EXPORT_OPTIONS[constants.CAMERAS]) ## } ## Animation { properties.option_animation_morph = settings.get( - constants.MORPH_TARGETS, + constants.MORPH_TARGETS, constants.EXPORT_OPTIONS[constants.MORPH_TARGETS]) properties.option_animation_skeletal = settings.get( - constants.ANIMATION, + constants.ANIMATION, constants.EXPORT_OPTIONS[constants.ANIMATION]) properties.option_frame_step = settings.get( - constants.FRAME_STEP, + constants.FRAME_STEP, constants.EXPORT_OPTIONS[constants.FRAME_STEP]) properties.option_frame_index_as_time = settings.get( @@ -388,18 +462,28 @@ def restore_settings_export(properties): ## } def compression_types(): + """Supported compression formats + + :rtype: tuple + + """ types = [(constants.NONE, constants.NONE, constants.NONE)] try: import msgpack - types.append((constants.MSGPACK, constants.MSGPACK, - constants.MSGPACK)) + types.append((constants.MSGPACK, constants.MSGPACK, + constants.MSGPACK)) except ImportError: pass return types def animation_options(): + """The supported skeletal animation types + + :returns: list of tuples + + """ anim = [ (constants.OFF, constants.OFF.title(), constants.OFF), (constants.POSE, constants.POSE.title(), constants.POSE), @@ -409,86 +493,87 @@ def animation_options(): return anim class ExportThree(bpy.types.Operator, ExportHelper): + """Class that handles the export properties""" - bl_idname='export.three' + bl_idname = 'export.three' bl_label = 'Export THREE' filename_ext = constants.EXTENSION option_vertices = BoolProperty( - name='Vertices', - description='Export vertices', + name="Vertices", + description="Export vertices", default=constants.EXPORT_OPTIONS[constants.VERTICES]) option_faces = BoolProperty( - name='Faces', - description='Export faces', + name="Faces", + description="Export faces", default=constants.EXPORT_OPTIONS[constants.FACES]) option_normals = BoolProperty( - name='Normals', - description='Export normals', + name="Normals", + description="Export normals", default=constants.EXPORT_OPTIONS[constants.NORMALS]) option_colors = BoolProperty( - name='Vertex Colors', - description='Export vertex colors', + name="Vertex Colors", + description="Export vertex colors", default=constants.EXPORT_OPTIONS[constants.COLORS]) option_mix_colors = BoolProperty( - name='Mix Colors', - description='Mix material and vertex colors', + name="Mix Colors", + description="Mix material and vertex colors", default=constants.EXPORT_OPTIONS[constants.MIX_COLORS]) option_uv_coords = BoolProperty( - name='UVs', - description='Export texture coordinates', + name="UVs", + description="Export texture coordinates", default=constants.EXPORT_OPTIONS[constants.UVS]) option_materials = BoolProperty( - name='Materials', - description='Export materials', + name="Materials", + description="Export materials", default=constants.EXPORT_OPTIONS[constants.MATERIALS]) option_face_materials = BoolProperty( - name='Face Materials', - description='Face mapping materials', + name="Face Materials", + description="Face mapping materials", default=constants.EXPORT_OPTIONS[constants.FACE_MATERIALS]) option_maps = BoolProperty( - name='Textures', - description='Include texture maps', + name="Textures", + description="Include texture maps", default=constants.EXPORT_OPTIONS[constants.MAPS]) option_skinning = BoolProperty( - name='Skinning', - description='Export skin data', + name="Skinning", + description="Export skin data", default=constants.EXPORT_OPTIONS[constants.SKINNING]) option_bones = BoolProperty( - name='Bones', - description='Export bones', + name="Bones", + description="Export bones", default=constants.EXPORT_OPTIONS[constants.BONES]) option_scale = FloatProperty( - name='Scale', - description='Scale vertices', - min=0.01, - max=1000.0, - soft_min=0.01, - soft_max=1000.0, + name="Scale", + description="Scale vertices", + min=0.01, + max=1000.0, + soft_min=0.01, + soft_max=1000.0, default=constants.EXPORT_OPTIONS[constants.SCALE]) option_round_off = BoolProperty( - name='Enable Precision', - description='Round off floating point values', + name="Enable Precision", + description="Round off floating point values", default=constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION]) option_round_value = IntProperty( - name='Precision', + name="Precision", min=0, max=16, - description='Floating point precision', + description="Floating point precision", default=constants.EXPORT_OPTIONS[constants.PRECISION]) logging_types = [ @@ -499,88 +584,88 @@ class ExportThree(bpy.types.Operator, ExportHelper): (constants.CRITICAL, constants.CRITICAL, constants.CRITICAL)] option_logging = EnumProperty( - name='', - description = 'Logging verbosity level', - items=logging_types, + name="", + description="Logging verbosity level", + items=logging_types, default=constants.DEBUG) option_geometry_type = EnumProperty( - name='Type', - description='Geometry type', + name="Type", + description="Geometry type", items=_geometry_types()[1:], default=constants.GEOMETRY) option_export_scene = BoolProperty( - name='Scene', - description='Export scene', + name="Scene", + description="Export scene", default=constants.EXPORT_OPTIONS[constants.SCENE]) - + #@TODO: removing this option since the ObjectLoader doesn't have # support for handling external geometry data #option_embed_geometry = BoolProperty( - # name='Embed geometry', - # description='Embed geometry', + # name="Embed geometry", + # description="Embed geometry", # default=constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY]) option_embed_animation = BoolProperty( - name='Embed animation', - description='Embed animation data with the geometry data', + name="Embed animation", + description="Embed animation data with the geometry data", default=constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION]) option_copy_textures = BoolProperty( - name='Copy textures', - description='Copy textures', + name="Copy textures", + description="Copy textures", default=constants.EXPORT_OPTIONS[constants.COPY_TEXTURES]) option_lights = BoolProperty( - name='Lights', - description='Export default scene lights', + name="Lights", + description="Export default scene lights", default=False) option_cameras = BoolProperty( - name='Cameras', - description='Export default scene cameras', + name="Cameras", + description="Export default scene cameras", default=False) option_animation_morph = BoolProperty( - name='Morph animation', - description='Export animation (morphs)', + name="Morph animation", + description="Export animation (morphs)", default=constants.EXPORT_OPTIONS[constants.MORPH_TARGETS]) option_animation_skeletal = EnumProperty( - name='', - description='Export animation (skeletal)', + name="", + description="Export animation (skeletal)", items=animation_options(), default=constants.OFF) option_frame_index_as_time = BoolProperty( - name='Frame index as time', - description='Use (original) frame index as frame time', + name="Frame index as time", + description="Use (original) frame index as frame time", default=constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME]) option_frame_step = IntProperty( - name='Frame step', - description='Animation frame step', - min=1, - max=1000, - soft_min=1, - soft_max=1000, + name="Frame step", + description="Animation frame step", + min=1, + max=1000, + soft_min=1, + soft_max=1000, default=1) - + option_indent = BoolProperty( - name='Indent JSON', - description='Disable this to reduce the file size', + name="Indent JSON", + description="Disable this to reduce the file size", default=constants.EXPORT_OPTIONS[constants.INDENT]) option_compression = EnumProperty( - name='', - description = 'Compression options', - items=compression_types(), + name="", + description="Compression options", + items=compression_types(), default=constants.NONE) option_influences = IntProperty( - name='Influences', - description='Maximum number of bone influences', + name="Influences", + description="Maximum number of bone influences", min=1, max=4, default=2) @@ -591,17 +676,27 @@ def invoke(self, context, event): @classmethod def poll(cls, context): + """ + + :param context: + + """ return context.active_object is not None def execute(self, context): + """ + + :param context: + + """ if not self.properties.filepath: - raise Exception('filename not set') + raise Exception("filename not set") settings = save_settings_export(self.properties) filepath = self.filepath if settings[constants.COMPRESSION] == constants.MSGPACK: - filepath = '%s%s' % (filepath[:-4], constants.PACK) + filepath = "%s%s" % (filepath[:-4], constants.PACK) from io_three import exporter if settings[constants.SCENE]: @@ -612,11 +707,16 @@ def execute(self, context): return {'FINISHED'} def draw(self, context): + """ + + :param context: + + """ layout = self.layout ## Geometry { row = layout.row() - row.label(text='GEOMETRY:') + row.label(text="GEOMETRY:") row = layout.row() row.prop(self.properties, 'option_vertices') @@ -639,7 +739,7 @@ def draw(self, context): ## Materials { row = layout.row() - row.label(text='- Shading:') + row.label(text="- Shading:") row = layout.row() row.prop(self.properties, 'option_face_materials') @@ -650,18 +750,18 @@ def draw(self, context): row = layout.row() row.prop(self.properties, 'option_mix_colors') ## } - + layout.separator() ## Animation { row = layout.row() - row.label(text='- Animation:') + row.label(text="- Animation:") row = layout.row() row.prop(self.properties, 'option_animation_morph') row = layout.row() - row.label(text='Skeletal animations:') + row.label(text="Skeletal animations:") row = layout.row() row.prop(self.properties, 'option_animation_skeletal') @@ -685,7 +785,7 @@ def draw(self, context): ## Scene { row = layout.row() - row.label(text='SCENE:') + row.label(text="SCENE:") row = layout.row() row.prop(self.properties, 'option_export_scene') @@ -703,7 +803,7 @@ def draw(self, context): ## Settings { row = layout.row() - row.label(text='SETTINGS:') + row.label(text="SETTINGS:") row = layout.row() row.prop(self.properties, 'option_maps') @@ -713,7 +813,7 @@ def draw(self, context): row = layout.row() row.prop(self.properties, 'option_scale') - + layout.row() row = layout.row() row.prop(self.properties, 'option_round_off') @@ -722,13 +822,13 @@ def draw(self, context): layout.row() row = layout.row() - row.label(text='Logging verbosity:') + row.label(text="Logging verbosity:") row = layout.row() row.prop(self.properties, 'option_logging') row = layout.row() - row.label(text='File compression format:') + row.label(text="File compression format:") row = layout.row() row.prop(self.properties, 'option_compression') @@ -740,21 +840,29 @@ def draw(self, context): def menu_func_export(self, context): + """ + + :param self: + :param context: + + """ default_path = bpy.data.filepath.replace('.blend', constants.EXTENSION) - text = 'Three.js (%s)' % constants.EXTENSION + text = "Three.js (%s)" % constants.EXTENSION operator = self.layout.operator(ExportThree.bl_idname, text=text) operator.filepath = default_path def register(): + """Registers the addon (Blender boilerplate)""" bpy.utils.register_module(__name__) bpy.types.INFO_MT_file_export.append(menu_func_export) def unregister(): + """Unregisters the addon (Blender boilerplate)""" bpy.utils.unregister_module(__name__) bpy.types.INFO_MT_file_export.remove(menu_func_export) if __name__ == '__main__': - register() + register() diff --git a/utils/exporters/blender/addons/io_three/exporter/base_classes.py b/utils/exporters/blender/addons/io_three/exporter/base_classes.py index 5a9a7019a14b3d..4953f3b2094c40 100644 --- a/utils/exporters/blender/addons/io_three/exporter/base_classes.py +++ b/utils/exporters/blender/addons/io_three/exporter/base_classes.py @@ -1,40 +1,68 @@ from . import utilities -from .. import constants, exceptions +from .. import constants, exceptions class BaseClass(constants.BASE_DICT): + """Base class which inherits from a base dictionary object.""" _defaults = {} def __init__(self, parent=None, type=None): constants.BASE_DICT.__init__(self) - self.__type = type + self._type = type - self.__parent = parent + self._parent = parent constants.BASE_DICT.update(self, self._defaults.copy()) - + def __setitem__(self, key, value): if not isinstance(value, constants.VALID_DATA_TYPES): - msg = 'Value is an invalid data type: %s' % type(value) - raise exceptions.ThreeValueError(msg) + msg = "Value is an invalid data type: %s" % type(value) + raise exceptions.ThreeValueError(msg) constants.BASE_DICT.__setitem__(self, key, value) @property def count(self): + """ + + :return: number of keys + :rtype: int + + """ return len(self.keys()) @property def parent(self): - return self.__parent + """ + + :return: parent object + + """ + return self._parent @property def type(self): - return self.__type - + """ + + :return: the type (if applicable) + + """ + return self._type + def copy(self): + """Copies the items to a standard dictionary object. + + :rtype: dict + + """ data = {} def _dict_copy(old, new): + """Recursive function for processing all values + + :param old: + :param new: + + """ for key, value in old.items(): if isinstance(value, (str, list)): new[key] = value[:] @@ -51,10 +79,11 @@ def _dict_copy(old, new): return data -class BaseNode(BaseClass): +class BaseNode(BaseClass): + """Base class for all nodes for the current platform.""" def __init__(self, node, parent, type): BaseClass.__init__(self, parent=parent, type=type) - self.__node = node + self._node = node if node is None: self[constants.UUID] = utilities.id() else: @@ -68,33 +97,51 @@ def __init__(self, node, parent, type): else: scene = None - self.__scene = scene - + self._scene = scene + @property def node(self): - return self.__node + """ + + :return: name of the node + + """ + return self._node @property def scene(self): - return self.__scene + """ + + :return: returns the scene point + + """ + + return self._scene @property def options(self): + """ + + :return: export options + :retype: dict + + """ return self.scene.options class BaseScene(BaseClass): + """Base class that scenes inherit from.""" def __init__(self, filepath, options): BaseClass.__init__(self, type=constants.SCENE) - self.__filepath = filepath + self._filepath = filepath - self.__options = options.copy() + self._options = options.copy() @property def filepath(self): - return self.__filepath + return self._filepath @property def options(self): - return self.__options + return self._options diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index 8ba14e1a59b13b..0e6fe8bad1c073 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -7,9 +7,10 @@ class Geometry(base_classes.BaseNode): + """Class that wraps a single mesh/geometry node.""" def __init__(self, node, parent=None): - logger.debug('Geometry().__init__(%s)', node) - + logger.debug("Geometry().__init__(%s)", node) + #@TODO: maybe better to have `three` constants for # strings that are specific to `three` properties geo_type = constants.GEOMETRY.title() @@ -18,23 +19,28 @@ def __init__(self, node, parent=None): if opt_type == constants.BUFFER_GEOMETRY: geo_type = constants.BUFFER_GEOMETRY elif opt_type != constants.GEOMETRY: - logger.error('Unknown geometry type %s', opt_type) + logger.error("Unknown geometry type %s", opt_type) - logger.info('Setting %s to "%s"', node, geo_type) + logger.info("Setting %s to '%s'", node, geo_type) self._defaults[constants.TYPE] = geo_type - base_classes.BaseNode.__init__(self, node, - parent=parent, - type=geo_type) + base_classes.BaseNode.__init__(self, node, + parent=parent, + type=geo_type) @property def animation_filename(self): + """Calculate the file name for the animation file + + :return: base name for the file + """ compression = self.options.get(constants.COMPRESSION) if compression in (None, constants.NONE): ext = constants.JSON elif compression == constants.MSGPACK: ext = constants.PACK + key = '' for key in (constants.MORPH_TARGETS, constants.ANIMATION): try: self[key] @@ -42,27 +48,32 @@ def animation_filename(self): except KeyError: pass else: - logger.info('%s has no animation data', self.node) + logger.info("%s has no animation data", self.node) return return '%s.%s.%s' % (self.node, key, ext) @property def face_count(self): + """Parse the bit masks of the `faces` array. + + :rtype: int + + """ try: faces = self[constants.FACES] except KeyError: - logger.debug('No parsed faces found') + logger.debug("No parsed faces found") return 0 length = len(faces) offset = 0 - bitset = lambda x,y: x & ( 1 << y ) + bitset = lambda x, y: x & (1 << y) face_count = 0 masks = (constants.MASK[constants.UVS], - constants.MASK[constants.NORMALS], - constants.MASK[constants.COLORS]) + constants.MASK[constants.NORMALS], + constants.MASK[constants.COLORS]) while offset < length: bit = faces[offset] @@ -84,20 +95,32 @@ def face_count(self): @property def metadata(self): + """Metadata for the current node. + + :rtype: dict + + """ metadata = { constants.GENERATOR: constants.THREE, constants.VERSION: FORMAT_VERSION } if self[constants.TYPE] == constants.GEOMETRY.title(): - self.__geometry_metadata(metadata) + self._geometry_metadata(metadata) else: - self.__buffer_geometry_metadata(metadata) + self._buffer_geometry_metadata(metadata) return metadata def copy(self, scene=True): - logger.debug('Geometry().copy(scene=%s)', scene) + """Copy the geometry definitions to a standard dictionary. + + :param scene: toggle for scene formatting (Default = True) + :type scene: bool + :rtype: dict + + """ + logger.debug("Geometry().copy(scene=%s)", scene) dispatch = { True: self._scene_format, False: self._geometry_format @@ -107,47 +130,68 @@ def copy(self, scene=True): try: data[constants.MATERIALS] = self[constants.MATERIALS].copy() except KeyError: - logger.debug('No materials to copy') + logger.debug("No materials to copy") return data def copy_textures(self): - logger.debug('Geometry().copy_textures()') + """Copy the textures to the destination directory.""" + logger.debug("Geometry().copy_textures()") if self.options.get(constants.COPY_TEXTURES): texture_registration = self.register_textures() if texture_registration: - logger.info('%s has registered textures', self.node) + logger.info("%s has registered textures", self.node) io.copy_registered_textures( os.path.dirname(self.scene.filepath), texture_registration) def parse(self): - logger.debug('Geometry().parse()') + """Parse the current node""" + logger.debug("Geometry().parse()") if self[constants.TYPE] == constants.GEOMETRY.title(): - logger.info('Parsing Geometry format') - self.__parse_geometry() + logger.info("Parsing Geometry format") + self._parse_geometry() else: - logger.info('Parsing BufferGeometry format') - self.__parse_buffer_geometry() + logger.info("Parsing BufferGeometry format") + self._parse_buffer_geometry() def register_textures(self): - logger.debug('Geometry().register_textures()') - return api.mesh.texture_registration(self.node) + """Obtain a texture registration object. + + :rtype: dict + + """ + logger.debug("Geometry().register_textures()") + return api.mesh.texture_registration(self.node) def write(self, filepath=None): - logger.debug('Geometry().write(filepath=%s)', filepath) + """Write the geometry definitions to disk. Uses the + desitnation path of the scene. + + :param filepath: optional output file path (Default=None) + :type filepath: str + + """ + logger.debug("Geometry().write(filepath=%s)", filepath) filepath = filepath or self.scene.filepath - io.dump(filepath, self.copy(scene=False), - options=self.scene.options) + io.dump(filepath, self.copy(scene=False), + options=self.scene.options) if self.options.get(constants.MAPS): - logger.info('Copying textures for %s', self.node) + logger.info("Copying textures for %s", self.node) self.copy_textures() def write_animation(self, filepath): - logger.debug('Geometry().write_animation(%s)', filepath) + """Write the animation definitions to a separate file + on disk. This helps optimize the geometry file size. + + :param filepath: destination path + :type filepath: str + + """ + logger.debug("Geometry().write_animation(%s)", filepath) for key in (constants.MORPH_TARGETS, constants.ANIMATION): try: @@ -156,29 +200,35 @@ def write_animation(self, filepath): except KeyError: pass else: - logger.info('%s has no animation data', self.node) + logger.info("%s has no animation data", self.node) return filepath = os.path.join(filepath, self.animation_filename) if filepath: - logger.info('Dumping animation data to %s', filepath) + logger.info("Dumping animation data to %s", filepath) io.dump(filepath, data, options=self.scene.options) return filepath else: - logger.warning('Could not determine a filepath for '\ - 'animation data. Nothing written to disk.') + logger.warning("Could not determine a filepath for "\ + "animation data. Nothing written to disk.") def _component_data(self): - logger.debug('Geometry()._component_data()') - + """Query the component data only + + :rtype: dict + + """ + logger.debug("Geometry()._component_data()") + if self[constants.TYPE] != constants.GEOMETRY.title(): return self[constants.ATTRIBUTES] - components = [constants.VERTICES, constants.FACES, - constants.UVS, constants.COLORS, constants.NORMALS, - constants.BONES, constants.SKIN_WEIGHTS, - constants.SKIN_INDICES, constants.NAME, - constants.INFLUENCES_PER_VERTEX] + components = [constants.VERTICES, constants.FACES, + constants.UVS, constants.COLORS, + constants.NORMALS, constants.BONES, + constants.SKIN_WEIGHTS, + constants.SKIN_INDICES, constants.NAME, + constants.INFLUENCES_PER_VERTEX] data = {} anim_components = [constants.MORPH_TARGETS, constants.ANIMATION] @@ -192,20 +242,25 @@ def _component_data(self): pass else: data[component] = os.path.basename( - self.animation_filename) + self.animation_filename) + break else: - logger.info('No animation data found for %s', self.node) + logger.info("No animation data found for %s", self.node) for component in components: try: data[component] = self[component] except KeyError: - logger.debug('Component %s not found', component) - pass + logger.debug("Component %s not found", component) return data def _geometry_format(self): + """Three.Geometry formatted definitions + + :rtype: dict + + """ data = self._component_data() if self[constants.TYPE] != constants.GEOMETRY.title(): @@ -219,17 +274,27 @@ def _geometry_format(self): return data - def __buffer_geometry_metadata(self, metadata): + def _buffer_geometry_metadata(self, metadata): + """Three.BufferGeometry metadata + + :rtype: dict + + """ for key, value in self[constants.ATTRIBUTES].items(): size = value[constants.ITEM_SIZE] array = value[constants.ARRAY] metadata[key] = len(array)/size - - def __geometry_metadata(self, metadata): + + def _geometry_metadata(self, metadata): + """Three.Geometry metadat + + :rtype: dict + + """ skip = (constants.TYPE, constants.FACES, constants.UUID, - constants.ANIMATION, constants.SKIN_INDICES, - constants.SKIN_WEIGHTS, constants.NAME, - constants.INFLUENCES_PER_VERTEX) + constants.ANIMATION, constants.SKIN_INDICES, + constants.SKIN_WEIGHTS, constants.NAME, + constants.INFLUENCES_PER_VERTEX) vectors = (constants.VERTICES, constants.NORMALS) for key in self.keys(): @@ -249,6 +314,11 @@ def __geometry_metadata(self, metadata): metadata[constants.FACES] = faces def _scene_format(self): + """Format the output for Scene compatability + + :rtype: dict + + """ data = { constants.UUID: self[constants.UUID], constants.TYPE: self[constants.TYPE] @@ -267,34 +337,35 @@ def _scene_format(self): } else: data[constants.ATTRIBUTES] = component_data - data[constants.METADATA] = self.metadata + data[constants.METADATA] = self.metadata data[constants.NAME] = self[constants.NAME] - return data + return data - def __parse_buffer_geometry(self): + def _parse_buffer_geometry(self): + """Parse the geometry to Three.BufferGeometry specs""" self[constants.ATTRIBUTES] = {} options_vertices = self.options.get(constants.VERTICES) option_normals = self.options.get(constants.NORMALS) option_uvs = self.options.get(constants.UVS) - dispatch = ( - (constants.POSITION, options_vertices, - api.mesh.buffer_position, 3), - (constants.UV, option_uvs, api.mesh.buffer_uv, 2), - (constants.NORMAL, option_normals, - api.mesh.buffer_normal, 3) - ) + pos_tuple = (constants.POSITION, options_vertices, + api.mesh.buffer_position, 3) + uvs_tuple = (constants.UV, option_uvs, + api.mesh.buffer_uv, 2) + normals_tuple = (constants.NORMAL, option_normals, + api.mesh.buffer_normal, 3) + dispatch = (pos_tuple, uvs_tuple, normals_tuple) - for key, option, func, size in dispatch: + for key, option, func, size in dispatch: if not option: continue array = func(self.node, self.options) or [] - if not array: - logger.warning('No array could be made for %s', key) + if not array: + logger.warning("No array could be made for %s", key) continue self[constants.ATTRIBUTES][key] = { @@ -303,40 +374,41 @@ def __parse_buffer_geometry(self): constants.ARRAY: array } - def __parse_geometry(self): + def _parse_geometry(self): + """Parse the geometry to Three.Geometry specs""" if self.options.get(constants.VERTICES): - logger.info('Parsing %s', constants.VERTICES) + logger.info("Parsing %s", constants.VERTICES) self[constants.VERTICES] = api.mesh.vertices( self.node, self.options) or [] if self.options.get(constants.NORMALS): - logger.info('Parsing %s', constants.NORMALS) + logger.info("Parsing %s", constants.NORMALS) self[constants.NORMALS] = api.mesh.normals( self.node, self.options) or [] if self.options.get(constants.COLORS): - logger.info('Parsing %s', constants.COLORS) + logger.info("Parsing %s", constants.COLORS) self[constants.COLORS] = api.mesh.vertex_colors( self.node) or [] - + if self.options.get(constants.FACE_MATERIALS): - logger.info('Parsing %s', constants.FACE_MATERIALS) + logger.info("Parsing %s", constants.FACE_MATERIALS) self[constants.MATERIALS] = api.mesh.materials( self.node, self.options) or [] if self.options.get(constants.UVS): - logger.info('Parsing %s', constants.UVS) + logger.info("Parsing %s", constants.UVS) self[constants.UVS] = api.mesh.uvs( self.node, self.options) or [] if self.options.get(constants.FACES): - logger.info('Parsing %s', constants.FACES) + logger.info("Parsing %s", constants.FACES) self[constants.FACES] = api.mesh.faces( self.node, self.options) or [] no_anim = (None, False, constants.OFF) if self.options.get(constants.ANIMATION) not in no_anim: - logger.info('Parsing %s', constants.ANIMATION) + logger.info("Parsing %s", constants.ANIMATION) self[constants.ANIMATION] = api.mesh.skeletal_animation( self.node, self.options) or [] @@ -345,12 +417,12 @@ def __parse_geometry(self): bone_map = {} if self.options.get(constants.BONES): - logger.info('Parsing %s', constants.BONES) + logger.info("Parsing %s", constants.BONES) bones, bone_map = api.mesh.bones(self.node, self.options) self[constants.BONES] = bones if self.options.get(constants.SKINNING): - logger.info('Parsing %s', constants.SKINNING) + logger.info("Parsing %s", constants.SKINNING) influences = self.options.get( constants.INFLUENCES_PER_VERTEX, 2) @@ -361,7 +433,7 @@ def __parse_geometry(self): self.node, bone_map, influences) if self.options.get(constants.MORPH_TARGETS): - logger.info('Parsing %s', constants.MORPH_TARGETS) + logger.info("Parsing %s", constants.MORPH_TARGETS) self[constants.MORPH_TARGETS] = api.mesh.morph_targets( self.node, self.options) diff --git a/utils/exporters/blender/addons/io_three/exporter/image.py b/utils/exporters/blender/addons/io_three/exporter/image.py index 64af5c9c31339d..a91bb79de782c1 100644 --- a/utils/exporters/blender/addons/io_three/exporter/image.py +++ b/utils/exporters/blender/addons/io_three/exporter/image.py @@ -4,22 +4,43 @@ class Image(base_classes.BaseNode): + """Class the wraps an image node. This is the node that + represent that actual file on disk. + """ def __init__(self, node, parent): - logger.debug('Image().__init__(%s)', node) + logger.debug("Image().__init__(%s)", node) base_classes.BaseNode.__init__(self, node, parent, constants.IMAGE) self[constants.URL] = api.image.file_name(self.node) @property def destination(self): + """ + + :return: full destination path (when copied) + + """ dirname = os.path.dirname(self.scene.filepath) return os.path.join(dirname, self[constants.URL]) @property def filepath(self): + """ + + :return: source file path + + """ return api.image.file_path(self.node) def copy_texture(self, func=io.copy): - logger.debug('Image().copy_texture()') + """Copy the texture. + self.filepath > self.destination + + :param func: Optional function override (Default = io.copy) + arguments are (, ) + :return: path the texture was copied to + + """ + logger.debug("Image().copy_texture()") func(self.filepath, self.destination) return self.destination diff --git a/utils/exporters/blender/addons/io_three/exporter/io.py b/utils/exporters/blender/addons/io_three/exporter/io.py index bc582cf1e57666..81ba137ef67271 100644 --- a/utils/exporters/blender/addons/io_three/exporter/io.py +++ b/utils/exporters/blender/addons/io_three/exporter/io.py @@ -5,13 +5,27 @@ def copy_registered_textures(dest, registration): - logger.debug('io.copy_registered_textures(%s, %s)', dest, registration) + """Copy the registered textures to the destination (root) path + + :param dest: destination directory + :param registration: registered textures + :type dest: str + :type registration: dict + + """ + logger.debug("io.copy_registered_textures(%s, %s)", dest, registration) for value in registration.values(): copy(value['file_path'], dest) def copy(src, dst): - logger.debug('io.copy(%s, %s)' % (src, dst)) + """Copy a file to a destination + + :param src: source file + :param dst: destination file/path + + """ + logger.debug("io.copy(%s, %s)" % (src, dst)) if os.path.isdir(dst): file_name = os.path.basename(src) dst = os.path.join(dst, file_name) @@ -21,19 +35,27 @@ def copy(src, dst): def dump(filepath, data, options=None): + """Dump the output to disk (JSON, msgpack, etc) + + :param filepath: output file path + :param data: serializable data to write to disk + :param options: (Default = None) + :type options: dict + + """ options = options or {} - logger.debug('io.dump(%s, data, options=%s)', filepath, options) + logger.debug("io.dump(%s, data, options=%s)", filepath, options) compress = options.get(constants.COMPRESSION, constants.NONE) if compress == constants.MSGPACK: try: import msgpack except ImportError: - logger.error('msgpack module not found') + logger.error("msgpack module not found") raise - logger.info('Dumping to msgpack') - func = lambda x,y: msgpack.dump(x, y) + logger.info("Dumping to msgpack") + func = lambda x, y: msgpack.dump(x, y) mode = 'wb' else: round_off = options.get(constants.ENABLE_PRECISION) @@ -44,28 +66,35 @@ def dump(filepath, data, options=None): indent = options.get(constants.INDENT, True) indent = 4 if indent else None - logger.info('Dumping to JSON') - func = lambda x,y: _json.json.dump(x, y, indent=indent) + logger.info("Dumping to JSON") + func = lambda x, y: _json.json.dump(x, y, indent=indent) mode = 'w' - logger.info('Writing to %s', filepath) + logger.info("Writing to %s", filepath) with open(filepath, mode=mode) as stream: func(data, stream) def load(filepath, options): - logger.debug('io.load(%s, %s)', filepath, options) + """Load the contents of the file path with the correct parser + + :param filepath: input file path + :param options: + :type options: dict + + """ + logger.debug("io.load(%s, %s)", filepath, options) compress = options.get(constants.COMPRESSION, constants.NONE) if compress == constants.MSGPACK: try: import msgpack except ImportError: - logger.error('msgpack module not found') + logger.error("msgpack module not found") raise module = msgpack mode = 'rb' else: - logger.info('Loading JSON') + logger.info("Loading JSON") module = _json.json mode = 'r' diff --git a/utils/exporters/blender/addons/io_three/exporter/material.py b/utils/exporters/blender/addons/io_three/exporter/material.py index 46b001d00202ad..0a289ad6a61620 100644 --- a/utils/exporters/blender/addons/io_three/exporter/material.py +++ b/utils/exporters/blender/addons/io_three/exporter/material.py @@ -3,21 +3,23 @@ class Material(base_classes.BaseNode): + """Class that wraps material nodes""" def __init__(self, node, parent): - logger.debug('Material().__init__(%s)', node) - base_classes.BaseNode.__init__(self, node, parent, - constants.MATERIAL) - - self.__common_attributes() + logger.debug("Material().__init__(%s)", node) + base_classes.BaseNode.__init__(self, node, parent, + constants.MATERIAL) + + self._common_attributes() if self[constants.TYPE] == constants.THREE_PHONG: - self.__phong_attributes() + self._phong_attributes() textures = self.parent.options.get(constants.MAPS) if textures: - self.__update_maps() + self._update_maps() - def __common_attributes(self): - logger.debug('Material().__common_attributes()') + def _common_attributes(self): + """Parse the common material attributes""" + logger.debug('Material()._common_attributes()') dispatch = { constants.PHONG: constants.THREE_PHONG, constants.LAMBERT: constants.THREE_LAMBERT, @@ -28,7 +30,7 @@ def __common_attributes(self): diffuse = api.material.diffuse_color(self.node) self[constants.COLOR] = utilities.rgb2int(diffuse) - + if self[constants.TYPE] != constants.THREE_BASIC: ambient = api.material.ambient_color(self.node) self[constants.AMBIENT] = utilities.rgb2int(ambient) @@ -45,14 +47,18 @@ def __common_attributes(self): self[constants.DEPTH_WRITE] = api.material.depth_write(self.node) - def __phong_attributes(self): - logger.debug('Material().__phong_attributes()') + def _phong_attributes(self): + """Parse phong specific attributes""" + logger.debug("Material()._phong_attributes()") specular = api.material.specular_color(self.node) self[constants.SPECULAR] = utilities.rgb2int(specular) self[constants.SHININESS] = api.material.specular_coef(self.node) - def __update_maps(self): - logger.debug('Material().__update_maps()') + def _update_maps(self): + """Parses maps/textures and updates the textures array + with any new nodes found. + """ + logger.debug("Material()._update_maps()") mapping = ( (api.material.diffuse_map, constants.MAP), @@ -60,14 +66,14 @@ def __update_maps(self): (api.material.light_map, constants.LIGHT_MAP) ) - for func,key in mapping: + for func, key in mapping: map_node = func(self.node) if map_node: logger.info('Found map node %s for %s', map_node, key) tex_inst = self.scene.texture(map_node.name) - self[key] = tex_inst[constants.UUID] + self[key] = tex_inst[constants.UUID] - if self[constants.TYPE] == constants.THREE_PHONG: + if self[constants.TYPE] == constants.THREE_PHONG: mapping = ( (api.material.bump_map, constants.BUMP_MAP, constants.BUMP_SCALE, api.material.bump_scale), @@ -77,8 +83,9 @@ def __update_maps(self): for func, map_key, scale_key, scale_func in mapping: map_node = func(self.node) - if not map_node: continue - logger.info('Found map node %s for %s', map_node, map_key) + if not map_node: + continue + logger.info("Found map node %s for %s", map_node, map_key) tex_inst = self.scene.texture(map_node.name) - self[map_key] = tex_inst[constants.UUID] + self[map_key] = tex_inst[constants.UUID] self[scale_key] = scale_func(self.node) diff --git a/utils/exporters/blender/addons/io_three/exporter/object.py b/utils/exporters/blender/addons/io_three/exporter/object.py index ba9a5f2d86eac1..220c6383cc3875 100644 --- a/utils/exporters/blender/addons/io_three/exporter/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/object.py @@ -3,18 +3,19 @@ class Object(base_classes.BaseNode): - + """Class that wraps an object node""" def __init__(self, node, parent=None, type=None): - logger.debug('Object().__init__(%s)', node) + logger.debug("Object().__init__(%s)", node) base_classes.BaseNode.__init__(self, node, parent=parent, type=type) if self.node: - self.__node_setup() + self._node_setup() else: - self.__root_setup() + self._root_setup() - def __init_camera(self): - logger.debug('Object().__init_camera()') + def _init_camera(self): + """Initialize camera attributes""" + logger.debug("Object()._init_camera()") self[constants.FAR] = api.camera.far(self.node) self[constants.NEAR] = api.camera.near(self.node) @@ -29,29 +30,32 @@ def __init_camera(self): #@TODO: need more light attributes. Some may have to come from # custom blender attributes. - def __init_light(self): - logger.debug('Object().__init_light()') + def _init_light(self): + """Initialize light attributes""" + logger.debug("Object()._init_light()") self[constants.COLOR] = api.light.color(self.node) self[constants.INTENSITY] = api.light.intensity(self.node) if self[constants.TYPE] != constants.DIRECTIONAL_LIGHT: self[constants.DISTANCE] = api.light.distance(self.node) - + if self[constants.TYPE] == constants.SPOT_LIGHT: self[constants.ANGLE] = api.light.angle(self.node) - def __init_mesh(self): - logger.debug('Object().__init_mesh()') + def _init_mesh(self): + """Initialize mesh attributes""" + logger.debug("Object()._init_mesh()") mesh = api.object.mesh(self.node, self.options) node = self.scene.geometry(mesh) if node: self[constants.GEOMETRY] = node[constants.UUID] else: - msg = 'Could not find Geometry() node for %s' + msg = "Could not find Geometry() node for %s" logger.error(msg, self.node) - def __node_setup(self): - logger.debug('Object().__node_setup()') + def _node_setup(self): + """Parse common node attributes of all objects""" + logger.debug("Object()._node_setup()") self[constants.NAME] = api.object.name(self.node) self[constants.POSITION] = api.object.position( @@ -68,42 +72,43 @@ def __node_setup(self): self[constants.TYPE] = api.object.node_type(self.node) if self.options.get(constants.MATERIALS): - logger.info('Parsing materials for %s', self.node) + logger.info("Parsing materials for %s", self.node) material_name = api.object.material(self.node) if material_name: - logger.info('Material found %s', material_name) + logger.info("Material found %s", material_name) material_inst = self.scene.material(material_name) self[constants.MATERIAL] = material_inst[constants.UUID] else: - logger.info('%s has no materials', self.node) + logger.info("%s has no materials", self.node) - casts_shadow = (constants.MESH, - constants.DIRECTIONAL_LIGHT, - constants.SPOT_LIGHT) + casts_shadow = (constants.MESH, + constants.DIRECTIONAL_LIGHT, + constants.SPOT_LIGHT) if self[constants.TYPE] in casts_shadow: - logger.info('Querying shadow casting for %s', self.node) + logger.info("Querying shadow casting for %s", self.node) self[constants.CAST_SHADOW] = \ api.object.cast_shadow(self.node) - + if self[constants.TYPE] == constants.MESH: - logger.info('Querying shadow receive for %s', self.node) + logger.info("Querying shadow receive for %s", self.node) self[constants.RECEIVE_SHADOW] = \ api.object.receive_shadow(self.node) camera = (constants.PERSPECTIVE_CAMERA, - constants.ORTHOGRAPHIC_CAMERA) + constants.ORTHOGRAPHIC_CAMERA) - lights = (constants.AMBIENT_LIGHT, constants.DIRECTIONAL_LIGHT, - constants.AREA_LIGHT, constants.POINT_LIGHT, - constants.SPOT_LIGHT, constants.HEMISPHERE_LIGHT) + lights = (constants.AMBIENT_LIGHT, + constants.DIRECTIONAL_LIGHT, + constants.AREA_LIGHT, constants.POINT_LIGHT, + constants.SPOT_LIGHT, constants.HEMISPHERE_LIGHT) if self[constants.TYPE] == constants.MESH: - self.__init_mesh() + self._init_mesh() elif self[constants.TYPE] in camera: - self.__init_camera() + self._init_camera() elif self[constants.TYPE] in lights: - self.__init_light() + self._init_light() for child in api.object.children(self.node, self.scene.valid_types): if not self.get(constants.CHILDREN): @@ -111,6 +116,8 @@ def __node_setup(self): else: self[constants.CHILDREN].append(Object(child, parent=self)) - def __root_setup(self): - logger.debug('Object().__root_setup()') - self[constants.MATRIX] = [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] + def _root_setup(self): + """Applies to a root/scene object""" + logger.debug("Object()._root_setup()") + self[constants.MATRIX] = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 1] diff --git a/utils/exporters/blender/addons/io_three/exporter/scene.py b/utils/exporters/blender/addons/io_three/exporter/scene.py index 39986dfbc7ae6c..cf021d469e8fae 100644 --- a/utils/exporters/blender/addons/io_three/exporter/scene.py +++ b/utils/exporters/blender/addons/io_three/exporter/scene.py @@ -4,8 +4,8 @@ base_classes, texture, material, - geometry, - object, + geometry, + object as object_, utilities, io, api @@ -13,6 +13,7 @@ class Scene(base_classes.BaseScene): + """Class that handles the contruction of a Three scene""" _defaults = { constants.METADATA: constants.DEFAULT_METADATA.copy(), constants.GEOMETRIES: [], @@ -22,7 +23,7 @@ class Scene(base_classes.BaseScene): } def __init__(self, filepath, options=None): - logger.debug('Scene().__init__(%s, %s)', filepath, options) + logger.debug("Scene().__init__(%s, %s)", filepath, options) base_classes.BaseScene.__init__(self, filepath, options or {}) source_file = api.scene_name() @@ -31,67 +32,103 @@ def __init__(self, filepath, options=None): @property def valid_types(self): + """ + + :return: list of valid node types + + """ valid_types = [api.constants.MESH] if self.options.get(constants.CAMERAS): - logger.info('Adding cameras to valid object types') + logger.info("Adding cameras to valid object types") valid_types.append(api.constants.CAMERA) if self.options.get(constants.LIGHTS): - logger.info('Adding lights to valid object types') + logger.info("Adding lights to valid object types") valid_types.append(api.constants.LAMP) return valid_types - def geometry(self, arg): - logger.debug('Scene().geometry(%s)', arg) - return self._find_node(arg, self[constants.GEOMETRIES]) + def geometry(self, value): + """Find a geometry node that matches either a name + or uuid value. + + :param value: name or uuid + :type value: str + + """ + logger.debug("Scene().geometry(%s)", value) + return _find_node(value, self[constants.GEOMETRIES]) + + def image(self, value): + """Find a image node that matches either a name + or uuid value. - def image(self, arg): - logger.debug('Scene().image%s)', arg) - return self._find_node(arg, self[constants.IMAGES]) + :param value: name or uuid + :type value: str - def material(self, arg): - logger.debug('Scene().material(%s)', arg) - return self._find_node(arg, self[constants.MATERIALS]) + """ + logger.debug("Scene().image%s)", value) + return _find_node(value, self[constants.IMAGES]) + + def material(self, value): + """Find a material node that matches either a name + or uuid value. + + :param value: name or uuid + :type value: str + + """ + logger.debug("Scene().material(%s)", value) + return _find_node(value, self[constants.MATERIALS]) def parse(self): - logger.debug('Scene().parse()') + """Execute the parsing of the scene""" + logger.debug("Scene().parse()") if self.options.get(constants.MAPS): - self.__parse_textures() + self._parse_textures() if self.options.get(constants.MATERIALS): - self.__parse_materials() + self._parse_materials() + + self._parse_geometries() + self._parse_objects() - self.__parse_geometries() - self.__parse_objects() + def texture(self, value): + """Find a texture node that matches either a name + or uuid value. - def texture(self, arg): - logger.debug('Scene().texture(%s)', arg) - return self._find_node(arg, self[constants.TEXTURES]) + :param value: name or uuid + :type value: str + + """ + logger.debug("Scene().texture(%s)", value) + return _find_node(value, self[constants.TEXTURES]) def write(self): - logger.debug('Scene().write()') + """Write the parsed scene to disk.""" + logger.debug("Scene().write()") data = {} - + embed_anim = self.options.get(constants.EMBED_ANIMATION, True) embed = self.options.get(constants.EMBED_GEOMETRY, True) compression = self.options.get(constants.COMPRESSION) - extension = constants.EXTENSIONS.get(compression, + extension = constants.EXTENSIONS.get( + compression, constants.EXTENSIONS[constants.JSON]) export_dir = os.path.dirname(self.filepath) for key, value in self.items(): - + if key == constants.GEOMETRIES: geometries = [] - for geometry in value: + for geom in value: if not embed_anim: - geometry.write_animation(export_dir) + geom.write_animation(export_dir) - geom_data = geometry.copy() + geom_data = geom.copy() if embed: geometries.append(geom_data) continue @@ -103,10 +140,10 @@ def write(self): geom_data.pop(constants.ATTRIBUTES) geom_data.pop(constants.METADATA) - url = 'geometry.%s%s' % (geometry.node, extension) + url = 'geometry.%s%s' % (geom.node, extension) geometry_file = os.path.join(export_dir, url) - geometry.write(filepath=geometry_file) + geom.write(filepath=geometry_file) geom_data[constants.URL] = os.path.basename(url) geometries.append(geom_data) @@ -123,20 +160,12 @@ def write(self): if self.options.get(constants.COPY_TEXTURES): for geo in self[constants.GEOMETRIES]: - logger.info('Copying textures from %s', geo.node) + logger.info("Copying textures from %s", geo.node) geo.copy_textures() - def _find_node(self, arg, manifest): - for index in manifest: - uuid = index.get(constants.UUID) == arg - name = index.node == arg - if uuid or name: - return index - else: - logger.debug('No matching node for %s', arg) - - def __parse_geometries(self): - logger.debug('Scene().__parse_geometries()') + def _parse_geometries(self): + """Locate all geometry nodes and parse them""" + logger.debug("Scene()._parse_geometries()") # this is an important step. please refer to the doc string # on the function for more information @@ -145,52 +174,75 @@ def __parse_geometries(self): # now iterate over all the extracted mesh nodes and parse each one for mesh in api.object.extracted_meshes(): - logger.info('Parsing geometry %s', mesh) + logger.info("Parsing geometry %s", mesh) geo = geometry.Geometry(mesh, self) geo.parse() geometries.append(geo) - logger.info('Added %d geometry nodes', len(geometries)) + logger.info("Added %d geometry nodes", len(geometries)) self[constants.GEOMETRIES] = geometries - def __parse_materials(self): - logger.debug('Scene().__parse_materials()') + def _parse_materials(self): + """Locate all non-orphaned materials and parse them""" + logger.debug("Scene()._parse_materials()") materials = [] for material_name in api.material.used_materials(): - logger.info('Parsing material %s', material_name) - materials.append(material.Material(material_name, parent=self)) + logger.info("Parsing material %s", material_name) + materials.append(material.Material(material_name, parent=self)) - logger.info('Added %d material nodes', len(materials)) + logger.info("Added %d material nodes", len(materials)) self[constants.MATERIALS] = materials - def __parse_objects(self): - logger.debug('Scene().__parse_objects()') + def _parse_objects(self): + """Locate all valid objects in the scene and parse them""" + logger.debug("Scene()._parse_objects()") try: scene_name = self[constants.METADATA][constants.SOURCE_FILE] except KeyError: scene_name = constants.SCENE - self[constants.OBJECT] = object.Object(None, parent=self) + self[constants.OBJECT] = object_.Object(None, parent=self) self[constants.OBJECT][constants.TYPE] = constants.SCENE.title() self[constants.UUID] = utilities.id_from_name(scene_name) - objects = [] + objects = [] for node in api.object.assemblies(self.valid_types, self.options): - logger.info('Parsing object %s', node) - obj = object.Object(node, parent=self[constants.OBJECT]) + logger.info("Parsing object %s", node) + obj = object_.Object(node, parent=self[constants.OBJECT]) objects.append(obj) - logger.info('Added %d object nodes', len(objects)) + logger.info("Added %d object nodes", len(objects)) self[constants.OBJECT][constants.CHILDREN] = objects - def __parse_textures(self): - logger.debug('Scene().__parse_textures()') + def _parse_textures(self): + """Locate all non-orphaned textures and parse them""" + logger.debug("Scene()._parse_textures()") textures = [] for texture_name in api.texture.textures(): - logger.info('Parsing texture %s', texture_name) + logger.info("Parsing texture %s", texture_name) tex_inst = texture.Texture(texture_name, self) textures.append(tex_inst) - logger.info('Added %d texture nodes', len(textures)) + logger.info("Added %d texture nodes", len(textures)) self[constants.TEXTURES] = textures + + +def _find_node(value, manifest): + """Find a node that matches either a name + or uuid value. + + :param value: name or uuid + :param manifest: manifest of nodes to search + :type value: str + :type manifest: list + + """ + for index in manifest: + uuid = index.get(constants.UUID) == value + name = index.node == value + if uuid or name: + return index + else: + logger.debug("No matching node for %s", value) + diff --git a/utils/exporters/blender/addons/io_three/exporter/texture.py b/utils/exporters/blender/addons/io_three/exporter/texture.py index 2eafe25ff67cfb..cdf866b83612f2 100644 --- a/utils/exporters/blender/addons/io_three/exporter/texture.py +++ b/utils/exporters/blender/addons/io_three/exporter/texture.py @@ -3,8 +3,9 @@ class Texture(base_classes.BaseNode): + """Class that wraps a texture node""" def __init__(self, node, parent): - logger.debug('Texture().__init__(%s)', node) + logger.debug("Texture().__init__(%s)", node) base_classes.BaseNode.__init__(self, node, parent, constants.TEXTURE) img_inst = self.scene.image(api.texture.file_name(self.node)) @@ -29,4 +30,10 @@ def __init__(self, node, parent): @property def image(self): + """ + + :return: the image object of the current texture + :rtype: image.Image + + """ return self.scene.image(self[constants.IMAGE]) diff --git a/utils/exporters/blender/addons/io_three/exporter/utilities.py b/utils/exporters/blender/addons/io_three/exporter/utilities.py index 021a8b31cc5d95..605371d41cba84 100644 --- a/utils/exporters/blender/addons/io_three/exporter/utilities.py +++ b/utils/exporters/blender/addons/io_three/exporter/utilities.py @@ -8,9 +8,15 @@ def bit_mask(flags): + """Generate a bit mask. + + :type flags: dict + :return: int + + """ bit = 0 - true = lambda x,y: (x | (1 << y)) - false = lambda x,y: (x & (~(1 << y))) + true = lambda x, y: (x | (1 << y)) + false = lambda x, y: (x & (~(1 << y))) for mask, position in constants.MASK.items(): func = true if flags.get(mask) else false @@ -20,19 +26,43 @@ def bit_mask(flags): def hash(value): + """Generate a hash from a given value + + :param value: + :rtype: str + + """ hash_ = hashlib.md5() hash_.update(repr(value).encode('utf8')) return hash_.hexdigest() def id(): + """Generate a random UUID + + :rtype: str + + """ return str(uuid.uuid4()).upper() + def id_from_name(name): + """Generate a UUID using a name as the namespace + + :type name: str + :rtype: str + + """ return str(uuid.uuid3(uuid.NAMESPACE_DNS, name)).upper() def rgb2int(rgb): + """Convert a given rgb value to an integer + + :type rgb: list|tuple + :rtype: int + + """ is_tuple = isinstance(rgb, tuple) rgb = list(rgb) if is_tuple else rgb @@ -41,6 +71,15 @@ def rgb2int(rgb): def round_off(value, ndigits=ROUND): + """Round off values to specified limit + + :param value: value(s) to round off + :param ndigits: limit (Default = ROUND) + :type value: float|list|tuple + :return: the same data type that was passed + :rtype: float|list|tuple + + """ is_tuple = isinstance(value, tuple) is_list = isinstance(value, list) @@ -58,10 +97,17 @@ def round_off(value, ndigits=ROUND): def rounding(options): - round_off = options.get(constants.ENABLE_PRECISION) - if round_off: + """By evaluation the options determine if precision was + enabled and what the value is + + :type options: dict + :rtype: bool, int + + """ + round_off_ = options.get(constants.ENABLE_PRECISION) + if round_off_: round_val = options[constants.PRECISION] else: round_val = None - return (round_off, round_val) + return (round_off_, round_val) diff --git a/utils/exporters/blender/addons/io_three/logger.py b/utils/exporters/blender/addons/io_three/logger.py index 7fd51f03e9fdfb..cf6e178cac96e9 100644 --- a/utils/exporters/blender/addons/io_three/logger.py +++ b/utils/exporters/blender/addons/io_three/logger.py @@ -15,7 +15,14 @@ constants.CRITICAL: logging.CRITICAL } + def init(filename, level=constants.DEBUG): + """Initialize the logger. + + :param filename: base name of the log file + :param level: logging level (Default = DEBUG) + + """ global LOG_FILE LOG_FILE = os.path.join(tempfile.gettempdir(), filename) with open(LOG_FILE, 'w'): From 988166acbea5bebbeaa609a4c4f6bd042a6430d2 Mon Sep 17 00:00:00 2001 From: "mathieu _alkama_ m." Date: Tue, 10 Feb 2015 23:21:16 +0100 Subject: [PATCH 115/333] fixed missing html line break --- docs/api/materials/SpriteMaterial.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/materials/SpriteMaterial.html b/docs/api/materials/SpriteMaterial.html index 2502628285d9f8..1a47a0ffaf1e74 100644 --- a/docs/api/materials/SpriteMaterial.html +++ b/docs/api/materials/SpriteMaterial.html @@ -24,7 +24,7 @@

[name]( [page:Object parameters] )

color - color of the sprite
map - the texture map
- rotation - the rotation of the sprite + rotation - the rotation of the sprite
fog - whether or not to use the scene fog
From 4582bf1276c30c238e415cb79f4871e8560d102d Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 10 Feb 2015 17:31:42 -0800 Subject: [PATCH 116/333] WebGLRenderer: More clear warning messages. See #5675. --- src/renderers/WebGLRenderer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 4d3764d6053db6..b26002a453f816 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -5652,7 +5652,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) { - console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' ); + console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' ); } @@ -5661,7 +5661,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) { - console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( ' + texture.sourceFile + ' )' ); + console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ' + texture.sourceFile + ' )' ); } From a00344f93bc28f2f28cb73b92c3d0ea18a173874 Mon Sep 17 00:00:00 2001 From: repsac Date: Tue, 10 Feb 2015 23:05:56 -0800 Subject: [PATCH 117/333] Restored original scene graph logic which does not try and preserve child/parent hierarchies More PEP8 conforming for the api package --- .../blender/addons/io_three/__init__.py | 4 +- .../addons/io_three/exporter/api/__init__.py | 32 +- .../addons/io_three/exporter/api/animation.py | 193 +++++-- .../addons/io_three/exporter/api/camera.py | 78 ++- .../addons/io_three/exporter/api/image.py | 32 +- .../addons/io_three/exporter/api/light.py | 48 +- .../addons/io_three/exporter/api/material.py | 241 +++++++-- .../addons/io_three/exporter/api/mesh.py | 487 ++++++++++++------ .../addons/io_three/exporter/api/object.py | 287 ++++++++--- .../addons/io_three/exporter/api/texture.py | 108 +++- .../addons/io_three/exporter/geometry.py | 6 +- .../blender/addons/io_three/exporter/image.py | 2 +- .../blender/addons/io_three/exporter/io.py | 2 +- .../addons/io_three/exporter/object.py | 10 +- .../blender/addons/io_three/exporter/scene.py | 2 +- .../addons/io_three/exporter/utilities.py | 2 +- .../blender/addons/io_three/logger.py | 2 +- 17 files changed, 1170 insertions(+), 366 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 3d162ec217480e..0b56adf6534716 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -41,9 +41,9 @@ bl_info = { 'name': "Three.js Format", 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", - 'version': (1, 2, 1), + 'version': (1, 2, 2), 'blender': (2, 7, 3), - 'location': "File > Import-Export", + 'location': "File > Export", 'description': "Export Three.js formatted JSON files.", 'warning': "Importer not included.", 'wiki_url': "https://github.com/mrdoob/three.js/tree/"\ diff --git a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py index b4107275037094..fa120d47252632 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py @@ -1,20 +1,33 @@ import os import bpy -from . import object, mesh, material, camera, light +from . import object as object_, mesh, material, camera, light from .. import logger def active_object(): + """ + + :return: The actively selected object + + """ return bpy.context.scene.objects.active def init(): - logger.debug('Initializing API') - object._MESH_MAP.clear() + """Initializing the api module. Required first step before + initializing the actual export process. + """ + logger.debug("Initializing API") + object_.clear_mesh_map() def selected_objects(valid_types=None): - logger.debug('api.selected_objects(%s)', valid_types) + """Selected objects. + + :param valid_types: Filter for valid types (Default value = None) + + """ + logger.debug("api.selected_objects(%s)", valid_types) for node in bpy.context.selected_objects: if valid_types is None: yield node.name @@ -23,9 +36,20 @@ def selected_objects(valid_types=None): def set_active_object(obj): + """Set the object as active in the scene + + :param obj: + + """ + logger.debug("api.set_active_object(%s)", obj) bpy.context.scene.objects.active = obj def scene_name(): + """ + + :return: name of the current scene + + """ return os.path.basename(bpy.data.filepath) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/animation.py b/utils/exporters/blender/addons/io_three/exporter/api/animation.py index 13af9003945092..f51c085cffda9c 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/animation.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/animation.py @@ -4,34 +4,66 @@ def pose_animation(armature, options): - logger.debug('animation.pose_animation %s', armature) + """Query armature animation using pose bones + + :param armature: + :param options: + :returns: list dictionaries containing animationdata + :rtype: [{}, {}, ...] + + """ + logger.debug("animation.pose_animation(%s)", armature) func = _parse_pose_action return _parse_action(func, armature, options) def rest_animation(armature, options): - logger.debug('animation.rest_animation %s', armature) + """Query armature animation (REST position) + + :param armature: + :param options: + :returns: list dictionaries containing animationdata + :rtype: [{}, {}, ...] + + """ + logger.debug("animation.rest_animation(%s)", armature) func = _parse_rest_action return _parse_action(func, armature, options) def _parse_action(func, armature, options): + """ + + :param func: + :param armature: + :param options: + + """ animations = [] - logger.info('Parsing %d actions', len(data.actions)) + logger.info("Parsing %d actions", len(data.actions)) round_off, round_val = utilities.rounding(options) for action in data.actions: - logger.info('Parsing action %s', action.name) + logger.info("Parsing action %s", action.name) animation = func(action, armature, options, round_off, round_val) animations.append(animation) return animations def _parse_rest_action(action, armature, options, round_off, round_val): + """ + + :param action: + :param armature: + :param options: + :param round_off: + :param round_val: + + """ end_frame = action.frame_range[1] start_frame = action.frame_range[0] frame_length = end_frame - start_frame - l,r,s = armature.matrix_world.decompose() - rotation_matrix = r.to_matrix() + rot = armature.matrix_world.decompose()[1] + rotation_matrix = rot.to_matrix() hierarchy = [] parent_index = -1 frame_step = options.get(constants.FRAME_STEP, 1) @@ -44,22 +76,27 @@ def _parse_rest_action(action, armature, options, round_off, round_val): # I believe this was meant to skip control bones, may # not be useful. needs more testing if bone.use_deform is False: - logger.info('Skipping animation data for bone %s', bone.name) + logger.info("Skipping animation data for bone %s", bone.name) continue - logger.info('Parsing animation data for bone %s', bone.name) + logger.info("Parsing animation data for bone %s", bone.name) keys = [] for frame in range(start, end): computed_frame = frame * frame_step - pos, pchange = _position(bone, computed_frame, - action, armature.matrix_world) - rot, rchange = _rotation(bone, computed_frame, - action, rotation_matrix) + pos, pchange = _position(bone, computed_frame, + action, armature.matrix_world) + rot, rchange = _rotation(bone, computed_frame, + action, rotation_matrix) - # flip y and z - px, py, pz = pos.x, pos.z, -pos.y - rx, ry, rz, rw = rot.x, rot.z, -rot.y, rot.w + if round_off: + pos_x, pos_y, pos_z = utilities.round_off( + [pos.x, pos.z, -pos.y], round_val) + rot_x, rot_y, rot_z, rot_w = utilities.round_off( + [rot.x, rot.z, -rot.y, rot.w], round_val) + else: + pos_x, pos_y, pos_z = pos.x, pos.z, -pos.y + rot_x, rot_y, rot_z, rot_w = rot.x, rot.z, -rot.y, rot.w if frame == start_frame: @@ -67,13 +104,13 @@ def _parse_rest_action(action, armature, options, round_off, round_val): #@TODO: missing scale values keyframe = { constants.TIME: time, - constants.POS: [px, py, pz], - constants.ROT: [rx, ry, rz, rw], + constants.POS: [pos_x, pos_y, pos_z], + constants.ROT: [rot_x, rot_y, rot_z, rot_w], constants.SCL: [1, 1, 1] } keys.append(keyframe) - # END-FRAME: needs pos, rot and scl attributes + # END-FRAME: needs pos, rot and scl attributes # with animation length (required frame) elif frame == end_frame / frame_step: @@ -81,13 +118,13 @@ def _parse_rest_action(action, armature, options, round_off, round_val): time = frame_length / fps keyframe = { constants.TIME: time, - constants.POS: [px, py, pz], - constants.ROT: [rx, ry, rz, rw], + constants.POS: [pos_x, pos_y, pos_z], + constants.ROT: [rot_x, rot_y, rot_z, rot_w], constants.SCL: [1, 1, 1] } keys.append(keyframe) - # MIDDLE-FRAME: needs only one of the attributes, + # MIDDLE-FRAME: needs only one of the attributes, # can be an empty frame (optional frame) elif pchange == True or rchange == True: @@ -96,31 +133,31 @@ def _parse_rest_action(action, armature, options, round_off, round_val): if pchange == True and rchange == True: keyframe = { - constants.TIME: time, - constants.POS: [px, py, pz], - constants.ROT: [rx, ry, rz, rw] + constants.TIME: time, + constants.POS: [pos_x, pos_y, pos_z], + constants.ROT: [rot_x, rot_y, rot_z, rot_w] } elif pchange == True: keyframe = { - constants.TIME: time, - constants.POS: [px, py, pz] + constants.TIME: time, + constants.POS: [pos_x, pos_y, pos_z] } elif rchange == True: keyframe = { - constants.TIME: time, - constants.ROT: [rx, ry, rz, rw] + constants.TIME: time, + constants.ROT: [rot_x, rot_y, rot_z, rot_w] } keys.append(keyframe) hierarchy.append({ - constants.KEYS: keys, + constants.KEYS: keys, constants.PARENT: parent_index }) parent_index += 1 animation = { - constants.HIERARCHY: hierarchy, + constants.HIERARCHY: hierarchy, constants.LENGTH:frame_length / fps, constants.FPS: fps, constants.NAME: action.name @@ -130,6 +167,15 @@ def _parse_rest_action(action, armature, options, round_off, round_val): def _parse_pose_action(action, armature, options, round_off, round_val): + """ + + :param action: + :param armature: + :param options: + :param round_off: + :param round_val: + + """ #@TODO: this seems to fail in batch mode meaning the # user has to have th GUI open. need to improve # this logic to allow batch processing, if Blender @@ -138,7 +184,7 @@ def _parse_pose_action(action, armature, options, round_off, round_val): context.area.type = 'DOPESHEET_EDITOR' context.space_data.mode = 'ACTION' context.area.spaces.active.action = action - + armature_matrix = armature.matrix_world fps = context.scene.render.fps @@ -155,23 +201,23 @@ def _parse_pose_action(action, armature, options, round_off, round_val): channels_scale = [] for pose_bone in armature.pose.bones: - logger.info('Processing channels for %s', + logger.info("Processing channels for %s", pose_bone.bone.name) keys.append([]) channels_location.append( - _find_channels(action, + _find_channels(action, pose_bone.bone, 'location')) channels_rotation.append( - _find_channels(action, + _find_channels(action, pose_bone.bone, 'rotation_quaternion')) channels_rotation.append( - _find_channels(action, + _find_channels(action, pose_bone.bone, 'rotation_euler')) channels_scale.append( - _find_channels(action, + _find_channels(action, pose_bone.bone, 'scale')) @@ -183,7 +229,7 @@ def _parse_pose_action(action, armature, options, round_off, round_val): else: frame = start_frame + frame_index * frame_step - logger.info('Processing frame %d', frame) + logger.info("Processing frame %d", frame) time = frame - start_frame if frame_index_as_time is False: @@ -194,7 +240,19 @@ def _parse_pose_action(action, armature, options, round_off, round_val): bone_index = 0 def has_keyframe_at(channels, frame): + """ + + :param channels: + :param frame: + + """ def find_keyframe_at(channel, frame): + """ + + :param channel: + :param frame: + + """ for keyframe in channel.keyframe_points: if keyframe.co[0] == frame: return keyframe @@ -207,7 +265,7 @@ def find_keyframe_at(channel, frame): for pose_bone in armature.pose.bones: - logger.info('Processing bone %s', pose_bone.bone.name) + logger.info("Processing bone %s", pose_bone.bone.name) if pose_bone.parent is None: bone_matrix = armature_matrix * pose_bone.matrix else: @@ -216,7 +274,7 @@ def find_keyframe_at(channel, frame): bone_matrix = parent_matrix.inverted() * bone_matrix pos, rot, scl = bone_matrix.decompose() - + pchange = True or has_keyframe_at( channels_location[bone_index], frame) rchange = True or has_keyframe_at( @@ -232,7 +290,7 @@ def find_keyframe_at(channel, frame): ) rot = ( utilities.round_off(rot.x, round_val), - utilities.round_off(rot.z, round_val), + utilities.round_off(rot.z, round_val), -utilities.round_off(rot.y, round_val), utilities.round_off(rot.w, round_val) ) @@ -262,15 +320,15 @@ def find_keyframe_at(channel, frame): keyframe[constants.SCL] = scl if len(keyframe.keys()) > 1: - logger.info('Recording keyframe data for %s %s', + logger.info("Recording keyframe data for %s %s", pose_bone.bone.name, str(keyframe)) keys[bone_index].append(keyframe) else: - logger.info('No anim data to record for %s', + logger.info("No anim data to record for %s", pose_bone.bone.name) bone_index += 1 - + hierarchy = [] bone_index = 0 for pose_bone in armature.pose.bones: @@ -285,9 +343,9 @@ def find_keyframe_at(channel, frame): context.scene.frame_set(start_frame) context.area.type = current_context - + animation = { - constants.HIERARCHY: hierarchy, + constants.HIERARCHY: hierarchy, constants.LENGTH:frame_length, constants.FPS: fps, constants.NAME: action.name @@ -297,10 +355,17 @@ def find_keyframe_at(channel, frame): def _find_channels(action, bone, channel_type): + """ + + :param action: + :param bone: + :param channel_type: + + """ result = [] if len(action.groups): - + group_index = -1 for index, group in enumerate(action.groups): if group.name == bone.name: @@ -316,7 +381,7 @@ def _find_channels(action, bone, channel_type): bone_label = '"%s"' % bone.name for channel in action.fcurves: data_path = [bone_label in channel.data_path, - channel_type in channel.data_path] + channel_type in channel.data_path] if all(data_path): result.append(channel) @@ -324,8 +389,16 @@ def _find_channels(action, bone, channel_type): def _position(bone, frame, action, armature_matrix): + """ + + :param bone: + :param frame: + :param action: + :param armature_matrix: - position = mathutils.Vector((0,0,0)) + """ + + position = mathutils.Vector((0, 0, 0)) change = False ngroups = len(action.groups) @@ -379,10 +452,18 @@ def _position(bone, frame, action, armature_matrix): def _rotation(bone, frame, action, armature_matrix): + """ + + :param bone: + :param frame: + :param action: + :param armature_matrix: + + """ # TODO: calculate rotation also from rotation_euler channels - rotation = mathutils.Vector((0,0,0,1)) + rotation = mathutils.Vector((0, 0, 0, 1)) change = False @@ -427,6 +508,13 @@ def _rotation(bone, frame, action, armature_matrix): def _handle_rotation_channel(channel, frame, rotation): + """ + + :param channel: + :param frame: + :param rotation: + + """ change = False @@ -454,6 +542,13 @@ def _handle_rotation_channel(channel, frame, rotation): def _handle_position_channel(channel, frame, position): + """ + + :param channel: + :param frame: + :param position: + + """ change = False diff --git a/utils/exporters/blender/addons/io_three/exporter/api/camera.py b/utils/exporters/blender/addons/io_three/exporter/api/camera.py index d34f001eb69049..6853a0a13ce376 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/camera.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/camera.py @@ -3,13 +3,25 @@ def _camera(func): + """ + + :param func: + + """ def inner(name, *args, **kwargs): + """ + + :param name: + :param *args: + :param **kwargs: + + """ if isinstance(name, types.Camera): camera = name else: - camera = data.cameras[name] + camera = data.cameras[name] return func(camera, *args, **kwargs) @@ -18,48 +30,96 @@ def inner(name, *args, **kwargs): @_camera def aspect(camera): - logger.debug('camera.aspect(%s)', camera) + """ + + :param camera: + :rtype: float + + """ + logger.debug("camera.aspect(%s)", camera) render = context.scene.render return render.resolution_x/render.resolution_y @_camera def bottom(camera): - logger.debug('camera.bottom(%s)', camera) + """ + + :param camera: + :rtype: float + + """ + logger.debug("camera.bottom(%s)", camera) return -(camera.angle_y * camera.ortho_scale) @_camera def far(camera): - logger.debug('camera.far(%s)', camera) + """ + + :param camera: + :rtype: float + + """ + logger.debug("camera.far(%s)", camera) return camera.clip_end @_camera def fov(camera): - logger.debug('camera.fov(%s)', camera) + """ + + :param camera: + :rtype: float + + """ + logger.debug("camera.fov(%s)", camera) return camera.lens @_camera def left(camera): - logger.debug('camera.left(%s)', camera) + """ + + :param camera: + :rtype: float + + """ + logger.debug("camera.left(%s)", camera) return -(camera.angle_x * camera.ortho_scale) @_camera def near(camera): - logger.debug('camera.near(%s)', camera) + """ + + :param camera: + :rtype: float + + """ + logger.debug("camera.near(%s)", camera) return camera.clip_start @_camera def right(camera): - logger.debug('camera.right(%s)', camera) + """ + + :param camera: + :rtype: float + + """ + logger.debug("camera.right(%s)", camera) return camera.angle_x * camera.ortho_scale @_camera def top(camera): - logger.debug('camera.top(%s)', camera) + """ + + :param camera: + :rtype: float + + """ + logger.debug("camera.top(%s)", camera) return camera.angle_y * camera.ortho_scale diff --git a/utils/exporters/blender/addons/io_three/exporter/api/image.py b/utils/exporters/blender/addons/io_three/exporter/api/image.py index 8ef45b21e4e514..c0581173fe7394 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/image.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/image.py @@ -4,13 +4,25 @@ def _image(func): + """ + + :param func: + + """ def inner(name, *args, **kwargs): + """ + + :param name: + :param *args: + :param **kwargs: + + """ if isinstance(name, types.Image): mesh = name else: - mesh = data.images[name] + mesh = data.images[name] return func(mesh, *args, **kwargs) @@ -18,11 +30,23 @@ def inner(name, *args, **kwargs): def file_name(image): - logger.debug('image.file_name(%s)', image) - return os.path.basename(file_path(image)) + """ + + :param image: + :rtype: str + + """ + logger.debug("image.file_name(%s)", image) + return os.path.basename(file_path(image)) @_image def file_path(image): - logger.debug('image.file_path(%s)', image) + """ + + :param image: + :rtype: str + + """ + logger.debug("image.file_path(%s)", image) return os.path.normpath(image.filepath_from_user()) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/light.py b/utils/exporters/blender/addons/io_three/exporter/api/light.py index 1668a6aa6459f8..33c5fa86dd89b3 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/light.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/light.py @@ -1,15 +1,27 @@ -from bpy import data, types +from bpy import data, types from .. import utilities, logger def _lamp(func): + """ + + :param func: + + """ def inner(name, *args, **kwargs): + """ + + :param name: + :param *args: + :param **kwargs: + + """ if isinstance(name, types.Lamp): lamp = name else: - lamp = data.lamps[name] + lamp = data.lamps[name] return func(lamp, *args, **kwargs) @@ -18,24 +30,48 @@ def inner(name, *args, **kwargs): @_lamp def angle(lamp): - logger.debug('light.angle(%s)', lamp) + """ + + :param lamp: + :rtype: float + + """ + logger.debug("light.angle(%s)", lamp) return lamp.spot_size @_lamp def color(lamp): - logger.debug('light.color(%s)', lamp) + """ + + :param lamp: + :rtype: int + + """ + logger.debug("light.color(%s)", lamp) colour = (lamp.color.r, lamp.color.g, lamp.color.b) return utilities.rgb2int(colour) @_lamp def distance(lamp): - logger.debug('light.distance(%s)', lamp) + """ + + :param lamp: + :rtype: float + + """ + logger.debug("light.distance(%s)", lamp) return lamp.distance @_lamp def intensity(lamp): - logger.debug('light.intensity(%s)', lamp) + """ + + :param lamp: + :rtype: float + + """ + logger.debug("light.intensity(%s)", lamp) return round(lamp.energy, 2) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/material.py b/utils/exporters/blender/addons/io_three/exporter/api/material.py index a3e6bcb985e8b5..0f227049c87026 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/material.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/material.py @@ -4,13 +4,25 @@ def _material(func): + """ + + :param func: + + """ def inner(name, *args, **kwargs): + """ + + :param name: + :param *args: + :param **kwargs: + + """ if isinstance(name, types.Material): material = name else: - material = data.materials[name] + material = data.materials[name] return func(material, *args, **kwargs) @@ -19,8 +31,15 @@ def inner(name, *args, **kwargs): @_material def ambient_color(material): - logger.debug('material.ambient_color(%s)', material) - diffuse = diffuse_color(material) + """ + + :param material: + :return: rgb value + :rtype: tuple + + """ + logger.debug("material.ambient_color(%s)", material) + diffuse = diffuse_color(material) return (material.ambient * diffuse[0], material.ambient * diffuse[1], material.ambient * diffuse[2]) @@ -28,18 +47,30 @@ def ambient_color(material): @_material def blending(material): - logger.debug('material.blending(%s)', material) + """ + + :param material: + :return: THREE_blending_type value + + """ + logger.debug("material.blending(%s)", material) try: blend = material.THREE_blending_type except AttributeError: - logger.debug('No THREE_blending_type attribute found') - blend = constants.NORMAL_BLENDING + logger.debug("No THREE_blending_type attribute found") + blend = constants.NORMAL_BLENDING return blend @_material def bump_map(material): - logger.debug('material.bump_map(%s)', material) + """ + + :param material: + :return: texture node for bump + + """ + logger.debug("material.bump_map(%s)", material) for texture in _valid_textures(material): if texture.use_map_normal and not \ texture.texture.use_normal_map: @@ -48,34 +79,61 @@ def bump_map(material): @_material def bump_scale(material): + """ + + :param material: + :rtype: float + + """ return normal_scale(material) @_material def depth_test(material): - logger.debug('material.depth_test(%s)', material) + """ + + :param material: + :return: THREE_depth_test value + :rtype: bool + + """ + logger.debug("material.depth_test(%s)", material) try: test = material.THREE_depth_test except AttributeError: - logger.debug('No THREE_depth_test attribute found') + logger.debug("No THREE_depth_test attribute found") test = True return test @_material def depth_write(material): - logger.debug('material.depth_write(%s)', material) + """ + + :param material: + :return: THREE_depth_write value + :rtype: bool + + """ + logger.debug("material.depth_write(%s)", material) try: write = material.THREE_depth_write except AttributeError: - logger.debug('No THREE_depth_write attribute found') + logger.debug("No THREE_depth_write attribute found") write = True return write @_material def diffuse_color(material): - logger.debug('material.diffuse_color(%s)', material) + """ + + :param material: + :return: rgb value + :rtype: tuple + + """ + logger.debug("material.diffuse_color(%s)", material) return (material.diffuse_intensity * material.diffuse_color[0], material.diffuse_intensity * material.diffuse_color[1], material.diffuse_intensity * material.diffuse_color[2]) @@ -83,7 +141,13 @@ def diffuse_color(material): @_material def diffuse_map(material): - logger.debug('material.diffuse_map(%s)', material) + """ + + :param material: + :return: texture node for map + + """ + logger.debug("material.diffuse_map(%s)", material) for texture in _valid_textures(material): if texture.use_map_color_diffuse and not \ texture.blend_type == MULTIPLY: @@ -92,8 +156,15 @@ def diffuse_map(material): @_material def emissive_color(material): - logger.debug('material.emissive_color(%s)', material) - diffuse = diffuse_color(material) + """ + + :param material: + :return: rgb value + :rtype: tuple + + """ + logger.debug("material.emissive_color(%s)", material) + diffuse = diffuse_color(material) return (material.emit * diffuse[0], material.emit * diffuse[1], material.emit * diffuse[2]) @@ -101,7 +172,13 @@ def emissive_color(material): @_material def light_map(material): - logger.debug('material.light_map(%s)', material) + """ + + :param material: + :return: texture node for light maps + + """ + logger.debug("material.light_map(%s)", material) for texture in _valid_textures(material): if texture.use_map_color_diffuse and \ texture.blend_type == MULTIPLY: @@ -110,7 +187,13 @@ def light_map(material): @_material def normal_scale(material): - logger.debug('material.normal_scale(%s)', material) + """ + + :param material: + :rtype: float + + """ + logger.debug("material.normal_scale(%s)", material) for texture in _valid_textures(material): if texture.use_map_normal: return texture.normal_factor @@ -118,22 +201,40 @@ def normal_scale(material): @_material def normal_map(material): - logger.debug('material.normal_map(%s)', material) + """ + + :param material: + :return: texture node for normals + + """ + logger.debug("material.normal_map(%s)", material) for texture in _valid_textures(material): if texture.use_map_normal and \ texture.texture.use_normal_map: return texture.texture - + @_material def opacity(material): - logger.debug('material.opacity(%s)', material) - return round( material.alpha, 2 ); + """ + + :param material: + :rtype: float + + """ + logger.debug("material.opacity(%s)", material) + return round(material.alpha, 2) @_material def shading(material): - logger.debug('material.shading(%s)', material) + """ + + :param material: + :return: shading type (phong or lambert) + + """ + logger.debug("material.shading(%s)", material) dispatch = { True: constants.PHONG, False: constants.LAMBERT @@ -144,21 +245,40 @@ def shading(material): @_material def specular_coef(material): - logger.debug('material.specular_coef(%s)', material) + """ + + :param material: + :rtype: float + + """ + logger.debug("material.specular_coef(%s)", material) return material.specular_hardness - + @_material def specular_color(material): - logger.debug('material.specular_color(%s)', material) + """ + + :param material: + :return: rgb value + :rtype: tuple + + """ + logger.debug("material.specular_color(%s)", material) return (material.specular_intensity * material.specular_color[0], material.specular_intensity * material.specular_color[1], material.specular_intensity * material.specular_color[2]) - + @_material def specular_map(material): - logger.debug('material.specular_map(%s)', material) + """ + + :param material: + :return: texture node for specular + + """ + logger.debug("material.specular_map(%s)", material) for texture in _valid_textures(material): if texture.use_map_specular: return texture.texture @@ -166,13 +286,25 @@ def specular_map(material): @_material def transparent(material): - logger.debug('material.transparent(%s)', material) + """ + + :param material: + :rtype: bool + + """ + logger.debug("material.transparent(%s)", material) return material.use_transparency @_material def type(material): - logger.debug('material.type(%s)', material) + """ + + :param material: + :return: THREE compatible shader type + + """ + logger.debug("material.type(%s)", material) if material.diffuse_shader != 'LAMBERT': material_type = constants.BASIC elif material.specular_intensity > 0: @@ -185,23 +317,42 @@ def type(material): @_material def use_vertex_colors(material): - logger.debug('material.use_vertex_colors(%s)', material) + """ + + :param material: + :rtype: bool + + """ + logger.debug("material.use_vertex_colors(%s)", material) return material.use_vertex_color_paint def used_materials(): - logger.debug('material.used_materials()') + """ + + :return: list of materials that are in use + :rtype: generator + + """ + logger.debug("material.used_materials()") for material in data.materials: if material.users > 0: yield material.name @_material def visible(material): - logger.debug('material.visible(%s)', material) + """ + + :param material: + :return: THREE_visible value + :rtype: bool + + """ + logger.debug("material.visible(%s)", material) try: vis = material.THREE_visible except AttributeError: - logger.debug('No THREE_visible attribute found') + logger.debug("No THREE_visible attribute found") vis = True return vis @@ -209,13 +360,27 @@ def visible(material): @_material def wireframe(material): - logger.debug('material.wireframe(%s)', material) + """ + + :param material: + :rtype: bool + + """ + logger.debug("material.wireframe(%s)", material) return material.type == WIRE - + def _valid_textures(material): + """ + + :param material: + :rtype: generator + + """ for texture in material.texture_slots: - if not texture: continue - if texture.texture.type != IMAGE: continue - logger.debug('Valid texture found %s', texture) + if not texture: + continue + if texture.texture.type != IMAGE: + continue + logger.debug("Valid texture found %s", texture) yield texture diff --git a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py index 269c0ee7a1c505..f770a5792ec43c 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py @@ -6,13 +6,25 @@ def _mesh(func): + """ + + :param func: + + """ def inner(name, *args, **kwargs): + """ + + :param name: + :param *args: + :param **kwargs: + + """ if isinstance(name, types.Mesh): mesh = name else: - mesh = data.meshes[name] + mesh = data.meshes[name] return func(mesh, *args, **kwargs) @@ -21,11 +33,17 @@ def inner(name, *args, **kwargs): @_mesh def skeletal_animation(mesh, options): - logger.debug('mesh.animation(%s, %s)', mesh, options) + """ + + :param mesh: + :param options: + + """ + logger.debug("mesh.animation(%s, %s)", mesh, options) armature = _armature(mesh) if not armature: - logger.warning('No armature found (%s)', mesh) + logger.warning("No armature found (%s)", mesh) return [] anim_type = options.get(constants.ANIMATION) @@ -34,21 +52,27 @@ def skeletal_animation(mesh, options): constants.POSE: animation.pose_animation, constants.REST: animation.rest_animation } - + func = dispatch[anim_type] #armature.data.pose_position = anim_type.upper() animations = func(armature, options) #armature.data.pose_position = pose_position - + return animations @_mesh def bones(mesh, options): - logger.debug('mesh.bones(%s)', mesh) + """ + + :param mesh: + :param options: + + """ + logger.debug("mesh.bones(%s)", mesh) armature = _armature(mesh) - if not armature: + if not armature: return [], {} round_off, round_val = utilities.rounding(options) @@ -56,34 +80,40 @@ def bones(mesh, options): #pose_position = armature.data.pose_position if anim_type == constants.OFF: - logger.info('Animation type not set, defaulting '\ - 'to using REST position for the armature.') + logger.info("Animation type not set, defaulting "\ + "to using REST position for the armature.") func = _rest_bones - #armature.data.pose_position = 'REST' + #armature.data.pose_position = "REST" else: dispatch = { constants.REST: _rest_bones, constants.POSE: _pose_bones } - logger.info('Using %s for the armature', anim_type) + logger.info("Using %s for the armature", anim_type) func = dispatch[anim_type] #armature.data.pose_position = anim_type.upper() - bones, bone_map = func(armature, round_off, round_val) + bones_, bone_map = func(armature, round_off, round_val) #armature.data.pose_position = pose_position - return (bones, bone_map) + return (bones_, bone_map) @_mesh def buffer_normal(mesh, options): + """ + + :param mesh: + :param options: + + """ normals_ = [] round_off, round_val = utilities.rounding(options) for face in mesh.tessfaces: vert_count = len(face.vertices) if vert_count is not 3: - msg = 'Non-triangulated face detected' + msg = "Non-triangulated face detected" raise exceptions.BufferGeometryError(msg) for vertex_index in face.vertices: @@ -99,13 +129,19 @@ def buffer_normal(mesh, options): @_mesh def buffer_position(mesh, options): + """ + + :param mesh: + :param options: + + """ position = [] round_off, round_val = utilities.rounding(options) for face in mesh.tessfaces: vert_count = len(face.vertices) if vert_count is not 3: - msg = 'Non-triangulated face detected' + msg = "Non-triangulated face detected" raise exceptions.BufferGeometryError(msg) for vertex_index in face.vertices: @@ -121,44 +157,56 @@ def buffer_position(mesh, options): @_mesh def buffer_uv(mesh, options): + """ + + :param mesh: + :param options: + + """ if len(mesh.uv_layers) is 0: return elif len(mesh.uv_layers) > 1: # if memory serves me correctly buffer geometry # only uses one UV layer - logger.warning('%s has more than 1 UV layer', mesh.name ) + logger.warning("%s has more than 1 UV layer", mesh.name) round_off, round_val = utilities.rounding(options) uvs_ = [] - for uv in mesh.uv_layers[0].data: - uv = (uv.uv[0], uv.uv[1]) + for uv_data in mesh.uv_layers[0].data: + uv_tuple = (uv_data.uv[0], uv_data.uv[1]) if round_off: - uv = utilities.round_off(uv, round_val) - uvs_.extend(uv) - + uv_tuple = utilities.round_off(uv_tuple, round_val) + uvs_.extend(uv_tuple) + return uvs_ @_mesh def faces(mesh, options): - logger.debug('mesh.faces(%s, %s)', mesh, options) + """ + + :param mesh: + :param options: + + """ + logger.debug("mesh.faces(%s, %s)", mesh, options) vertex_uv = len(mesh.uv_textures) > 0 has_colors = len(mesh.vertex_colors) > 0 - logger.info('Has UVs = %s', vertex_uv) - logger.info('Has vertex colours = %s', has_colors) + logger.info("Has UVs = %s", vertex_uv) + logger.info("Has vertex colours = %s", has_colors) round_off, round_val = utilities.rounding(options) if round_off: - logger.debug('Rounding off of vectors set to %s', round_off) + logger.debug("Rounding off of vectors set to %s", round_off) opt_colours = options[constants.COLORS] and has_colors opt_uvs = options[constants.UVS] and vertex_uv opt_materials = options.get(constants.FACE_MATERIALS) opt_normals = options[constants.NORMALS] - logger.debug('Vertex colours enabled = %s', opt_colours) - logger.debug('UVS enabled = %s', opt_uvs) - logger.debug('Materials enabled = %s', opt_materials) - logger.debug('Normals enabled = %s', opt_normals) + logger.debug("Vertex colours enabled = %s", opt_colours) + logger.debug("UVS enabled = %s", opt_uvs) + logger.debug("Materials enabled = %s", opt_materials) + logger.debug("Normals enabled = %s", opt_normals) uv_layers = _uvs(mesh, options) if opt_uvs else None vertex_normals = _normals(mesh, options) if opt_normals else None @@ -168,41 +216,42 @@ def faces(mesh, options): colour_indices = {} if vertex_colours: - logger.debug('Indexing colours') + logger.debug("Indexing colours") for index, colour in enumerate(vertex_colours): colour_indices[str(colour)] = index normal_indices = {} if vertex_normals: - logger.debug('Indexing normals') + logger.debug("Indexing normals") for index, normal in enumerate(vertex_normals): normal_indices[str(normal)] = index - logger.info('Parsing %d faces', len(mesh.tessfaces)) + logger.info("Parsing %d faces", len(mesh.tessfaces)) for face in mesh.tessfaces: vert_count = len(face.vertices) if vert_count not in (3, 4): - logger.error('%d vertices for face %d detected', - vert_count, face.index) - raise exceptions.NGonError('ngons are not supported') + logger.error("%d vertices for face %d detected", + vert_count, + face.index) + raise exceptions.NGonError("ngons are not supported") - materials = face.material_index is not None and opt_materials + mat_index = face.material_index is not None and opt_materials mask = { constants.QUAD: vert_count is 4, - constants.MATERIALS: materials, + constants.MATERIALS: mat_index, constants.UVS: False, constants.NORMALS: False, constants.COLORS: False } face_data = [] - + face_data.extend([v for v in face.vertices]) - + if mask[constants.MATERIALS]: face_data.append(face.material_index) - + #@TODO: this needs the same optimization as what # was done for colours and normals if uv_layers: @@ -210,10 +259,11 @@ def faces(mesh, options): layer = mesh.tessface_uv_textures[index] for uv_data in layer.data[face.index].uv: - uv = (uv_data[0], uv_data[1]) + uv_tuple = (uv_data[0], uv_data[1]) if round_off: - uv = utilities.round_off(uv, round_val) - face_data.append(uv_layer.index(uv)) + uv_tuple = utilities.round_off( + uv_tuple, round_val) + face_data.append(uv_layer.index(uv_tuple)) mask[constants.UVS] = True if vertex_normals: @@ -224,7 +274,7 @@ def faces(mesh, options): normal = utilities.round_off(normal, round_val) face_data.append(normal_indices[str(normal)]) mask[constants.NORMALS] = True - + if vertex_colours: colours = mesh.tessface_vertex_colors.active.data[face.index] @@ -241,51 +291,59 @@ def faces(mesh, options): faces_data.extend(face_data) return faces_data - + @_mesh def morph_targets(mesh, options): - logger.debug('mesh.morph_targets(%s, %s)', mesh, options) + """ + + :param mesh: + :param options: + + """ + logger.debug("mesh.morph_targets(%s, %s)", mesh, options) obj = object_.objects_using_mesh(mesh)[0] original_frame = context.scene.frame_current frame_step = options.get(constants.FRAME_STEP, 1) scene_frames = range(context.scene.frame_start, - context.scene.frame_end+1, frame_step) + context.scene.frame_end+1, + frame_step) morphs = [] round_off, round_val = utilities.rounding(options) for frame in scene_frames: - logger.info('Processing data at frame %d', frame) + logger.info("Processing data at frame %d", frame) context.scene.frame_set(frame, 0.0) morphs.append([]) - vertices = object_.extract_mesh(obj, options).vertices[:] + vertices_ = object_.extract_mesh(obj, options).vertices[:] - for vertex in vertices: + for vertex in vertices_: if round_off: vectors = [ - utilities.round_off(vertex.co.x, round_val), - utilities.round_off(vertex.co.y, round_val), + utilities.round_off(vertex.co.x, round_val), + utilities.round_off(vertex.co.y, round_val), utilities.round_off(vertex.co.z, round_val) ] else: vectors = [vertex.co.x, vertex.co.y, vertex.co.z] morphs[-1].extend(vectors) - + context.scene.frame_set(original_frame, 0.0) morphs_detected = False for index, each in enumerate(morphs): - if index is 0: continue + if index is 0: + continue morphs_detected = morphs[index-1] != each - if morphs_detected: - logger.info('Valid morph target data detected') + if morphs_detected: + logger.info("Valid morph target data detected") break - else: - logger.info('No valid morph data detected') + else: + logger.info("No valid morph data detected") return manifest = [] - for index,morph in enumerate(morphs): + for index, morph in enumerate(morphs): manifest.append({ constants.NAME: 'animation_%06d' % index, constants.VERTICES: morph @@ -296,25 +354,31 @@ def morph_targets(mesh, options): @_mesh def materials(mesh, options): - logger.debug('mesh.materials(%s, %s)', mesh, options) + """ + + :param mesh: + :param options: + + """ + logger.debug("mesh.materials(%s, %s)", mesh, options) indices = set([face.material_index for face in mesh.tessfaces]) material_sets = [(mesh.materials[index], index) for index in indices] - materials = [] + materials_ = [] maps = options.get(constants.MAPS) mix = options.get(constants.MIX_COLORS) use_colors = options.get(constants.COLORS) - logger.info('Colour mix is set to %s', mix) - logger.info('Vertex colours set to %s', use_colors) + logger.info("Colour mix is set to %s", mix) + logger.info("Vertex colours set to %s", use_colors) for mat, index in material_sets: try: dbg_color = constants.DBG_COLORS[index] except IndexError: dbg_color = constants.DBG_COLORS[0] - - logger.info('Compiling attributes for %s', mat.name) + + logger.info("Compiling attributes for %s", mat.name) attributes = { constants.COLOR_AMBIENT: material.ambient_color(mat), constants.COLOR_EMISSIVE: material.emissive_color(mat), @@ -334,58 +398,65 @@ def materials(mesh, options): if use_colors: colors = material.use_vertex_colors(mat) attributes[constants.VERTEX_COLORS] = colors - + if (use_colors and mix) or (not use_colors): colors = material.diffuse_color(mat) attributes[constants.COLOR_DIFFUSE] = colors if attributes[constants.SHADING] == constants.PHONG: - logger.info('Adding specular attributes') + logger.info("Adding specular attributes") attributes.update({ constants.SPECULAR_COEF: material.specular_coef(mat), constants.COLOR_SPECULAR: material.specular_color(mat) }) if mesh.show_double_sided: - logger.info('Double sided is on') + logger.info("Double sided is on") attributes[constants.DOUBLE_SIDED] = True - materials.append(attributes) + materials_.append(attributes) - if not maps: continue + if not maps: + continue diffuse = _diffuse_map(mat) if diffuse: - logger.info('Diffuse map found') + logger.info("Diffuse map found") attributes.update(diffuse) - + light = _light_map(mat) if light: - logger.info('Light map found') + logger.info("Light map found") attributes.update(light) specular = _specular_map(mat) if specular: - logger.info('Specular map found') + logger.info("Specular map found") attributes.update(specular) if attributes[constants.SHADING] == constants.PHONG: normal = _normal_map(mat) if normal: - logger.info('Normal map found') + logger.info("Normal map found") attributes.update(normal) bump = _bump_map(mat) if bump: - logger.info('Bump map found') + logger.info("Bump map found") attributes.update(bump) - return materials + return materials_ @_mesh def normals(mesh, options): - logger.debug('mesh.normals(%s, %s)', mesh, options) + """ + + :param mesh: + :param options: + + """ + logger.debug("mesh.normals(%s, %s)", mesh, options) normal_vectors = [] for vector in _normals(mesh, options): @@ -396,86 +467,122 @@ def normals(mesh, options): @_mesh def skin_weights(mesh, bone_map, influences): - logger.debug('mesh.skin_weights(%s)', mesh) + """ + + :param mesh: + :param bone_map: + :param influences: + + """ + logger.debug("mesh.skin_weights(%s)", mesh) return _skinning_data(mesh, bone_map, influences, 1) @_mesh def skin_indices(mesh, bone_map, influences): - logger.debug('mesh.skin_indices(%s)', mesh) + """ + + :param mesh: + :param bone_map: + :param influences: + + """ + logger.debug("mesh.skin_indices(%s)", mesh) return _skinning_data(mesh, bone_map, influences, 0) @_mesh def texture_registration(mesh): - logger.debug('mesh.texture_registration(%s)', mesh) - materials = mesh.materials or [] + """ + + :param mesh: + + """ + logger.debug("mesh.texture_registration(%s)", mesh) + materials_ = mesh.materials or [] registration = {} funcs = ( - (constants.MAP_DIFFUSE, material.diffuse_map), + (constants.MAP_DIFFUSE, material.diffuse_map), (constants.SPECULAR_MAP, material.specular_map), - (constants.LIGHT_MAP, material.light_map), - (constants.BUMP_MAP, material.bump_map), + (constants.LIGHT_MAP, material.light_map), + (constants.BUMP_MAP, material.bump_map), (constants.NORMAL_MAP, material.normal_map) ) - + def _registration(file_path, file_name): + """ + + :param file_path: + :param file_name: + + """ return { 'file_path': file_path, 'file_name': file_name, 'maps': [] } - logger.info('found %d materials', len(materials)) - for mat in materials: + logger.info("found %d materials", len(materials_)) + for mat in materials_: for (key, func) in funcs: tex = func(mat) - if tex is None: continue + if tex is None: + continue - logger.info('%s has texture %s', key, tex.name) + logger.info("%s has texture %s", key, tex.name) file_path = texture.file_path(tex) file_name = texture.file_name(tex) - hash_ = utilities.hash(file_path) - - reg = registration.setdefault(hash_, + reg = registration.setdefault( + utilities.hash(file_path), _registration(file_path, file_name)) - reg['maps'].append(key) + reg["maps"].append(key) return registration @_mesh def uvs(mesh, options): - logger.debug('mesh.uvs(%s, %s)', mesh, options) - uvs = [] + """ + + :param mesh: + :param options: + + """ + logger.debug("mesh.uvs(%s, %s)", mesh, options) + uvs_ = [] for layer in _uvs(mesh, options): - uvs.append([]) - logger.info('Parsing UV layer %d', len(uvs)) + uvs_.append([]) + logger.info("Parsing UV layer %d", len(uvs_)) for pair in layer: - uvs[-1].extend(pair) - return uvs + uvs_[-1].extend(pair) + return uvs_ @_mesh def vertex_colors(mesh): - logger.debug('mesh.vertex_colors(%s)', mesh) + """ + + :param mesh: + + """ + logger.debug("mesh.vertex_colors(%s)", mesh) vertex_colours = [] try: vertex_colour = mesh.tessface_vertex_colors.active.data except AttributeError: - logger.info('No vertex colours found') + logger.info("No vertex colours found") return for face in mesh.tessfaces: colours = (vertex_colour[face.index].color1, - vertex_colour[face.index].color2, - vertex_colour[face.index].color3, - vertex_colour[face.index].color4) + vertex_colour[face.index].color2, + vertex_colour[face.index].color3, + vertex_colour[face.index].color4) for colour in colours: colour = utilities.rgb2int((colour.r, colour.g, colour.b)) @@ -488,8 +595,14 @@ def vertex_colors(mesh): @_mesh def vertices(mesh, options): - logger.debug('mesh.vertices(%s, %s)', mesh, options) - vertices = [] + """ + + :param mesh: + :param options: + + """ + logger.debug("mesh.vertices(%s, %s)", mesh, options) + vertices_ = [] round_off, round_val = utilities.rounding(options) @@ -498,26 +611,31 @@ def vertices(mesh, options): if round_off: vector = utilities.round_off(vector, round_val) - vertices.extend(vector) + vertices_.extend(vector) - return vertices + return vertices_ def _normal_map(mat): + """ + + :param mat: + + """ tex = material.normal_map(mat) if tex is None: return - logger.info('Found normal texture map %s', tex.name) + logger.info("Found normal texture map %s", tex.name) normal = { - constants.MAP_NORMAL: + constants.MAP_NORMAL: texture.file_name(tex), constants.MAP_NORMAL_FACTOR: - material.normal_scale(mat), - constants.MAP_NORMAL_ANISOTROPY: + material.normal_scale(mat), + constants.MAP_NORMAL_ANISOTROPY: texture.anisotropy(tex), - constants.MAP_NORMAL_WRAP: texture.wrap(tex), + constants.MAP_NORMAL_WRAP: texture.wrap(tex), constants.MAP_NORMAL_REPEAT: texture.repeat(tex) } @@ -525,75 +643,95 @@ def _normal_map(mat): def _bump_map(mat): + """ + + :param mat: + + """ tex = material.bump_map(mat) if tex is None: return - logger.info('Found bump texture map %s', tex.name) + logger.info("Found bump texture map %s", tex.name) bump = { - constants.MAP_BUMP: + constants.MAP_BUMP: texture.file_name(tex), - constants.MAP_BUMP_ANISOTROPY: + constants.MAP_BUMP_ANISOTROPY: texture.anisotropy(tex), constants.MAP_BUMP_WRAP: texture.wrap(tex), constants.MAP_BUMP_REPEAT: texture.repeat(tex), constants.MAP_BUMP_SCALE: - material.bump_scale(mat), + material.bump_scale(mat), } return bump def _specular_map(mat): + """ + + :param mat: + + """ tex = material.specular_map(mat) if tex is None: - return + return - logger.info('Found specular texture map %s', tex.name) + logger.info("Found specular texture map %s", tex.name) specular = { - constants.MAP_SPECULAR: + constants.MAP_SPECULAR: texture.file_name(tex), - constants.MAP_SPECULAR_ANISOTROPY: + constants.MAP_SPECULAR_ANISOTROPY: texture.anisotropy(tex), constants.MAP_SPECULAR_WRAP: texture.wrap(tex), constants.MAP_SPECULAR_REPEAT: texture.repeat(tex) } - return specular + return specular def _light_map(mat): + """ + + :param mat: + + """ tex = material.light_map(mat) if tex is None: - return + return - logger.info('Found light texture map %s', tex.name) + logger.info("Found light texture map %s", tex.name) light = { - constants.MAP_LIGHT: + constants.MAP_LIGHT: texture.file_name(tex), - constants.MAP_LIGHT_ANISOTROPY: + constants.MAP_LIGHT_ANISOTROPY: texture.anisotropy(tex), constants.MAP_LIGHT_WRAP: texture.wrap(tex), constants.MAP_LIGHT_REPEAT: texture.repeat(tex) } - return light + return light def _diffuse_map(mat): + """ + + :param mat: + + """ tex = material.diffuse_map(mat) if tex is None: - return + return - logger.info('Found diffuse texture map %s', tex.name) + logger.info("Found diffuse texture map %s", tex.name) diffuse = { - constants.MAP_DIFFUSE: + constants.MAP_DIFFUSE: texture.file_name(tex), - constants.MAP_DIFFUSE_ANISOTROPY: + constants.MAP_DIFFUSE_ANISOTROPY: texture.anisotropy(tex), constants.MAP_DIFFUSE_WRAP: texture.wrap(tex), constants.MAP_DIFFUSE_REPEAT: texture.repeat(tex) @@ -603,6 +741,12 @@ def _diffuse_map(mat): def _normals(mesh, options): + """ + + :param mesh: + :param options: + + """ vectors = [] round_off, round_val = utilities.rounding(options) @@ -626,41 +770,60 @@ def _normals(mesh, options): def _uvs(mesh, options): + """ + + :param mesh: + :param options: + + """ uv_layers = [] round_off, round_val = utilities.rounding(options) for layer in mesh.uv_layers: uv_layers.append([]) - for uv in layer.data: - uv = (uv.uv[0], uv.uv[1]) + for uv_data in layer.data: + uv_tuple = (uv_data.uv[0], uv_data.uv[1]) if round_off: - uv = utilities.round_off(uv, round_val) + uv_tuple = utilities.round_off(uv_tuple, round_val) - if uv not in uv_layers[-1]: - uv_layers[-1].append(uv) + if uv_tuple not in uv_layers[-1]: + uv_layers[-1].append(uv_tuple) return uv_layers def _armature(mesh): + """ + + :param mesh: + + """ obj = object_.objects_using_mesh(mesh)[0] armature = obj.find_armature() if armature: - logger.info('Found armature %s for %s', armature.name, obj.name) + logger.info("Found armature %s for %s", armature.name, obj.name) else: - logger.info('Found no armature for %s', obj.name) + logger.info("Found no armature for %s", obj.name) return armature def _skinning_data(mesh, bone_map, influences, array_index): + """ + + :param mesh: + :param bone_map: + :param influences: + :param array_index: + + """ armature = _armature(mesh) manifest = [] - if not armature: + if not armature: return manifest obj = object_.objects_using_mesh(mesh)[0] - logger.debug('Skinned object found %s', obj.name) + logger.debug("Skinned object found %s", obj.name) for vertex in mesh.vertices: bone_array = [] @@ -691,7 +854,14 @@ def _skinning_data(mesh, bone_map, influences, array_index): def _pose_bones(armature, round_off, round_val): - bones = [] + """ + + :param armature: + :param round_off: + :param round_val: + + """ + bones_ = [] bone_map = {} bone_count = 0 @@ -727,7 +897,7 @@ def _pose_bones(armature, round_off, round_val): ) rot = ( utilities.round_off(rot.x, round_val), - utilities.round_off(rot.z, round_val), + utilities.round_off(rot.z, round_val), -utilities.round_off(rot.y, round_val), utilities.round_off(rot.w, round_val) ) @@ -740,29 +910,36 @@ def _pose_bones(armature, round_off, round_val): pos = (pos.x, pos.z, -pos.y) rot = (rot.x, rot.z, -rot.y, rot.w) scl = (scl.x, scl.z, scl.y) - bones.append({ + bones_.append({ constants.PARENT: bone_index, constants.NAME: armature_bone.name, constants.POS: pos, constants.ROTQ: rot, - constants.SCL: scl + constants.SCL: scl }) - return bones, bone_map + return bones_, bone_map def _rest_bones(armature, round_off, round_val): - bones = [] + """ + + :param armature: + :param round_off: + :param round_val: + + """ + bones_ = [] bone_map = {} bone_count = 0 bone_index_rel = 0 for bone in armature.data.bones: - logger.info('Parsing bone %s', bone.name) + logger.info("Parsing bone %s", bone.name) if not bone.use_deform: - logger.debug('Ignoring bone %s at: %d', - bone.name, bone_index_rel) + logger.debug("Ignoring bone %s at: %d", + bone.name, bone_index_rel) continue if bone.parent is None: @@ -787,21 +964,21 @@ def _rest_bones(armature, round_off, round_val): y_axis = bone_world_pos.z z_axis = -bone_world_pos.y - logger.debug('Adding bone %s at: %s, %s', - bone.name, bone_index, bone_index_rel) + logger.debug("Adding bone %s at: %s, %s", + bone.name, bone_index, bone_index_rel) bone_map[bone_count] = bone_index_rel bone_index_rel += 1 #@TODO: the rotq probably should not have these # hard coded values - bones.append({ + bones_.append({ constants.PARENT: bone_index, constants.NAME: bone.name, constants.POS: (x_axis, y_axis, z_axis), - constants.ROTQ: (0,0,0,1) + constants.ROTQ: (0, 0, 0, 1) }) bone_count += 1 - return (bones, bone_map) + return (bones_, bone_map) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/object.py b/utils/exporters/blender/addons/io_three/exporter/api/object.py index e104422bf2317a..6e6934b48f886c 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/object.py @@ -17,12 +17,10 @@ PERSP, ORTHO, RENDER, - NO_SHADOW + NO_SHADOW, + ZYX ) -ROTATE_X_PI2 = mathutils.Quaternion((1.0, 0.0, 0.0), - math.radians(-90.0)).to_matrix().to_4x4() - # Blender doesn't seem to have a good way to link a mesh back to the # objects that are instancing it, or it is bloody obvious and I haven't @@ -32,20 +30,43 @@ def _object(func): + """ + + :param func: + + """ + + def inner(arg, *args, **kwargs): + """ - def inner(name, *args, **kwargs): + :param arg: + :param *args: + :param **kwargs: - if isinstance(name, types.Object): - obj = name + """ + + if isinstance(arg, types.Object): + obj = arg else: - obj = data.objects[name] + obj = data.objects[arg] return func(obj, *args, **kwargs) return inner +def clear_mesh_map(): + """Clears the mesh map, required on initialization""" + _MESH_MAP.clear() + + def assemblies(valid_types, options): + """ + + :param valid_types: + :param options: + + """ logger.debug('object.assemblies(%s)', valid_types) for obj in data.objects: @@ -60,6 +81,11 @@ def assemblies(valid_types, options): @_object def cast_shadow(obj): + """ + + :param obj: + + """ logger.debug('object.cast_shadow(%s)', obj) if obj.type == LAMP: if obj.data.type in (SPOT, SUN): @@ -79,6 +105,12 @@ def cast_shadow(obj): @_object def children(obj, valid_types): + """ + + :param obj: + :param valid_types: + + """ logger.debug('object.children(%s, %s)', obj, valid_types) for child in obj.children: if child.type in valid_types: @@ -87,6 +119,11 @@ def children(obj, valid_types): @_object def material(obj): + """ + + :param obj: + + """ logger.debug('object.material(%s)', obj) try: return obj.material_slots[0].name @@ -96,38 +133,54 @@ def material(obj): @_object def mesh(obj, options): + """ + + :param obj: + :param options: + + """ logger.debug('object.mesh(%s, %s)', obj, options) if obj.type != MESH: return - - for mesh, objects in _MESH_MAP.items(): + + for mesh_, objects in _MESH_MAP.items(): if obj in objects: - return mesh + return mesh_ else: logger.debug('Could not map object, updating manifest') - mesh = extract_mesh(obj, options) - if len(mesh.tessfaces) is not 0: - manifest = _MESH_MAP.setdefault(mesh.name, []) + mesh_ = extract_mesh(obj, options) + if len(mesh_.tessfaces) is not 0: + manifest = _MESH_MAP.setdefault(mesh_.name, []) manifest.append(obj) - mesh = mesh.name + mesh_name = mesh_.name else: # possibly just being used as a controller logger.info('Object %s has no faces', obj.name) - mesh = None + mesh_name = None - return mesh + return mesh_name @_object def name(obj): + """ + + :param obj: + + """ return obj.name @_object def node_type(obj): + """ + + :param obj: + + """ logger.debug('object.node_type(%s)', obj) # standard transformation nodes are inferred - if obj.type == MESH: + if obj.type == MESH: return constants.MESH.title() elif obj.type == EMPTY: return constants.OBJECT.title() @@ -150,18 +203,29 @@ def node_type(obj): except AttributeError: msg = 'Invalid type: %s' % obj.type raise exceptions.UnsupportedObjectType(msg) - + def nodes(valid_types, options): + """ + + :param valid_types: + :param options: + + """ for obj in data.objects: if _valid_node(obj, valid_types, options): yield obj.name @_object def position(obj, options): + """ + + :param obj: + :param options: + + """ logger.debug('object.position(%s)', obj) - parent = obj.parent is None - vector = _decompose_matrix(obj, local=not parent)[0] + vector = _decompose_matrix(obj)[0] vector = (vector.x, vector.y, vector.z) round_off, round_val = utilities.rounding(options) @@ -173,6 +237,11 @@ def position(obj, options): @_object def receive_shadow(obj): + """ + + :param obj: + + """ if obj.type == MESH: mat = material(obj) if mat: @@ -183,9 +252,15 @@ def receive_shadow(obj): @_object def rotation(obj, options): + """ + + :param obj: + :param options: + + """ logger.debug('object.rotation(%s)', obj) - vector = _decompose_matrix(obj)[1] - vector = (vector.x, vector.y, vector.z, vector.w) + vector = _decompose_matrix(obj)[1].to_euler(ZYX) + vector = (vector.x, vector.y, vector.z) round_off, round_val = utilities.rounding(options) if round_off: @@ -196,6 +271,12 @@ def rotation(obj, options): @_object def scale(obj, options): + """ + + :param obj: + :param options: + + """ logger.debug('object.scale(%s)', obj) vector = _decompose_matrix(obj)[2] vector = (vector.x, vector.y, vector.z) @@ -209,56 +290,80 @@ def scale(obj, options): @_object def select(obj): + """ + + :param obj: + + """ obj.select = True @_object def unselect(obj): + """ + + :param obj: + + """ obj.select = False @_object def visible(obj): + """ + + :param obj: + + """ logger.debug('object.visible(%s)', obj) return obj.is_visible(context.scene) def extract_mesh(obj, options, recalculate=False): + """ + + :param obj: + :param options: + :param recalculate: (Default value = False) + + """ logger.debug('object.extract_mesh(%s, %s)', obj, options) - mesh = obj.to_mesh(context.scene, True, RENDER) + mesh_node = obj.to_mesh(context.scene, True, RENDER) # transfer the geometry type to the extracted mesh - mesh.THREE_geometry_type = obj.data.THREE_geometry_type + mesh_node.THREE_geometry_type = obj.data.THREE_geometry_type # now determine whether or not to export using the geometry type # set globally from the exporter's options or to use the local # override on the mesh node itself - opt_buffer = options.get(constants.GEOMETRY_TYPE) + opt_buffer = options.get(constants.GEOMETRY_TYPE) opt_buffer = opt_buffer == constants.BUFFER_GEOMETRY - prop_buffer = mesh.THREE_geometry_type == constants.BUFFER_GEOMETRY + prop_buffer = mesh_node.THREE_geometry_type == constants.BUFFER_GEOMETRY # if doing buffer geometry it is imperative to triangulate the mesh if opt_buffer or prop_buffer: original_mesh = obj.data - obj.data = mesh - logger.debug('swapped %s for %s', original_mesh.name, mesh.name) - + obj.data = mesh_node + logger.debug('swapped %s for %s', + original_mesh.name, + mesh_node.name) + obj.select = True bpy.context.scene.objects.active = obj logger.info('Applying triangulation to %s', obj.data.name) bpy.ops.object.modifier_add(type='TRIANGULATE') - bpy.ops.object.modifier_apply(apply_as='DATA', - modifier='Triangulate') + bpy.ops.object.modifier_apply(apply_as='DATA', + modifier='Triangulate') obj.data = original_mesh obj.select = False # recalculate the normals to face outwards, this is usually - # best after applying a modifiers, especialy for something + # best after applying a modifiers, especialy for something # like the mirror if recalculate: logger.info('Recalculating normals') original_mesh = obj.data - obj.data = mesh + obj.data = mesh_node bpy.context.scene.objects.active = obj bpy.ops.object.mode_set(mode='EDIT') @@ -270,64 +375,72 @@ def extract_mesh(obj, options, recalculate=False): if not options.get(constants.SCENE): xrot = mathutils.Matrix.Rotation(-math.pi/2, 4, 'X') - mesh.transform(xrot * obj.matrix_world) + mesh_node.transform(xrot * obj.matrix_world) # now generate a unique name index = 0 while True: if index is 0: - name = '%sGeometry' % obj.data.name + mesh_name = '%sGeometry' % obj.data.name else: - name = '%sGeometry.%d' % (obj.data.name, index) + mesh_name = '%sGeometry.%d' % (obj.data.name, index) try: - data.meshes[name] + data.meshes[mesh_name] index += 1 except KeyError: break - mesh.name = name + mesh_node.name = mesh_name + + mesh_node.update(calc_tessface=True) + mesh_node.calc_normals() + mesh_node.calc_tessface() + scale_ = options.get(constants.SCALE, 1) + mesh_node.transform(mathutils.Matrix.Scale(scale_, 4)) + + return mesh_node - mesh.update(calc_tessface=True) - mesh.calc_normals() - mesh.calc_tessface() - scale = options.get(constants.SCALE, 1) - mesh.transform(mathutils.Matrix.Scale(scale, 4)) - return mesh +def objects_using_mesh(mesh_node): + """ + :param mesh_node: + :return: list of object names -def objects_using_mesh(mesh): - logger.debug('object.objects_using_mesh(%s)', mesh) - for name, objects in _MESH_MAP.items(): - if name == mesh.name: + """ + logger.debug('object.objects_using_mesh(%s)', mesh_node) + for mesh_name, objects in _MESH_MAP.items(): + if mesh_name == mesh_node.name: return objects else: logger.warning('Could not find mesh mapping') def prep_meshes(options): - ''' - Prep the mesh nodes. Preperation includes identifying: + """Prep the mesh nodes. Preperation includes identifying: - nodes that are on visible layers - nodes that have export disabled - nodes that have modifiers that need to be applied - ''' + + :param options: + + """ logger.debug('object.prep_meshes(%s)', options) mapping = {} visible_layers = _visible_scene_layers() - + for obj in data.objects: - if obj.type != MESH: + if obj.type != MESH: continue # this is ideal for skipping controller or proxy nodes # that may apply to a Blender but not a 3js scene - if not _on_visible_layer(obj, visible_layers): + if not _on_visible_layer(obj, visible_layers): logger.info('%s is not on a visible layer', obj.name) continue # if someone really insists on a visible node not being exportable - if not obj.THREE_export: + if not obj.THREE_export: logger.info('%s export is disabled', obj.name) continue @@ -338,59 +451,93 @@ def prep_meshes(options): # the mesh making the mesh unique to this particular object if len(obj.modifiers): logger.info('%s has modifiers' % obj.name) - mesh = extract_mesh(obj, options, recalculate=True) - _MESH_MAP[mesh.name] = [obj] + mesh_node = extract_mesh(obj, options, recalculate=True) + _MESH_MAP[mesh_node.name] = [obj] continue - logger.info('adding mesh %s.%s to prep', - obj.name, obj.data.name) + logger.info('adding mesh %s.%s to prep', + obj.name, obj.data.name) manifest = mapping.setdefault(obj.data.name, []) manifest.append(obj) - + # now associate the extracted mesh node with all the objects # that are instancing it for objects in mapping.values(): - mesh = extract_mesh(objects[0], options) - _MESH_MAP[mesh.name] = objects + mesh_node = extract_mesh(objects[0], options) + _MESH_MAP[mesh_node.name] = objects def extracted_meshes(): + """ + + :return: names of extracted mesh nodes + + """ logger.debug('object.extracted_meshes()') return [key for key in _MESH_MAP.keys()] def _decompose_matrix(obj, local=False): + """ + + :param obj: + :param local: (Default value = False) + + """ + rotate_x_pi2 = mathutils.Quaternion((1.0, 0.0, 0.0), + math.radians(-90.0)) + rotate_x_pi2 = rotate_x_pi2.to_matrix().to_4x4() + if local: - matrix = ROTATE_X_PI2 * obj.matrix_local + matrix = rotate_x_pi2 * obj.matrix_local else: - matrix = ROTATE_X_PI2 * obj.matrix_world + matrix = rotate_x_pi2 * obj.matrix_world return matrix.decompose() def _on_visible_layer(obj, visible_layers): - visible = True + """ + + :param obj: + :param visible_layers: + + """ + is_visible = True for index, layer in enumerate(obj.layers): if layer and index not in visible_layers: logger.info('%s is on a hidden layer', obj.name) - visible = False + is_visible = False break - return visible + return is_visible def _visible_scene_layers(): + """ + + :return: list of visiible layer indices + + """ visible_layers = [] for index, layer in enumerate(context.scene.layers): - if layer: visible_layers.append(index) + if layer: + visible_layers.append(index) return visible_layers def _valid_node(obj, valid_types, options): + """ + + :param obj: + :param valid_types: + :param options: + + """ if obj.type not in valid_types: return False # skip objects that are not on visible layers visible_layers = _visible_scene_layers() - if not _on_visible_layer(obj, visible_layers): + if not _on_visible_layer(obj, visible_layers): return False try: diff --git a/utils/exporters/blender/addons/io_three/exporter/api/texture.py b/utils/exporters/blender/addons/io_three/exporter/api/texture.py index 4f719fe892883b..7c020f59948fca 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/texture.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/texture.py @@ -5,13 +5,25 @@ def _texture(func): + """ + + :param func: + + """ def inner(name, *args, **kwargs): + """ + + :param name: + :param *args: + :param **kwargs: + + """ if isinstance(name, types.Texture): texture = name else: - texture = data.textures[name] + texture = data.textures[name] return func(texture, *args, **kwargs) @@ -20,37 +32,67 @@ def inner(name, *args, **kwargs): @_texture def anisotropy(texture): - logger.debug('texture.file_path(%s)', texture) + """ + + :param texture: + :return: filter_size value + + """ + logger.debug("texture.file_path(%s)", texture) return texture.filter_size @_texture def file_name(texture): - logger.debug('texture.file_name(%s)', texture) + """ + + :param texture: + :return: file name + + """ + logger.debug("texture.file_name(%s)", texture) if texture.image: return image.file_name(texture.image) @_texture def file_path(texture): - logger.debug('texture.file_path(%s)', texture) + """ + + :param texture: + :return: file path + + """ + logger.debug("texture.file_path(%s)", texture) if texture.image: return image.file_path(texture.image) @_texture def image_node(texture): - logger.debug('texture.image_node(%s)', texture) + """ + + :param texture: + :return: texture's image node + + """ + logger.debug("texture.image_node(%s)", texture) return texture.image @_texture def mag_filter(texture): - logger.debug('texture.mag_filter(%s)', texture) + """ + + :param texture: + :return: THREE_mag_filter value + + """ + logger.debug("texture.mag_filter(%s)", texture) try: val = texture.THREE_mag_filter except AttributeError: - logger.debug('No THREE_mag_filter attribute found') + logger.debug("No THREE_mag_filter attribute found") val = MAG_FILTER return val @@ -58,44 +100,76 @@ def mag_filter(texture): @_texture def mapping(texture): - logger.debug('texture.mapping(%s)', texture) + """ + + :param texture: + :return: THREE_mapping value + + """ + logger.debug("texture.mapping(%s)", texture) try: val = texture.THREE_mapping except AttributeError: - logger.debug('No THREE_mapping attribute found') + logger.debug("No THREE_mapping attribute found") val = MAPPING return val + + @_texture def min_filter(texture): - logger.debug('texture.min_filter(%s)', texture) + """ + + :param texture: + :return: THREE_min_filter value + + """ + logger.debug("texture.min_filter(%s)", texture) try: val = texture.THREE_min_filter except AttributeError: - logger.debug('No THREE_min_filter attribute found') - val = MIN_FILTER + logger.debug("No THREE_min_filter attribute found") + val = MIN_FILTER return val @_texture def repeat(texture): - logger.debug('texture.repeat(%s)', texture) + """The repeat parameters of the texture node + + :param texture: + :returns: repeat_x, and repeat_y values + + """ + logger.debug("texture.repeat(%s)", texture) return (texture.repeat_x, texture.repeat_y) @_texture def wrap(texture): - logger.debug('texture.wrap(%s)', texture) + """The wrapping parameters of the texture node + + :param texture: + :returns: tuple of THREE compatible wrapping values + + """ + logger.debug("texture.wrap(%s)", texture) wrapping = { - True: constants.WRAPPING.MIRROR, + True: constants.WRAPPING.MIRROR, False: constants.WRAPPING.REPEAT } - return (wrapping[texture.use_mirror_x], wrapping[texture.use_mirror_y]) + return (wrapping[texture.use_mirror_x], + wrapping[texture.use_mirror_y]) def textures(): - logger.debug('texture.textures()') + """ + + :return: list of texture node names that are IMAGE + + """ + logger.debug("texture.textures()") for texture in data.textures: if texture.type == IMAGE: yield texture.name diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index 0e6fe8bad1c073..72c514df1331cf 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -115,7 +115,8 @@ def metadata(self): def copy(self, scene=True): """Copy the geometry definitions to a standard dictionary. - :param scene: toggle for scene formatting (Default = True) + :param scene: toggle for scene formatting + (Default value = True) :type scene: bool :rtype: dict @@ -168,7 +169,8 @@ def write(self, filepath=None): """Write the geometry definitions to disk. Uses the desitnation path of the scene. - :param filepath: optional output file path (Default=None) + :param filepath: optional output file path + (Default value = None) :type filepath: str """ diff --git a/utils/exporters/blender/addons/io_three/exporter/image.py b/utils/exporters/blender/addons/io_three/exporter/image.py index a91bb79de782c1..575b6506019b51 100644 --- a/utils/exporters/blender/addons/io_three/exporter/image.py +++ b/utils/exporters/blender/addons/io_three/exporter/image.py @@ -36,7 +36,7 @@ def copy_texture(self, func=io.copy): """Copy the texture. self.filepath > self.destination - :param func: Optional function override (Default = io.copy) + :param func: Optional function override (Default value = io.copy) arguments are (, ) :return: path the texture was copied to diff --git a/utils/exporters/blender/addons/io_three/exporter/io.py b/utils/exporters/blender/addons/io_three/exporter/io.py index 81ba137ef67271..69aab0e2502717 100644 --- a/utils/exporters/blender/addons/io_three/exporter/io.py +++ b/utils/exporters/blender/addons/io_three/exporter/io.py @@ -39,7 +39,7 @@ def dump(filepath, data, options=None): :param filepath: output file path :param data: serializable data to write to disk - :param options: (Default = None) + :param options: (Default value = None) :type options: dict """ diff --git a/utils/exporters/blender/addons/io_three/exporter/object.py b/utils/exporters/blender/addons/io_three/exporter/object.py index 220c6383cc3875..1e313d38b742ce 100644 --- a/utils/exporters/blender/addons/io_three/exporter/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/object.py @@ -110,11 +110,11 @@ def _node_setup(self): elif self[constants.TYPE] in lights: self._init_light() - for child in api.object.children(self.node, self.scene.valid_types): - if not self.get(constants.CHILDREN): - self[constants.CHILDREN] = [Object(child, parent=self)] - else: - self[constants.CHILDREN].append(Object(child, parent=self)) + #for child in api.object.children(self.node, self.scene.valid_types): + # if not self.get(constants.CHILDREN): + # self[constants.CHILDREN] = [Object(child, parent=self)] + # else: + # self[constants.CHILDREN].append(Object(child, parent=self)) def _root_setup(self): """Applies to a root/scene object""" diff --git a/utils/exporters/blender/addons/io_three/exporter/scene.py b/utils/exporters/blender/addons/io_three/exporter/scene.py index cf021d469e8fae..c2521de5076f3b 100644 --- a/utils/exporters/blender/addons/io_three/exporter/scene.py +++ b/utils/exporters/blender/addons/io_three/exporter/scene.py @@ -206,7 +206,7 @@ def _parse_objects(self): self[constants.UUID] = utilities.id_from_name(scene_name) objects = [] - for node in api.object.assemblies(self.valid_types, self.options): + for node in api.object.nodes(self.valid_types, self.options): logger.info("Parsing object %s", node) obj = object_.Object(node, parent=self[constants.OBJECT]) objects.append(obj) diff --git a/utils/exporters/blender/addons/io_three/exporter/utilities.py b/utils/exporters/blender/addons/io_three/exporter/utilities.py index 605371d41cba84..87e773cfaf7a2c 100644 --- a/utils/exporters/blender/addons/io_three/exporter/utilities.py +++ b/utils/exporters/blender/addons/io_three/exporter/utilities.py @@ -74,7 +74,7 @@ def round_off(value, ndigits=ROUND): """Round off values to specified limit :param value: value(s) to round off - :param ndigits: limit (Default = ROUND) + :param ndigits: limit (Default value = ROUND) :type value: float|list|tuple :return: the same data type that was passed :rtype: float|list|tuple diff --git a/utils/exporters/blender/addons/io_three/logger.py b/utils/exporters/blender/addons/io_three/logger.py index cf6e178cac96e9..5e15d265a433dd 100644 --- a/utils/exporters/blender/addons/io_three/logger.py +++ b/utils/exporters/blender/addons/io_three/logger.py @@ -20,7 +20,7 @@ def init(filename, level=constants.DEBUG): """Initialize the logger. :param filename: base name of the log file - :param level: logging level (Default = DEBUG) + :param level: logging level (Default value = DEBUG) """ global LOG_FILE From 8a2fb4280bbd90f12808a26a985330dff016fe0e Mon Sep 17 00:00:00 2001 From: Jesse Wardle Date: Thu, 12 Feb 2015 12:09:16 -0700 Subject: [PATCH 118/333] Added missing constants. --- .../api/constants/CustomBlendingEquations.html | 4 +++- docs/api/constants/Textures.html | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/api/constants/CustomBlendingEquations.html b/docs/api/constants/CustomBlendingEquations.html index b27f99eb9a5708..bee4aae4586394 100644 --- a/docs/api/constants/CustomBlendingEquations.html +++ b/docs/api/constants/CustomBlendingEquations.html @@ -13,7 +13,9 @@

Equations

THREE.AddEquation
THREE.SubtractEquation
- THREE.ReverseSubtractEquation + THREE.ReverseSubtractEquation
+ THREE.MinEquation
+ THREE.MaxEquation

Destination Factors

diff --git a/docs/api/constants/Textures.html b/docs/api/constants/Textures.html index f62109b263016c..165604b3b457ce 100644 --- a/docs/api/constants/Textures.html +++ b/docs/api/constants/Textures.html @@ -21,6 +21,8 @@

Mapping Modes

THREE.UVMapping
THREE.CubeReflectionMapping
THREE.CubeRefractionMapping
+ THREE.EquirectangularReflectionMapping
+ THREE.EquirectangularRefractionMapping
THREE.SphericalReflectionMapping @@ -49,8 +51,8 @@

Data Types

THREE.UnsignedShortType
THREE.IntType
THREE.UnsignedIntType
- THREE.HalfFloatType
- THREE.FloatType + THREE.FloatType
+ THREE.HalfFloatType

Pixel Types

@@ -66,10 +68,11 @@

Pixel Formats

THREE.RGBFormat
THREE.RGBAFormat
THREE.LuminanceFormat
- THREE.LuminanceAlphaFormat + THREE.LuminanceAlphaFormat
+ THREE.RGBEFormat -

Compressed Texture Formats

+

DDS / ST3C Compressed Texture Formats

THREE.RGB_S3TC_DXT1_Format
THREE.RGBA_S3TC_DXT1_Format
@@ -77,6 +80,13 @@

Compressed Texture Formats

THREE.RGBA_S3TC_DXT5_Format
+

PVRTC Compressed Texture Formats

+
+ THREE.RGB_PVRTC_4BPPV1_Format
+ THREE.RGB_PVRTC_2BPPV1_Format
+ THREE.RGBA_PVRTC_4BPPV1_Format
+ THREE.RGBA_PVRTC_2BPPV1_Format +

Source

From b3cdf8bf7966f9a5fcea7816b2677a8b7df3d411 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Feb 2015 14:34:43 -0800 Subject: [PATCH 119/333] Editor: Hacky/temporal VR implementation. --- editor/index.html | 3 +++ editor/js/Player.js | 1 + editor/js/libs/app.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/editor/index.html b/editor/index.html index 34614028a187dd..69e361b686bfa5 100644 --- a/editor/index.html +++ b/editor/index.html @@ -51,6 +51,9 @@ + + + diff --git a/editor/js/Player.js b/editor/js/Player.js index be89a651ade271..72194b8a00242e 100644 --- a/editor/js/Player.js +++ b/editor/js/Player.js @@ -27,6 +27,7 @@ var Player = function ( editor ) { container.setDisplay( '' ); + player.setVR( editor.config.getKey( 'project/vr' ) ); player.load( editor.toJSON() ); player.setSize( container.dom.offsetWidth, container.dom.offsetHeight ); player.play(); diff --git a/editor/js/libs/app.js b/editor/js/libs/app.js index c4c4d5bda0e935..5e1bbdd389fa8b 100644 --- a/editor/js/libs/app.js +++ b/editor/js/libs/app.js @@ -6,9 +6,13 @@ var APP = { Player: function () { + var scope = this; + var loader = new THREE.ObjectLoader(); var camera, scene, renderer; + var vr, controls; + var events = {}; this.dom = undefined; @@ -70,6 +74,18 @@ var APP = { this.dom = renderer.domElement; + if ( vr === true ) { + + controls = new THREE.VRControls( camera ); + renderer = new THREE.VREffect( renderer ); + + this.dom.addEventListener( 'dblclick', function () { + + renderer.setFullScreen( true ); + + } ); + } + }; this.setCamera = function ( value ) { @@ -80,8 +96,19 @@ var APP = { }; + this.setVR = function ( value ) { + + vr = value; + + }; + this.setSize = function ( width, height ) { + if ( vr ) { + width = 1280; + height = 800; + } + this.width = width; this.height = height; @@ -110,6 +137,8 @@ var APP = { dispatch( events.update, { time: time, delta: time - prevTime } ); + if ( vr ) controls.update(); + renderer.render( scene, camera ); prevTime = time; From 39289c9dece88d87638344da5616c8df0ef4a05c Mon Sep 17 00:00:00 2001 From: paulmasson Date: Thu, 12 Feb 2015 15:10:45 -0800 Subject: [PATCH 120/333] Remove unused variable --- src/extras/geometries/ParametricGeometry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extras/geometries/ParametricGeometry.js b/src/extras/geometries/ParametricGeometry.js index 2297fc637dde97..f31abaa8fdeeac 100644 --- a/src/extras/geometries/ParametricGeometry.js +++ b/src/extras/geometries/ParametricGeometry.js @@ -23,7 +23,7 @@ THREE.ParametricGeometry = function ( func, slices, stacks ) { var faces = this.faces; var uvs = this.faceVertexUvs[ 0 ]; - var i, il, j, p; + var i, j, p; var u, v; var stackCount = stacks + 1; From 933be4a2ecad6ea1d2342af2f4ab0c4476465057 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Feb 2015 17:20:13 -0800 Subject: [PATCH 121/333] ObjectLoader: Code clean up. --- src/loaders/ObjectLoader.js | 74 ++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 5a793f9e3e9259..5509a73401f4fe 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -6,8 +6,6 @@ THREE.ObjectLoader = function ( manager ) { this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - this.texturePath = ''; - }; THREE.ObjectLoader.prototype = { @@ -16,6 +14,12 @@ THREE.ObjectLoader.prototype = { load: function ( url, onLoad, onProgress, onError ) { + if ( this.texturePath === undefined ) { + + this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 ); + + } + var scope = this; var loader = new THREE.XHRLoader( scope.manager ); @@ -28,14 +32,9 @@ THREE.ObjectLoader.prototype = { }, - setTexturePath: function ( texturePath ) { + setTexturePath: function ( value ) { - if ( typeof texturePath === 'string' ) { - this.texturePath = texturePath; - } - else { - console.warn( 'THREE.ObjectLoader: texturePath should be a string', texturePath ); - } + this.texturePath = value; }, @@ -47,22 +46,24 @@ THREE.ObjectLoader.prototype = { parse: function ( json, onLoad ) { + var scope = this; var geometries, materials, images, textures; - var self = this; - self.manager.itemStart(json.object.uuid); - var manager = new THREE.LoadingManager( function() { + this.manager.itemStart( json.object.uuid ); + + var manager = new THREE.LoadingManager( function () { + + textures = scope.parseTextures( json.textures, images ); + + materials = scope.parseMaterials( json.materials, textures ); - textures = self.parseTextures( json.textures, images ); - materials = self.parseMaterials( json.materials, textures ); + onLoad( scope.parseObject( json.object, geometries, materials ) ); - onLoad( self.parseObject( json.object, geometries, materials ) ); // report back to parent manager - self.manager.itemEnd(json.object.uuid); + scope.manager.itemEnd( json.object.uuid ); } ); - geometries = this.parseGeometries( json.geometries ); images = this.parseImages( json.images, manager ); }, @@ -226,11 +227,13 @@ THREE.ObjectLoader.prototype = { if ( data.map ) { - if ( !textures[data.map] ) { + if ( textures[ data.map ] === undefined ) { + console.warn( 'THREE.ObjectLoader: Undefined texture', data.map ); - } - material.map = textures[data.map]; + } + + material.map = textures[ data.map ]; } @@ -246,8 +249,8 @@ THREE.ObjectLoader.prototype = { parseImages: function ( json, manager ) { + var scope = this; var images = {}; - var self = this; if ( json !== undefined ) { @@ -263,12 +266,12 @@ THREE.ObjectLoader.prototype = { for ( var i = 0, l = json.length; i < l; i ++ ) { var data = json[ i ]; - var url = self.texturePath + data.url; + var url = scope.texturePath + data.url; - self.manager.itemStart( url ); + scope.manager.itemStart( url ); loader.load( url, function ( uuid, url, image ) { - self.manager.itemEnd( url ); + scope.manager.itemEnd( url ); images[ uuid ] = image; @@ -276,8 +279,7 @@ THREE.ObjectLoader.prototype = { } - } - else { + } else { manager.onLoad(); @@ -297,28 +299,32 @@ THREE.ObjectLoader.prototype = { var data = json[ i ]; - if ( !data.image ) { + if ( data.image === undefined ) { + console.warn( 'THREE.ObjectLoader: No "image" speficied for', data.uuid ); + } - if ( !images[data.image] ) { + if ( images[ data.image ] === undefined ) { + console.warn( 'THREE.ObjectLoader: Undefined image', data.image ); + } - var texture = new THREE.Texture( images[data.image] ); + var texture = new THREE.Texture( images[ data.image ] ); texture.needsUpdate = true; texture.uuid = data.uuid; if ( data.name !== undefined ) texture.name = data.name; - if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2(data.repeat[0], data.repeat[1]); - if ( data.minFilter !== undefined ) texture.minFilter = THREE[data.minFilter]; - if ( data.magFilter !== undefined ) texture.magFilter = THREE[data.magFilter]; + if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] ); + if ( data.minFilter !== undefined ) texture.minFilter = THREE[ data.minFilter ]; + if ( data.magFilter !== undefined ) texture.magFilter = THREE[ data.magFilter ]; if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; if ( data.wrap instanceof Array ) { - texture.wrapS = THREE[data.wrap[0]]; - texture.wrapT = THREE[data.wrap[1]]; + texture.wrapS = THREE[ data.wrap[ 0 ] ]; + texture.wrapT = THREE[ data.wrap[ 1 ] ]; } From 07343214c13697589632bbdc2793a22d120773df Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Feb 2015 17:29:17 -0800 Subject: [PATCH 122/333] ObjectLoader: More code clean up. --- src/loaders/ObjectLoader.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 5509a73401f4fe..11cf8884c44b27 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -51,10 +51,10 @@ THREE.ObjectLoader.prototype = { this.manager.itemStart( json.object.uuid ); - var manager = new THREE.LoadingManager( function () { + geometries = this.parseGeometries( json.geometries ); + images = this.parseImages( json.images, function () { textures = scope.parseTextures( json.textures, images ); - materials = scope.parseMaterials( json.materials, textures ); onLoad( scope.parseObject( json.object, geometries, materials ) ); @@ -64,8 +64,6 @@ THREE.ObjectLoader.prototype = { } ); - images = this.parseImages( json.images, manager ); - }, parseGeometries: function ( json ) { @@ -247,41 +245,43 @@ THREE.ObjectLoader.prototype = { }, - parseImages: function ( json, manager ) { + parseImages: function ( json, onLoad ) { var scope = this; var images = {}; - if ( json !== undefined ) { + if ( json !== undefined && json.length > 0 ) { + + var manager = new THREE.LoadingManager( onLoad ); var loader = new THREE.ImageLoader( manager ); loader.setCrossOrigin( this.crossOrigin ); - if ( json.length === 0 ) { + var loadImage = function ( data ) { - manager.onLoad(); + var url = scope.texturePath + data.url; - } + scope.manager.itemStart( url ); - for ( var i = 0, l = json.length; i < l; i ++ ) { + loader.load( url, function ( image ) { - var data = json[ i ]; - var url = scope.texturePath + data.url; + scope.manager.itemEnd( url ); - scope.manager.itemStart( url ); - loader.load( url, function ( uuid, url, image ) { + images[ data.uuid ] = image; - scope.manager.itemEnd( url ); + } ); + + }; - images[ uuid ] = image; + for ( var i = 0, l = json.length; i < l; i ++ ) { - }.bind( null, data.uuid, url ) ); + loadImage( json[ i ] ); } } else { - manager.onLoad(); + onLoad(); } From 48bc32d60acbaa4854abde20c66d7f75fa0d2fbd Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Feb 2015 18:43:48 -0800 Subject: [PATCH 123/333] Started WebGLTextures. --- src/renderers/WebGLRenderer.js | 29 ++++---------------- src/renderers/webgl/WebGLTextures.js | 41 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 src/renderers/webgl/WebGLTextures.js diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 88c36e39edb63a..326cc07bbcc172 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -254,6 +254,8 @@ THREE.WebGLRenderer = function ( parameters ) { } + var textures = new THREE.WebGLTextures( _gl ); + // var glClearColor = function ( r, g, b, a ) { @@ -887,17 +889,6 @@ THREE.WebGLRenderer = function ( parameters ) { delete texture.image.__webglTextureCube; - } else { - - // 2D texture - - if ( texture.__webglInit === undefined ) return; - - _gl.deleteTexture( texture.__webglTexture ); - - delete texture.__webglTexture; - delete texture.__webglInit; - } }; @@ -5684,19 +5675,9 @@ THREE.WebGLRenderer = function ( parameters ) { this.uploadTexture = function ( texture ) { - if ( texture.__webglInit === undefined ) { - - texture.__webglInit = true; - - texture.addEventListener( 'dispose', onTextureDispose ); - - texture.__webglTexture = _gl.createTexture(); - - _this.info.memory.textures ++; - - } + var webglTexture = textures.get( texture ); - _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture ); + _gl.bindTexture( _gl.TEXTURE_2D, webglTexture ); _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); @@ -5805,7 +5786,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture ); + _gl.bindTexture( _gl.TEXTURE_2D, textures.get( texture ) ); } diff --git a/src/renderers/webgl/WebGLTextures.js b/src/renderers/webgl/WebGLTextures.js new file mode 100644 index 00000000000000..36527cc9d0d069 --- /dev/null +++ b/src/renderers/webgl/WebGLTextures.js @@ -0,0 +1,41 @@ +/** +* @author mrdoob / http://mrdoob.com/ +*/ + +THREE.WebGLTextures = function ( gl ) { + + var textures = {}; + + this.get = function ( texture ) { + + if ( textures[ texture.id ] !== undefined ) { + + return textures[ texture.id ]; + + } + + return this.create( texture ); + + }; + + this.create = function ( texture ) { + + texture.addEventListener( 'dispose', this.delete ); + + textures[ texture.id ] = gl.createTexture(); + + return textures[ texture.id ]; + + }; + + this.delete = function ( texture ) { + + texture.removeEventListener( 'dispose', this.delete ); + + gl.deleteTexture( textures[ texture.id ] ); + + delete textures[ texture.id ]; + + }; + +}; From e98bd232478e17db9dcb929ec5ea05ee721b994f Mon Sep 17 00:00:00 2001 From: "Luis E. Fraguada" Date: Fri, 13 Feb 2015 11:52:31 +0100 Subject: [PATCH 124/333] Added support for loading PointCloud Objects Just added some basic code for parsing PointCloud objects. Tested this with a JSON Scene format 4.3 and works fine. --- src/loaders/ObjectLoader.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 11cf8884c44b27..68cab42f3ad876 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -437,6 +437,27 @@ THREE.ObjectLoader.prototype = { object = new THREE.Line( geometry, material ); break; + + case 'PointCloud': + + var geometry = geometries[ data.geometry ]; + var material = materials[ data.material ]; + + if ( geometry === undefined ) { + + console.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); + + } + + if ( material === undefined ) { + + console.warn( 'THREE.ObjectLoader: Undefined material', data.material ); + + } + + object = new THREE.PointCloud( geometry, material ); + + break; case 'Sprite': From 82d271c43e82b698650e61f27cd0faf03003caa1 Mon Sep 17 00:00:00 2001 From: alexan0308 Date: Fri, 13 Feb 2015 22:15:20 +0600 Subject: [PATCH 125/333] cdcdcdcdcdcdc --- docs/api/extras/geometries/CylinderGeometry.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/extras/geometries/CylinderGeometry.html b/docs/api/extras/geometries/CylinderGeometry.html index 992859f42651e3..3d97663f722a73 100644 --- a/docs/api/extras/geometries/CylinderGeometry.html +++ b/docs/api/extras/geometries/CylinderGeometry.html @@ -8,7 +8,7 @@ [page:Geometry] → - +

[name]

A class for generating cylinder geometries
From 0323a2c89ce91471495c1520bc125ff5f8a452ea Mon Sep 17 00:00:00 2001 From: alexan0308 Date: Fri, 13 Feb 2015 22:31:48 +0600 Subject: [PATCH 126/333] CylinderGeometry_docs_add_thetaStart_thetaLength --- docs/api/extras/geometries/CylinderGeometry.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/api/extras/geometries/CylinderGeometry.html b/docs/api/extras/geometries/CylinderGeometry.html index 3d97663f722a73..e17b611ac9c7c8 100644 --- a/docs/api/extras/geometries/CylinderGeometry.html +++ b/docs/api/extras/geometries/CylinderGeometry.html @@ -26,14 +26,16 @@

Example

Constructor

-

[name]([page:Float radiusTop], [page:Float radiusBottom], [page:Float height], [page:Integer radiusSegments], [page:Integer heightSegments], [page:Boolean openEnded])

+

[name]([page:Float radiusTop], [page:Float radiusBottom], [page:Float height], [page:Integer radiusSegments], [page:Integer heightSegments], [page:Boolean openEnded], [page:Float thetaStart], [page:Float thetaLength])

radiusTop — Radius of the cylinder at the top. Default is 20.
radiusBottom — Radius of the cylinder at the bottom. Default is 20.
height — Height of the cylinder. Default is 100.
radiusSegments — Number of segmented faces around the circumference of the cylinder. Default is 8
heightSegments — Number of rows of faces along the height of the cylinder. Default is 1.
- openEnded — A Boolean indicating whether the ends of the cylinder are open or capped. Default is false, meaning capped. + openEnded — A Boolean indicating whether the ends of the cylinder are open or capped. Default is false, meaning capped.
+ thetaStart — Start angle for first segment, default = 0 (three o'clock position).
+ thetaLength — The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete cylinder.
From 76bd6d1379ced22e99cced2f5b2edfd8ba760363 Mon Sep 17 00:00:00 2001 From: erichlof Date: Fri, 13 Feb 2015 11:18:04 -0600 Subject: [PATCH 127/333] Create ShadowMesh.js --- src/objects/ShadowMesh.js | 73 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/objects/ShadowMesh.js diff --git a/src/objects/ShadowMesh.js b/src/objects/ShadowMesh.js new file mode 100644 index 00000000000000..ed04590b69e42b --- /dev/null +++ b/src/objects/ShadowMesh.js @@ -0,0 +1,73 @@ +// File:src/objects/ShadowMesh.js + +/** + * @author erichlof / http://github.com/erichlof + */ + +// a shadow Mesh that follows its parent Mesh in the scene, but is confined to a single plane. + +THREE.ShadowMesh = function ( parentMesh ) { + + var shadowMaterial = new THREE.MeshBasicMaterial( { + + color: 0x000000, + transparent: true, + opacity: 0.6, + depthWrite: false + + } ); + + THREE.Mesh.call( this, parentMesh.geometry, shadowMaterial ); + + this.parentMeshMatrix = parentMesh.matrix; + + this.frustumCulled = false; + +}; + +THREE.ShadowMesh.prototype = Object.create( THREE.Mesh.prototype ); +THREE.ShadowMesh.prototype.constructor = THREE.ShadowMesh; + +THREE.ShadowMesh.prototype.update = function () { + + // based on https://www.opengl.org/archives/resources/features/StencilTalk/tsld021.htm + var shadowMatrix = new THREE.Matrix4(); + + return function ( plane, lightPosition4D ) { + + var dot = plane.normal.x * lightPosition4D.x + + plane.normal.y * lightPosition4D.y + + plane.normal.z * lightPosition4D.z + + -plane.constant * lightPosition4D.w; + + var sme = shadowMatrix.elements; + + sme[ 0 ] = dot - lightPosition4D.x * plane.normal.x; + sme[ 4 ] = - lightPosition4D.x * plane.normal.y; + sme[ 8 ] = - lightPosition4D.x * plane.normal.z; + sme[ 12 ] = - lightPosition4D.x * -plane.constant; + + sme[ 1 ] = - lightPosition4D.y * plane.normal.x; + sme[ 5 ] = dot - lightPosition4D.y * plane.normal.y; + sme[ 9 ] = - lightPosition4D.y * plane.normal.z; + sme[ 13 ] = - lightPosition4D.y * -plane.constant; + + sme[ 2 ] = - lightPosition4D.z * plane.normal.x; + sme[ 6 ] = - lightPosition4D.z * plane.normal.y; + sme[ 10 ] = dot - lightPosition4D.z * plane.normal.z; + sme[ 14 ] = - lightPosition4D.z * -plane.constant; + + sme[ 3 ] = - lightPosition4D.w * plane.normal.x; + sme[ 7 ] = - lightPosition4D.w * plane.normal.y; + sme[ 11 ] = - lightPosition4D.w * plane.normal.z; + sme[ 15 ] = dot - lightPosition4D.w * -plane.constant; + + this.matrix.identity(); + this.matrix.multiply( shadowMatrix ); + this.matrix.multiply( this.parentMeshMatrix ); + + this.matrixAutoUpdate = false; + + }; + +}(); From f8474ae4442bfcc46d79939905f54f69d225a46b Mon Sep 17 00:00:00 2001 From: erichlof Date: Fri, 13 Feb 2015 16:05:28 -0600 Subject: [PATCH 128/333] Update ShadowMesh.js --- src/objects/ShadowMesh.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/objects/ShadowMesh.js b/src/objects/ShadowMesh.js index ed04590b69e42b..80b888c210f4a1 100644 --- a/src/objects/ShadowMesh.js +++ b/src/objects/ShadowMesh.js @@ -6,7 +6,7 @@ // a shadow Mesh that follows its parent Mesh in the scene, but is confined to a single plane. -THREE.ShadowMesh = function ( parentMesh ) { +THREE.ShadowMesh = function ( mesh ) { var shadowMaterial = new THREE.MeshBasicMaterial( { @@ -17,9 +17,9 @@ THREE.ShadowMesh = function ( parentMesh ) { } ); - THREE.Mesh.call( this, parentMesh.geometry, shadowMaterial ); + THREE.Mesh.call( this, mesh.geometry, shadowMaterial ); - this.parentMeshMatrix = parentMesh.matrix; + this.parentMeshMatrix = mesh.matrix; this.frustumCulled = false; @@ -62,9 +62,7 @@ THREE.ShadowMesh.prototype.update = function () { sme[ 11 ] = - lightPosition4D.w * plane.normal.z; sme[ 15 ] = dot - lightPosition4D.w * -plane.constant; - this.matrix.identity(); - this.matrix.multiply( shadowMatrix ); - this.matrix.multiply( this.parentMeshMatrix ); + this.matrix.multiplyMatrices( shadowMatrix, this.parentMeshMatrix ); this.matrixAutoUpdate = false; From c2ebad446edeafaddc14ffc67533e8de4e422ed5 Mon Sep 17 00:00:00 2001 From: alexan0308 Date: Sun, 15 Feb 2015 13:43:22 +0600 Subject: [PATCH 129/333] webgl_interactive_lines_visible_sphere --- examples/webgl_interactive_lines.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/webgl_interactive_lines.html b/examples/webgl_interactive_lines.html index d7e5b7b8cb6b9b..c28f6b2bcedbc7 100644 --- a/examples/webgl_interactive_lines.html +++ b/examples/webgl_interactive_lines.html @@ -52,9 +52,9 @@ var geometry = new THREE.SphereGeometry( 5 ); var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); - //sphereInter = new THREE.Mesh( geometry, material ); - //sphereInter.visible = false; - //scene.add( sphereInter ); + sphereInter = new THREE.Mesh( geometry, material ); + sphereInter.visible = false; + scene.add( sphereInter ); var geometry = new THREE.Geometry(); @@ -111,7 +111,7 @@ scene.add( parentTransform ); raycaster = new THREE.Raycaster(); - raycaster.linePrecision = 1; + raycaster.linePrecision = 3; renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setClearColor( 0xf0f0f0 ); @@ -189,8 +189,8 @@ currentIntersected = intersects[ 0 ].object; currentIntersected.material.linewidth = 5; - //sphereInter.visible = true; - //sphereInter.position.copy( intersects[ 0 ].point ); + sphereInter.visible = true; + sphereInter.position.copy( intersects[ 0 ].point ); } else { @@ -202,7 +202,7 @@ currentIntersected = undefined; - //sphereInter.visible = false; + sphereInter.visible = false; } From 889f42c8245f132b751d5158a14b8ccedf9d55bb Mon Sep 17 00:00:00 2001 From: repsac Date: Sun, 15 Feb 2015 01:04:53 -0800 Subject: [PATCH 130/333] Added simple popups for error/info/warning dialogs When performing a geometry export of an incorrectly selected node an error dialog will now open instead of the traceback window Added the dialogs module Addon version now prints to the log for debugging --- .../blender/addons/io_three/__init__.py | 3 +- .../blender/addons/io_three/dialogs.py | 112 ++++++++++++++++++ .../addons/io_three/exporter/__init__.py | 23 +++- .../addons/io_three/exporter/api/__init__.py | 10 ++ 4 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 utils/exporters/blender/addons/io_three/dialogs.py diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 0b56adf6534716..2c6da580f331e8 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -41,7 +41,7 @@ bl_info = { 'name': "Three.js Format", 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", - 'version': (1, 2, 2), + 'version': (1, 2, 3), 'blender': (2, 7, 3), 'location': "File > Export", 'description': "Export Three.js formatted JSON files.", @@ -693,6 +693,7 @@ def execute(self, context): raise Exception("filename not set") settings = save_settings_export(self.properties) + settings['addon_version'] = bl_info['version'] filepath = self.filepath if settings[constants.COMPRESSION] == constants.MSGPACK: diff --git a/utils/exporters/blender/addons/io_three/dialogs.py b/utils/exporters/blender/addons/io_three/dialogs.py new file mode 100644 index 00000000000000..01baf18eeb2f29 --- /dev/null +++ b/utils/exporters/blender/addons/io_three/dialogs.py @@ -0,0 +1,112 @@ +from bpy import context + +CONTEXT = { + 0: { + 'title': "Error Message", + 'icon': 'CANCEL' + }, + 1: { + 'title': "Warning Message", + 'icon': 'ERROR' # I prefer this icon for warnings + }, + 2: { + 'title': "Message", + 'icon': 'NONE' + }, + 3: { + 'title': "Question", + 'icon': 'QUESTION' + } +} + + +def error(message, title="", wrap=40): + """Creates an error dialog. + + :param message: text of the message body + :param title: text to append to the title + (Default value = "") + :param wrap: line width (Default value = 40) + + """ + _draw(message, title, wrap, 0) + + +def warning(message, title="", wrap=40): + """Creates an error dialog. + + :param message: text of the message body + :param title: text to append to the title + (Default value = "") + :param wrap: line width (Default value = 40) + + """ + _draw(message, title, wrap, 1) + + + +def info(message, title="", wrap=40): + """Creates an error dialog. + + :param message: text of the message body + :param title: text to append to the title + (Default value = "") + :param wrap: line width (Default value = 40) + + """ + _draw(message, title, wrap, 2) + + + +def question(message, title="", wrap=40): + """Creates an error dialog. + + :param message: text of the message body + :param title: text to append to the title + (Default value = "") + :param wrap: line width (Default value = 40) + + """ + _draw(message, title, wrap, 3) + + + +# Great idea borrowed from +# http://community.cgcookie.com/t/code-snippet-easy-error-messages/203 +def _draw(message, title, wrap, key): + """ + + :type message: str + :type title: str + :type wrap: int + :type key: int + + """ + lines = [] + if wrap > 0: + while len(message) > wrap: + i = message.rfind(' ', 0, wrap) + if i == -1: + lines += [message[:wrap]] + message = message[wrap:] + else: + lines += [message[:i]] + message = message[i+1:] + if message: + lines += [message] + + def draw(self, *args): + """ + + :param self: + :param *args: + + """ + for line in lines: + self.layout.label(line) + + title = "%s: %s" % (title, CONTEXT[key]['title']) + icon = CONTEXT[key]['icon'] + + context.window_manager.popup_menu( + draw, title=title.strip(), icon=icon) diff --git a/utils/exporters/blender/addons/io_three/exporter/__init__.py b/utils/exporters/blender/addons/io_three/exporter/__init__.py index 4acb0d7c1ae474..2f0cba4d9bf879 100644 --- a/utils/exporters/blender/addons/io_three/exporter/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/__init__.py @@ -1,7 +1,7 @@ import os import sys import traceback -from .. import constants, logger, exceptions +from .. import constants, logger, exceptions, dialogs from . import scene, geometry, api, base_classes @@ -9,7 +9,10 @@ def _error_handler(func): def inner(filepath, options, *args, **kwargs): level = options.get(constants.LOGGING, constants.DEBUG) + version = options.get('addon_version') logger.init('io_three.export.log', level=level) + if version is not None: + logger.debug("Addon Version %s", version) api.init() try: @@ -55,16 +58,26 @@ def export_scene(filepath, options): @_error_handler def export_geometry(filepath, options, node=None): + msg = "" + exception = None if node is None: node = api.active_object() if node is None: - msg = 'Nothing selected' + msg = "Nothing selected" logger.error(msg) - raise exceptions.SelectionError(msg) + exception = exceptions.SelectionError if node.type != 'MESH': - msg = 'Not a valid mesh object' - raise exceptions.GeometryError(msg) + msg = "%s is not a valid mesh object" % node.name + logger.error(msg) + exception = exceptions.GeometryError + if exception is not None: + if api.batch_mode(): + raise exception(msg) + else: + dialogs.error(msg) + return + mesh = api.object.mesh(node, options) parent = base_classes.BaseScene(filepath, options) geo = geometry.Geometry(mesh, parent) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py index fa120d47252632..a273c9d482eedc 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py @@ -13,6 +13,16 @@ def active_object(): return bpy.context.scene.objects.active +def batch_mode(): + """ + + :return: Whether or not the session is interactive + :rtype: bool + + """ + return bpy.context.area is None + + def init(): """Initializing the api module. Required first step before initializing the actual export process. From e5ae7d153be11a97618259bbb787290bea94e590 Mon Sep 17 00:00:00 2001 From: "Luis E. Fraguada" Date: Sun, 15 Feb 2015 14:14:27 +0100 Subject: [PATCH 131/333] Update ObjectLoader.js to load different maps Simple extension to the PR submitted by @denzp https://github.com/mrdoob/three.js/pull/5502 to allow for other map types. Tested here with map, bumpMap, and alphaMap: http://datable.net/WebGL/Test299/ --- src/loaders/ObjectLoader.js | 74 ++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 68cab42f3ad876..75e3fcc9399b88 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -229,11 +229,83 @@ THREE.ObjectLoader.prototype = { console.warn( 'THREE.ObjectLoader: Undefined texture', data.map ); - } + } material.map = textures[ data.map ]; } + + if ( data.bumpMap ) { + + if ( !textures[data.bumpMap] ) { + + console.warn( 'THREE.ObjectLoader: Undefined texture', data.bumpMap ); + + } + + material.bumpMap = textures[data.bumpMap]; + + } + + if ( data.alphaMap ) { + + if ( !textures[data.alphaMap] ) { + + console.warn( 'THREE.ObjectLoader: Undefined texture', data.alphaMap ); + + } + + material.alphaMap = textures[data.alphaMap]; + + } + + if ( data.envMap ) { + + if ( !textures[data.envMap] ) { + + console.warn( 'THREE.ObjectLoader: Undefined texture', data.envMap ); + + } + + material.envMap = textures[data.envMap]; + + } + + if ( data.normalMap ) { + + if ( !textures[data.normalMap] ) { + + console.warn( 'THREE.ObjectLoader: Undefined texture', data.normalMap ); + + } + + material.normalMap = textures[data.normalMap]; + + } + + if ( data.lightMap ) { + + if ( !textures[data.lightMap] ) { + + console.warn( 'THREE.ObjectLoader: Undefined texture', data.lightMap ); + + } + + material.lightMap = textures[data.lightMap]; + + } + + if ( data.specularMap ) { + + if ( !textures[data.specularMap] ) { + + console.warn( 'THREE.ObjectLoader: Undefined texture', data.specularMap ); + + } + + material.specularMap = textures[data.specularMap]; + + } materials[ data.uuid ] = material; From 3ee2e831afd955e06a4e3d59acbf5b47475519ad Mon Sep 17 00:00:00 2001 From: erichlof Date: Mon, 16 Feb 2015 13:28:03 -0600 Subject: [PATCH 132/333] Update ShadowMesh.js --- src/objects/ShadowMesh.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects/ShadowMesh.js b/src/objects/ShadowMesh.js index 80b888c210f4a1..c5b217c7c9977c 100644 --- a/src/objects/ShadowMesh.js +++ b/src/objects/ShadowMesh.js @@ -19,7 +19,7 @@ THREE.ShadowMesh = function ( mesh ) { THREE.Mesh.call( this, mesh.geometry, shadowMaterial ); - this.parentMeshMatrix = mesh.matrix; + this.parentMeshMatrix = mesh.matrixWorld; this.frustumCulled = false; From 766a64b2e26ae821c8cbbbc30bf10e1e50209df2 Mon Sep 17 00:00:00 2001 From: erichlof Date: Tue, 17 Feb 2015 00:15:20 -0600 Subject: [PATCH 133/333] Update ShadowMesh.js --- src/objects/ShadowMesh.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objects/ShadowMesh.js b/src/objects/ShadowMesh.js index c5b217c7c9977c..f71b392a223488 100644 --- a/src/objects/ShadowMesh.js +++ b/src/objects/ShadowMesh.js @@ -22,6 +22,8 @@ THREE.ShadowMesh = function ( mesh ) { this.parentMeshMatrix = mesh.matrixWorld; this.frustumCulled = false; + + this.matrixAutoUpdate = false; }; @@ -61,10 +63,8 @@ THREE.ShadowMesh.prototype.update = function () { sme[ 7 ] = - lightPosition4D.w * plane.normal.y; sme[ 11 ] = - lightPosition4D.w * plane.normal.z; sme[ 15 ] = dot - lightPosition4D.w * -plane.constant; - - this.matrix.multiplyMatrices( shadowMatrix, this.parentMeshMatrix ); - this.matrixAutoUpdate = false; + this.matrix.multiplyMatrices( shadowMatrix, this.parentMeshMatrix ); }; From 5a5c9ae09a282c8bf34781fa3e527050e7e20094 Mon Sep 17 00:00:00 2001 From: Pavel Vasev Date: Tue, 17 Feb 2015 17:23:16 +0500 Subject: [PATCH 134/333] Export PointCloud in Object3D :: toJSON --- src/core/Object3D.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 4700d1d025c080..2daab175417fca 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -693,7 +693,7 @@ THREE.Object3D.prototype = { data.color = object.color.getHex(); data.groundColor = object.groundColor.getHex(); - } else if ( object instanceof THREE.Mesh ) { + } else if ( object instanceof THREE.Mesh || object instanceof THREE.PointCloud ) { data.geometry = parseGeometry( object.geometry ); data.material = parseMaterial( object.material ); From 56c7c276fec8e0763062fb45438a35be3bf3e82e Mon Sep 17 00:00:00 2001 From: Pavel Vasev Date: Tue, 17 Feb 2015 17:25:07 +0500 Subject: [PATCH 135/333] Export PointCloudMaterial --- src/materials/Material.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/materials/Material.js b/src/materials/Material.js index c1c84dd288ff95..ee7fa97a088646 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -155,6 +155,15 @@ THREE.Material.prototype = { if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; if ( this.side !== THREE.FrontSide ) output.side = this.side; + } else if ( this instanceof THREE.PointCloudMaterial ) { + + output.size = this.size; + output.sizeAttenuation = this.sizeAttenuation; + output.color = this.color.getHex(); + + if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; + if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; + } else if ( this instanceof THREE.ShaderMaterial ) { output.uniforms = this.uniforms; From f946b1f6e4c9dfabecd561c310915915d83c12de Mon Sep 17 00:00:00 2001 From: Pavel Vasev Date: Tue, 17 Feb 2015 17:26:09 +0500 Subject: [PATCH 136/333] Import PointCloudMaterial features --- src/loaders/MaterialLoader.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/loaders/MaterialLoader.js b/src/loaders/MaterialLoader.js index dadd082c0935f7..a8e7f86aebf103 100644 --- a/src/loaders/MaterialLoader.js +++ b/src/loaders/MaterialLoader.js @@ -51,6 +51,10 @@ THREE.MaterialLoader.prototype = { if ( json.transparent !== undefined ) material.transparent = json.transparent; if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; + // for PointCloudMaterial + if ( json.size !== undefined ) material.size = json.size; + if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation; + if ( json.materials !== undefined ) { for ( var i = 0, l = json.materials.length; i < l; i ++ ) { From fcf54cd2ed3b9097126c3f6b4fc5764a07f5195e Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 17 Feb 2015 13:20:07 -0800 Subject: [PATCH 137/333] ObjectLoader: Fixed editor breakage. Fixes #6091. --- src/loaders/ObjectLoader.js | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 11cf8884c44b27..f8ad3628cf5515 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -46,23 +46,13 @@ THREE.ObjectLoader.prototype = { parse: function ( json, onLoad ) { - var scope = this; - var geometries, materials, images, textures; - - this.manager.itemStart( json.object.uuid ); - - geometries = this.parseGeometries( json.geometries ); - images = this.parseImages( json.images, function () { - - textures = scope.parseTextures( json.textures, images ); - materials = scope.parseMaterials( json.materials, textures ); - - onLoad( scope.parseObject( json.object, geometries, materials ) ); + var geometries = this.parseGeometries( json.geometries ); - // report back to parent manager - scope.manager.itemEnd( json.object.uuid ); + var images = this.parseImages( json.images, onLoad ); + var textures = this.parseTextures( json.textures, images ); + var materials = this.parseMaterials( json.materials, textures ); - } ); + return this.parseObject( json.object, geometries, materials ); }, @@ -281,7 +271,7 @@ THREE.ObjectLoader.prototype = { } else { - onLoad(); + if ( onLoad !== undefined ) onLoad(); } From 57dbbab577ecf33f8a924af6343201799e5847c6 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 17 Feb 2015 13:31:54 -0800 Subject: [PATCH 138/333] Simplified ObjectLoader. --- src/loaders/ObjectLoader.js | 205 +++++++++++++----------------------- 1 file changed, 73 insertions(+), 132 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 2cb1c432d47e6e..df9eaf8ca53de4 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -202,6 +202,18 @@ THREE.ObjectLoader.prototype = { if ( json !== undefined ) { + var getTexture = function ( name ) { + + if ( textures[ name ] === undefined ) { + + THREE.warn( 'THREE.ObjectLoader: Undefined texture', name ); + + } + + return textures[ name ]; + + }; + var loader = new THREE.MaterialLoader(); for ( var i = 0, l = json.length; i < l; i ++ ) { @@ -213,88 +225,46 @@ THREE.ObjectLoader.prototype = { if ( data.name !== undefined ) material.name = data.name; - if ( data.map ) { + if ( data.map !== undefined ) { - if ( textures[ data.map ] === undefined ) { + material.map = getTexture( data.map ); - console.warn( 'THREE.ObjectLoader: Undefined texture', data.map ); + } - } + if ( data.bumpMap !== undefined ) { - material.map = textures[ data.map ]; + material.bumpMap = getTexture( data.bumpMap ); } - - if ( data.bumpMap ) { - - if ( !textures[data.bumpMap] ) { - - console.warn( 'THREE.ObjectLoader: Undefined texture', data.bumpMap ); - - } - - material.bumpMap = textures[data.bumpMap]; - - } - - if ( data.alphaMap ) { - - if ( !textures[data.alphaMap] ) { - - console.warn( 'THREE.ObjectLoader: Undefined texture', data.alphaMap ); - - } - - material.alphaMap = textures[data.alphaMap]; - + + if ( data.alphaMap !== undefined ) { + + material.alphaMap = getTexture( data.alphaMap ); + } - - if ( data.envMap ) { - - if ( !textures[data.envMap] ) { - - console.warn( 'THREE.ObjectLoader: Undefined texture', data.envMap ); - - } - - material.envMap = textures[data.envMap]; - + + if ( data.envMap !== undefined ) { + + material.envMap = getTexture( data.envMap ); + } - - if ( data.normalMap ) { - - if ( !textures[data.normalMap] ) { - - console.warn( 'THREE.ObjectLoader: Undefined texture', data.normalMap ); - - } - - material.normalMap = textures[data.normalMap]; - + + if ( data.normalMap !== undefined ) { + + material.normalMap = getTexture( data.normalMap ); + } - - if ( data.lightMap ) { - - if ( !textures[data.lightMap] ) { - - console.warn( 'THREE.ObjectLoader: Undefined texture', data.lightMap ); - - } - - material.lightMap = textures[data.lightMap]; - + + if ( data.lightMap !== undefined ) { + + material.lightMap = getTexture( data.lightMap ); + } - - if ( data.specularMap ) { - - if ( !textures[data.specularMap] ) { - - console.warn( 'THREE.ObjectLoader: Undefined texture', data.specularMap ); - - } - - material.specularMap = textures[data.specularMap]; - + + if ( data.specularMap !== undefined ) { + + material.specularMap = getTexture( data.specularMap ); + } materials[ data.uuid ] = material; @@ -363,13 +333,13 @@ THREE.ObjectLoader.prototype = { if ( data.image === undefined ) { - console.warn( 'THREE.ObjectLoader: No "image" speficied for', data.uuid ); + THREE.warn( 'THREE.ObjectLoader: No "image" speficied for', data.uuid ); } if ( images[ data.image ] === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined image', data.image ); + THREE.warn( 'THREE.ObjectLoader: Undefined image', data.image ); } @@ -408,6 +378,30 @@ THREE.ObjectLoader.prototype = { var object; + var getGeometry = function ( name ) { + + if ( geometries[ name ] === undefined ) { + + THREE.warn( 'THREE.ObjectLoader: Undefined geometry', name ); + + } + + return geometries[ name ]; + + }; + + var getMaterial = function ( name ) { + + if ( materials[ name ] === undefined ) { + + THREE.warn( 'THREE.ObjectLoader: Undefined material', name ); + + } + + return materials[ name ]; + + }; + switch ( data.type ) { case 'Scene': @@ -460,78 +454,25 @@ THREE.ObjectLoader.prototype = { case 'Mesh': - var geometry = geometries[ data.geometry ]; - var material = materials[ data.material ]; - - if ( geometry === undefined ) { - - THREE.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); - - } - - if ( material === undefined ) { - - THREE.warn( 'THREE.ObjectLoader: Undefined material', data.material ); - - } - - object = new THREE.Mesh( geometry, material ); + object = new THREE.Mesh( getGeometry( data.geometry ), getMaterial( data.material ) ); break; case 'Line': - var geometry = geometries[ data.geometry ]; - var material = materials[ data.material ]; - - if ( geometry === undefined ) { - - THREE.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); - - } - - if ( material === undefined ) { - - THREE.warn( 'THREE.ObjectLoader: Undefined material', data.material ); - - } - - object = new THREE.Line( geometry, material ); + object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ) ); break; - - case 'PointCloud': - - var geometry = geometries[ data.geometry ]; - var material = materials[ data.material ]; - - if ( geometry === undefined ) { - - console.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); - } - - if ( material === undefined ) { - - console.warn( 'THREE.ObjectLoader: Undefined material', data.material ); - - } + case 'PointCloud': - object = new THREE.PointCloud( geometry, material ); + object = new THREE.PointCloud( getGeometry( data.geometry ), getMaterial( data.material ) ); break; case 'Sprite': - var material = materials[ data.material ]; - - if ( material === undefined ) { - - THREE.warn( 'THREE.ObjectLoader: Undefined material', data.material ); - - } - - object = new THREE.Sprite( material ); + object = new THREE.Sprite( getMaterial( data.material ) ); break; From 48f1ea25a085f96fb4821323420f5a349460064b Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 17 Feb 2015 14:24:13 -0800 Subject: [PATCH 139/333] WebGLRenderer: Reverted WebGLTextures by now... --- src/extras/helpers/EdgesHelper.js | 1 + src/renderers/WebGLRenderer.js | 29 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/extras/helpers/EdgesHelper.js b/src/extras/helpers/EdgesHelper.js index 252fc7e09ef1cf..ad1ce2451f6162 100644 --- a/src/extras/helpers/EdgesHelper.js +++ b/src/extras/helpers/EdgesHelper.js @@ -13,6 +13,7 @@ THREE.EdgesHelper = function ( object, hex ) { var geometry = new THREE.BufferGeometry(); var geometry2; + if ( object.geometry instanceof THREE.BufferGeometry ) { geometry2 = new THREE.Geometry(); diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 326cc07bbcc172..88c36e39edb63a 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -254,8 +254,6 @@ THREE.WebGLRenderer = function ( parameters ) { } - var textures = new THREE.WebGLTextures( _gl ); - // var glClearColor = function ( r, g, b, a ) { @@ -889,6 +887,17 @@ THREE.WebGLRenderer = function ( parameters ) { delete texture.image.__webglTextureCube; + } else { + + // 2D texture + + if ( texture.__webglInit === undefined ) return; + + _gl.deleteTexture( texture.__webglTexture ); + + delete texture.__webglTexture; + delete texture.__webglInit; + } }; @@ -5675,9 +5684,19 @@ THREE.WebGLRenderer = function ( parameters ) { this.uploadTexture = function ( texture ) { - var webglTexture = textures.get( texture ); + if ( texture.__webglInit === undefined ) { + + texture.__webglInit = true; + + texture.addEventListener( 'dispose', onTextureDispose ); + + texture.__webglTexture = _gl.createTexture(); + + _this.info.memory.textures ++; + + } - _gl.bindTexture( _gl.TEXTURE_2D, webglTexture ); + _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture ); _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); @@ -5786,7 +5805,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - _gl.bindTexture( _gl.TEXTURE_2D, textures.get( texture ) ); + _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture ); } From eb167c9fe408eb90848fa3ad774e9ce8c0c56ee0 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 17 Feb 2015 14:29:41 -0800 Subject: [PATCH 140/333] Updated builds. --- build/three.js | 538 ++++++++++++++++++++++++++++--------------- build/three.min.js | 428 +++++++++++++++++----------------- src/core/Object3D.js | 7 +- 3 files changed, 575 insertions(+), 398 deletions(-) diff --git a/build/three.js b/build/three.js index f26837c546e8dc..fe2ad654260985 100644 --- a/build/three.js +++ b/build/three.js @@ -26,6 +26,13 @@ if ( Math.sign === undefined ) { } + +// set the default log handlers +THREE.log = function() { console.log.apply( console, arguments ); } +THREE.warn = function() { console.warn.apply( console, arguments ); } +THREE.error = function() { console.error.apply( console, arguments ); } + + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button THREE.MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; @@ -190,25 +197,25 @@ THREE.RGBA_PVRTC_2BPPV1_Format = 2103; THREE.Projector = function () { - console.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' ); + THREE.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' ); this.projectVector = function ( vector, camera ) { - console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); + THREE.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); vector.project( camera ); }; this.unprojectVector = function ( vector, camera ) { - console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); + THREE.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); vector.unproject( camera ); }; this.pickingRay = function ( vector, camera ) { - console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' ); + THREE.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' ); }; @@ -216,7 +223,7 @@ THREE.Projector = function () { THREE.CanvasRenderer = function () { - console.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' ); + THREE.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' ); this.domElement = document.createElement( 'canvas' ); this.clear = function () {}; @@ -1014,7 +1021,7 @@ THREE.Quaternion.prototype = { if ( p !== undefined ) { - console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); + THREE.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); return this.multiplyQuaternions( q, p ); } @@ -1043,7 +1050,7 @@ THREE.Quaternion.prototype = { multiplyVector3: function ( vector ) { - console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); + THREE.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); return vector.applyQuaternion( this ); }, @@ -1254,7 +1261,7 @@ THREE.Vector2.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -1288,7 +1295,7 @@ THREE.Vector2.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } @@ -1700,7 +1707,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -1737,7 +1744,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } @@ -1764,7 +1771,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); return this.multiplyVectors( v, w ); } @@ -1805,7 +1812,7 @@ THREE.Vector3.prototype = { if ( euler instanceof THREE.Euler === false ) { - console.error( 'THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.' ); + THREE.error( 'THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.' ); } @@ -2216,7 +2223,7 @@ THREE.Vector3.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); return this.crossVectors( v, w ); } @@ -2323,19 +2330,19 @@ THREE.Vector3.prototype = { setEulerFromRotationMatrix: function ( m, order ) { - console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); + THREE.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); }, setEulerFromQuaternion: function ( q, order ) { - console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); + THREE.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); }, getPositionFromMatrix: function ( m ) { - console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); + THREE.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); return this.setFromMatrixPosition( m ); @@ -2343,14 +2350,14 @@ THREE.Vector3.prototype = { getScaleFromMatrix: function ( m ) { - console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); + THREE.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); return this.setFromMatrixScale( m ); }, getColumnFromMatrix: function ( index, matrix ) { - console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); + THREE.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); return this.setFromMatrixColumn( index, matrix ); @@ -2380,7 +2387,7 @@ THREE.Vector3.prototype = { }, setFromMatrixColumn: function ( index, matrix ) { - + var offset = index * 4; var me = matrix.elements; @@ -2555,7 +2562,7 @@ THREE.Vector4.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -2595,7 +2602,7 @@ THREE.Vector4.prototype = { if ( w !== undefined ) { - console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + THREE.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } @@ -3345,7 +3352,7 @@ THREE.Euler.prototype = { } else { - console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ) + THREE.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ) } @@ -4200,7 +4207,7 @@ THREE.Matrix3 = function () { if ( arguments.length > 0 ) { - console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); + THREE.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); } @@ -4254,14 +4261,14 @@ THREE.Matrix3.prototype = { multiplyVector3: function ( vector ) { - console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); return vector.applyMatrix3( this ); }, multiplyVector3Array: function ( a ) { - console.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); + THREE.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); return this.applyToVector3Array( a ); }, @@ -4351,7 +4358,7 @@ THREE.Matrix3.prototype = { } else { - console.warn( msg ); + THREE.warn( msg ); } @@ -4483,7 +4490,7 @@ THREE.Matrix4 = function () { if ( arguments.length > 0 ) { - console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); + THREE.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); } @@ -4531,7 +4538,7 @@ THREE.Matrix4.prototype = { extractPosition: function ( m ) { - console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); + THREE.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); return this.copyPosition( m ); }, @@ -4609,7 +4616,7 @@ THREE.Matrix4.prototype = { if ( euler instanceof THREE.Euler === false ) { - console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); + THREE.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); } @@ -4735,7 +4742,7 @@ THREE.Matrix4.prototype = { setRotationFromQuaternion: function ( q ) { - console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); + THREE.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); return this.makeRotationFromQuaternion( q ); @@ -4822,7 +4829,7 @@ THREE.Matrix4.prototype = { if ( n !== undefined ) { - console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); + THREE.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); return this.multiplyMatrices( m, n ); } @@ -4901,21 +4908,21 @@ THREE.Matrix4.prototype = { multiplyVector3: function ( vector ) { - console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); return vector.applyProjection( this ); }, multiplyVector4: function ( vector ) { - console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); return vector.applyMatrix4( this ); }, multiplyVector3Array: function ( a ) { - console.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); + THREE.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); return this.applyToVector3Array( a ); }, @@ -4951,7 +4958,7 @@ THREE.Matrix4.prototype = { rotateAxis: function ( v ) { - console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); v.transformDirection( this ); @@ -4959,7 +4966,7 @@ THREE.Matrix4.prototype = { crossVector: function ( vector ) { - console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); return vector.applyMatrix4( this ); }, @@ -5065,7 +5072,7 @@ THREE.Matrix4.prototype = { return function () { - console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); + THREE.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); var te = this.elements; return v1.set( te[ 12 ], te[ 13 ], te[ 14 ] ); @@ -5118,7 +5125,7 @@ THREE.Matrix4.prototype = { if ( det == 0 ) { - var msg = "Matrix4.getInverse(): can't invert matrix, determinant is 0"; + var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0"; if ( throwOnInvertible || false ) { @@ -5126,7 +5133,7 @@ THREE.Matrix4.prototype = { } else { - console.warn( msg ); + THREE.warn( msg ); } @@ -5143,31 +5150,31 @@ THREE.Matrix4.prototype = { translate: function ( v ) { - console.warn( 'THREE.Matrix4: .translate() has been removed.' ); + THREE.error( 'THREE.Matrix4: .translate() has been removed.' ); }, rotateX: function ( angle ) { - console.warn( 'THREE.Matrix4: .rotateX() has been removed.' ); + THREE.error( 'THREE.Matrix4: .rotateX() has been removed.' ); }, rotateY: function ( angle ) { - console.warn( 'THREE.Matrix4: .rotateY() has been removed.' ); + THREE.error( 'THREE.Matrix4: .rotateY() has been removed.' ); }, rotateZ: function ( angle ) { - console.warn( 'THREE.Matrix4: .rotateZ() has been removed.' ); + THREE.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); }, rotateByAxis: function ( axis, angle ) { - console.warn( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); + THREE.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); }, @@ -7346,7 +7353,7 @@ THREE.EventDispatcher.prototype = { } else { - console.error( 'THREE.Raycaster: Unsupported camera type.' ); + THREE.error( 'THREE.Raycaster: Unsupported camera type.' ); } @@ -7370,7 +7377,7 @@ THREE.EventDispatcher.prototype = { if ( objects instanceof Array === false ) { - console.log( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); + THREE.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); return intersects; } @@ -7478,7 +7485,7 @@ THREE.Object3D.prototype = { get eulerOrder () { - console.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); + THREE.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); return this.rotation.order; @@ -7486,7 +7493,7 @@ THREE.Object3D.prototype = { set eulerOrder ( value ) { - console.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); + THREE.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' ); this.rotation.order = value; @@ -7494,13 +7501,13 @@ THREE.Object3D.prototype = { get useQuaternion () { - console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); + THREE.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); }, set useQuaternion ( value ) { - console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); + THREE.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); }, @@ -7618,7 +7625,7 @@ THREE.Object3D.prototype = { translate: function ( distance, axis ) { - console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); + THREE.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); return this.translateOnAxis( axis, distance ); }, @@ -7709,7 +7716,7 @@ THREE.Object3D.prototype = { if ( object === this ) { - console.error( "THREE.Object3D.add:", object, "can't be added as a child of itself." ); + THREE.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); return this; } @@ -7729,7 +7736,7 @@ THREE.Object3D.prototype = { } else { - console.error( "THREE.Object3D.add:", object, "is not an instance of THREE.Object3D." ); + THREE.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); } @@ -7765,7 +7772,7 @@ THREE.Object3D.prototype = { getChildByName: function ( name ) { - console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); + THREE.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); return this.getObjectByName( name ); }, @@ -8088,12 +8095,7 @@ THREE.Object3D.prototype = { data.color = object.color.getHex(); data.groundColor = object.groundColor.getHex(); - } else if ( object instanceof THREE.Mesh ) { - - data.geometry = parseGeometry( object.geometry ); - data.material = parseMaterial( object.material ); - - } else if ( object instanceof THREE.Line ) { + } else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.PointCloud ) { data.geometry = parseGeometry( object.geometry ); data.material = parseMaterial( object.material ); @@ -8249,7 +8251,7 @@ THREE.Face3.prototype = { THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) { - console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ) + THREE.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ) return new THREE.Face3( a, b, c, normal, color, materialIndex ); }; @@ -8376,21 +8378,21 @@ THREE.BufferAttribute.prototype = { THREE.Int8Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint8Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint8ClampedAttribute = function ( data, itemSize ) { - console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); @@ -8398,42 +8400,42 @@ THREE.Uint8ClampedAttribute = function ( data, itemSize ) { THREE.Int16Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint16Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Int32Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Uint32Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Float32Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; THREE.Float64Attribute = function ( data, itemSize ) { - console.warn( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); + THREE.warn( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' ); return new THREE.BufferAttribute( data, itemSize ); }; @@ -8497,7 +8499,7 @@ THREE.BufferGeometry.prototype = { if ( attribute instanceof THREE.BufferAttribute === false ) { - console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); + THREE.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); this.attributes[ name ] = { array: arguments[ 1 ], itemSize: arguments[ 2 ] }; @@ -8743,7 +8745,7 @@ THREE.BufferGeometry.prototype = { if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.' ); + THREE.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.' ); } @@ -8797,7 +8799,7 @@ THREE.BufferGeometry.prototype = { if ( isNaN( this.boundingSphere.radius ) ) { - console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.' ); + THREE.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.' ); } @@ -8942,7 +8944,7 @@ THREE.BufferGeometry.prototype = { this.attributes.normal === undefined || this.attributes.uv === undefined ) { - console.warn( 'Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); + THREE.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); return; } @@ -9230,7 +9232,7 @@ THREE.BufferGeometry.prototype = { if ( geometry instanceof THREE.BufferGeometry === false ) { - console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); + THREE.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); return; } @@ -9993,7 +9995,7 @@ THREE.Geometry.prototype = { if ( geometry instanceof THREE.Geometry === false ) { - console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); + THREE.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); return; } @@ -10103,7 +10105,7 @@ THREE.Geometry.prototype = { if ( mesh instanceof THREE.Mesh === false ) { - console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); + THREE.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); return; } @@ -11879,7 +11881,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex if ( json.metadata !== undefined && json.metadata.type === 'scene' ) { - console.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' ); + THREE.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' ); return; } @@ -11889,7 +11891,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex } else { - console.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' ); + THREE.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' ); } @@ -11901,7 +11903,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex } else { - console.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' ); + THREE.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' ); } @@ -12288,7 +12290,7 @@ THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + + THREE.warn( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); } @@ -12558,6 +12560,10 @@ THREE.MaterialLoader.prototype = { if ( json.transparent !== undefined ) material.transparent = json.transparent; if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; + // for PointCloudMaterial + if ( json.size !== undefined ) material.size = json.size; + if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation; + if ( json.materials !== undefined ) { for ( var i = 0, l = json.materials.length; i < l; i ++ ) { @@ -12592,31 +12598,45 @@ THREE.ObjectLoader.prototype = { load: function ( url, onLoad, onProgress, onError ) { + if ( this.texturePath === undefined ) { + + this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 ); + + } + var scope = this; var loader = new THREE.XHRLoader( scope.manager ); loader.setCrossOrigin( this.crossOrigin ); loader.load( url, function ( text ) { - onLoad( scope.parse( JSON.parse( text ) ) ); + scope.parse( JSON.parse( text ), onLoad ); }, onProgress, onError ); }, + setTexturePath: function ( value ) { + + this.texturePath = value; + + }, + setCrossOrigin: function ( value ) { this.crossOrigin = value; }, - parse: function ( json ) { + parse: function ( json, onLoad ) { var geometries = this.parseGeometries( json.geometries ); - var materials = this.parseMaterials( json.materials ); - var object = this.parseObject( json.object, geometries, materials ); - return object; + var images = this.parseImages( json.images, onLoad ); + var textures = this.parseTextures( json.textures, images ); + var materials = this.parseMaterials( json.materials, textures ); + + return this.parseObject( json.object, geometries, materials ); }, @@ -12760,12 +12780,24 @@ THREE.ObjectLoader.prototype = { }, - parseMaterials: function ( json ) { + parseMaterials: function ( json, textures ) { var materials = {}; if ( json !== undefined ) { + var getTexture = function ( name ) { + + if ( textures[ name ] === undefined ) { + + THREE.warn( 'THREE.ObjectLoader: Undefined texture', name ); + + } + + return textures[ name ]; + + }; + var loader = new THREE.MaterialLoader(); for ( var i = 0, l = json.length; i < l; i ++ ) { @@ -12777,6 +12809,48 @@ THREE.ObjectLoader.prototype = { if ( data.name !== undefined ) material.name = data.name; + if ( data.map !== undefined ) { + + material.map = getTexture( data.map ); + + } + + if ( data.bumpMap !== undefined ) { + + material.bumpMap = getTexture( data.bumpMap ); + + } + + if ( data.alphaMap !== undefined ) { + + material.alphaMap = getTexture( data.alphaMap ); + + } + + if ( data.envMap !== undefined ) { + + material.envMap = getTexture( data.envMap ); + + } + + if ( data.normalMap !== undefined ) { + + material.normalMap = getTexture( data.normalMap ); + + } + + if ( data.lightMap !== undefined ) { + + material.lightMap = getTexture( data.lightMap ); + + } + + if ( data.specularMap !== undefined ) { + + material.specularMap = getTexture( data.specularMap ); + + } + materials[ data.uuid ] = material; } @@ -12787,6 +12861,99 @@ THREE.ObjectLoader.prototype = { }, + parseImages: function ( json, onLoad ) { + + var scope = this; + var images = {}; + + if ( json !== undefined && json.length > 0 ) { + + var manager = new THREE.LoadingManager( onLoad ); + + var loader = new THREE.ImageLoader( manager ); + loader.setCrossOrigin( this.crossOrigin ); + + var loadImage = function ( data ) { + + var url = scope.texturePath + data.url; + + scope.manager.itemStart( url ); + + loader.load( url, function ( image ) { + + scope.manager.itemEnd( url ); + + images[ data.uuid ] = image; + + } ); + + }; + + for ( var i = 0, l = json.length; i < l; i ++ ) { + + loadImage( json[ i ] ); + + } + + } else { + + if ( onLoad !== undefined ) onLoad(); + + } + + return images; + + }, + + parseTextures: function ( json, images ) { + + var textures = {}; + + if ( json !== undefined ) { + + for ( var i = 0, l = json.length; i < l; i ++ ) { + + var data = json[ i ]; + + if ( data.image === undefined ) { + + THREE.warn( 'THREE.ObjectLoader: No "image" speficied for', data.uuid ); + + } + + if ( images[ data.image ] === undefined ) { + + THREE.warn( 'THREE.ObjectLoader: Undefined image', data.image ); + + } + + var texture = new THREE.Texture( images[ data.image ] ); + texture.needsUpdate = true; + + texture.uuid = data.uuid; + + if ( data.name !== undefined ) texture.name = data.name; + if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] ); + if ( data.minFilter !== undefined ) texture.minFilter = THREE[ data.minFilter ]; + if ( data.magFilter !== undefined ) texture.magFilter = THREE[ data.magFilter ]; + if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; + if ( data.wrap instanceof Array ) { + + texture.wrapS = THREE[ data.wrap[ 0 ] ]; + texture.wrapT = THREE[ data.wrap[ 1 ] ]; + + } + + textures[ data.uuid ] = texture; + + } + + } + + return textures; + + }, + parseObject: function () { var matrix = new THREE.Matrix4(); @@ -12795,6 +12962,30 @@ THREE.ObjectLoader.prototype = { var object; + var getGeometry = function ( name ) { + + if ( geometries[ name ] === undefined ) { + + THREE.warn( 'THREE.ObjectLoader: Undefined geometry', name ); + + } + + return geometries[ name ]; + + }; + + var getMaterial = function ( name ) { + + if ( materials[ name ] === undefined ) { + + THREE.warn( 'THREE.ObjectLoader: Undefined material', name ); + + } + + return materials[ name ]; + + }; + switch ( data.type ) { case 'Scene': @@ -12847,57 +13038,25 @@ THREE.ObjectLoader.prototype = { case 'Mesh': - var geometry = geometries[ data.geometry ]; - var material = materials[ data.material ]; - - if ( geometry === undefined ) { - - console.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); - - } - - if ( material === undefined ) { - - console.warn( 'THREE.ObjectLoader: Undefined material', data.material ); - - } - - object = new THREE.Mesh( geometry, material ); + object = new THREE.Mesh( getGeometry( data.geometry ), getMaterial( data.material ) ); break; case 'Line': - var geometry = geometries[ data.geometry ]; - var material = materials[ data.material ]; - - if ( geometry === undefined ) { - - console.warn( 'THREE.ObjectLoader: Undefined geometry', data.geometry ); + object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ) ); - } - - if ( material === undefined ) { - - console.warn( 'THREE.ObjectLoader: Undefined material', data.material ); + break; - } + case 'PointCloud': - object = new THREE.Line( geometry, material ); + object = new THREE.PointCloud( getGeometry( data.geometry ), getMaterial( data.material ) ); break; case 'Sprite': - var material = materials[ data.material ]; - - if ( material === undefined ) { - - console.warn( 'THREE.ObjectLoader: Undefined material', data.material ); - - } - - object = new THREE.Sprite( material ); + object = new THREE.Sprite( getMaterial( data.material ) ); break; @@ -13289,7 +13448,7 @@ THREE.Material.prototype = { if ( newValue === undefined ) { - console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); + THREE.warn( "THREE.Material: '" + key + "' parameter is undefined." ); continue; } @@ -13373,6 +13532,15 @@ THREE.Material.prototype = { if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; if ( this.side !== THREE.FrontSide ) output.side = this.side; + } else if ( this instanceof THREE.PointCloudMaterial ) { + + output.size = this.size; + output.sizeAttenuation = this.sizeAttenuation; + output.color = this.color.getHex(); + + if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; + if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; + } else if ( this instanceof THREE.ShaderMaterial ) { output.uniforms = this.uniforms; @@ -14234,14 +14402,14 @@ THREE.PointCloudMaterial.prototype.clone = function () { THREE.ParticleBasicMaterial = function ( parameters ) { - console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointCloudMaterial.' ); + THREE.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointCloudMaterial.' ); return new THREE.PointCloudMaterial( parameters ); }; THREE.ParticleSystemMaterial = function ( parameters ) { - console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' ); + THREE.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' ); return new THREE.PointCloudMaterial( parameters ); }; @@ -14870,7 +15038,7 @@ THREE.PointCloud.prototype.clone = function ( object ) { THREE.ParticleSystem = function ( geometry, material ) { - console.warn( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' ); + THREE.warn( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' ); return new THREE.PointCloud( geometry, material ); }; @@ -15124,7 +15292,7 @@ THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) { } - console.log( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); + THREE.warn( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); return 0; @@ -15492,7 +15660,7 @@ THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) { } else { - console.warn( 'THREE.Skeleton bonInverses is the wrong length.' ); + THREE.warn( 'THREE.Skeleton bonInverses is the wrong length.' ); this.boneInverses = []; @@ -15755,7 +15923,7 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) { } else { - console.warn( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode ); + THREE.warn( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode ); } @@ -15889,7 +16057,7 @@ THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) { } else { - console.warn( 'animation[' + label + '] undefined' ); + THREE.warn( 'THREE.MorphAnimMesh: animation[' + label + '] undefined in .playAnimation()' ); } @@ -17770,7 +17938,7 @@ THREE.WebGLRenderer = function ( parameters ) { } catch ( error ) { - console.error( error ); + THREE.error( 'THREE.WebGLRenderer: ' + error ); } @@ -17928,12 +18096,12 @@ THREE.WebGLRenderer = function ( parameters ) { if ( mediumpAvailable ) { _precision = 'mediump'; - console.warn( 'THREE.WebGLRenderer: highp not supported, using mediump.' ); + THREE.warn( 'THREE.WebGLRenderer: highp not supported, using mediump.' ); } else { _precision = 'lowp'; - console.warn( 'THREE.WebGLRenderer: highp and mediump not supported, using lowp.' ); + THREE.warn( 'THREE.WebGLRenderer: highp and mediump not supported, using lowp.' ); } @@ -17942,7 +18110,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _precision === 'mediump' && ! mediumpAvailable ) { _precision = 'lowp'; - console.warn( 'THREE.WebGLRenderer: mediump not supported, using lowp.' ); + THREE.warn( 'THREE.WebGLRenderer: mediump not supported, using lowp.' ); } @@ -20853,7 +21021,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( camera instanceof THREE.Camera === false ) { - console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); + THREE.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); return; } @@ -22396,7 +22564,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( textureUnit >= _maxTextures ) { - console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures ); + THREE.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures ); } @@ -22734,7 +22902,7 @@ THREE.WebGLRenderer = function ( parameters ) { default: - console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type ); + THREE.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type ); } @@ -23200,7 +23368,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) { - console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' ); + THREE.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' ); } @@ -23209,7 +23377,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) { - console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( ' + texture.sourceFile + ' )' ); + THREE.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ' + texture.sourceFile + ' )' ); } @@ -23298,7 +23466,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - console.warn( "Attempt to load unsupported compressed texture format" ); + THREE.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" ); } @@ -23375,7 +23543,7 @@ THREE.WebGLRenderer = function ( parameters ) { var context = canvas.getContext( '2d' ); context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); - console.log( 'THREE.WebGLRenderer:', image, 'is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height + '.' ); + THREE.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image ); return canvas; @@ -23462,7 +23630,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - console.warn( "Attempt to load unsupported compressed texture format" ); + THREE.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()" ); } @@ -23897,7 +24065,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( maxBones < object.skeleton.bones.length ) { - console.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' ); + THREE.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' ); } @@ -23956,25 +24124,25 @@ THREE.WebGLRenderer = function ( parameters ) { this.initMaterial = function () { - console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); + THREE.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); }; this.addPrePlugin = function () { - console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); + THREE.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); }; this.addPostPlugin = function () { - console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); + THREE.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); }; this.updateShadowMap = function () { - console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); + THREE.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); }; @@ -24125,7 +24293,7 @@ THREE.WebGLExtensions = function ( gl ) { if ( extension === null ) { - console.log( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); + THREE.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); } @@ -24479,19 +24647,19 @@ THREE.WebGLProgram = ( function () { _gl.linkProgram( program ); + var programLogInfo = _gl.getProgramInfoLog( program ); + if ( _gl.getProgramParameter( program, _gl.LINK_STATUS ) === false ) { - console.error( 'THREE.WebGLProgram: Could not initialise shader.' ); - console.error( 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) ); - console.error( 'gl.getError()', _gl.getError() ); + THREE.error( 'THREE.WebGLProgram: shader error: ' + _gl.getError(), 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ), 'gl.getPRogramInfoLog', programLogInfo ); } + + if ( programLogInfo !== '' ) { - if ( _gl.getProgramInfoLog( program ) !== '' ) { - - console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', _gl.getProgramInfoLog( program ) ); - // console.warn( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); - // console.warn( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); + THREE.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()' + programLogInfo ); + // THREE.warn( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); + // THREE.warn( _gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); } @@ -24622,14 +24790,13 @@ THREE.WebGLShader = ( function () { if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) { - console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); + THREE.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); } if ( gl.getShaderInfoLog( shader ) !== '' ) { - console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ) ); - console.warn( addLineNumbers( string ) ); + THREE.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ), addLineNumbers( string ) ); } @@ -25240,7 +25407,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje light.shadowCascadeArray[ n ] = virtualLight; - console.log( "Created virtualLight", virtualLight ); + //console.log( "Created virtualLight", virtualLight ); } else { @@ -25301,7 +25468,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje } else { - console.error( "Unsupported light type for shadow" ); + THREE.error( "THREE.ShadowMapPlugin: Unsupported light type for shadow", light ); continue; } @@ -26016,7 +26183,7 @@ THREE.GeometryUtils = { merge: function ( geometry1, geometry2, materialIndexOffset ) { - console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); + THREE.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); var matrix; @@ -26035,7 +26202,7 @@ THREE.GeometryUtils = { center: function ( geometry ) { - console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); + THREE.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); return geometry.center(); } @@ -26127,13 +26294,13 @@ THREE.ImageUtils = { loadCompressedTexture: function () { - console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' ) + THREE.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' ) }, loadCompressedTextureCube: function () { - console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' ) + THREE.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' ) }, @@ -26646,7 +26813,7 @@ THREE.FontUtils.generateShapes = function ( text, parameters ) { //throw ( "Warning, unable to triangulate polygon!" ); //return null; // Sometimes warning is fine, especially polygons are triangulated in reverse. - console.log( 'Warning, unable to triangulate polygon!' ); + THREE.warn( 'THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()' ); if ( indices ) return vertIndices; return result; @@ -26965,7 +27132,7 @@ THREE.Curve = function () { THREE.Curve.prototype.getPoint = function ( t ) { - console.log( "Warning, getPoint() not implemented!" ); + THREE.warn( "THREE.Curve: Warning, getPoint() not implemented!" ); return null; }; @@ -28796,7 +28963,7 @@ THREE.Shape.Utils = { if ( allPointsMap[ key ] !== undefined ) { - console.log( "Duplicate point", key ); + THREE.warn( "THREE.Shape: Duplicate point", key ); } @@ -29327,9 +29494,9 @@ THREE.AnimationHandler = { // - add: function () { console.warn( 'THREE.AnimationHandler.add() has been deprecated.' ); }, - get: function () { console.warn( 'THREE.AnimationHandler.get() has been deprecated.' ); }, - remove: function () { console.warn( 'THREE.AnimationHandler.remove() has been deprecated.' ); }, + add: function () { THREE.warn( 'THREE.AnimationHandler.add() has been deprecated.' ); }, + get: function () { THREE.warn( 'THREE.AnimationHandler.get() has been deprecated.' ); }, + remove: function () { THREE.warn( 'THREE.AnimationHandler.remove() has been deprecated.' ); }, // @@ -30450,7 +30617,7 @@ THREE.CircleGeometry.prototype.constructor = THREE.CircleGeometry; THREE.CubeGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) { - console.warn( 'THREE.CubeGeometry has been renamed to THREE.BoxGeometry.' ); + THREE.warn( 'THREE.CubeGeometry has been renamed to THREE.BoxGeometry.' ); return new THREE.BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ); }; @@ -30808,7 +30975,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { function scalePt2 ( pt, vec, size ) { - if ( ! vec ) console.log( "die" ); + if ( ! vec ) THREE.error( "THREE.ExtrudeGeometry: vec does not exist" ); return vec.clone().multiplyScalar( size ).add( pt ); @@ -32872,7 +33039,7 @@ THREE.ParametricGeometry = function ( func, slices, stacks ) { var faces = this.faces; var uvs = this.faceVertexUvs[ 0 ]; - var i, il, j, p; + var i, j, p; var u, v; var stackCount = stacks + 1; @@ -33506,7 +33673,18 @@ THREE.EdgesHelper = function ( object, hex ) { var keys = [ 'a', 'b', 'c' ]; var geometry = new THREE.BufferGeometry(); - var geometry2 = object.geometry.clone(); + var geometry2; + + if ( object.geometry instanceof THREE.BufferGeometry ) { + + geometry2 = new THREE.Geometry(); + geometry2.fromBufferGeometry( object.geometry ); + + } else { + + geometry2 = object.geometry.clone(); + + } geometry2.mergeVertices(); geometry2.computeFaceNormals(); @@ -34624,7 +34802,7 @@ THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) { } else { - console.warn( "animation[" + name + "] undefined" ); + THREE.warn( "THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()" ); } diff --git a/build/three.min.js b/build/three.min.js index aa270b4643cbc0..e5e4c3d84d674d 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -1,11 +1,12 @@ // threejs.org/license -'use strict';var THREE={REVISION:"71dev"};"object"===typeof module&&(module.exports=THREE);void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0a?-1:0>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){if(0===b)this.r=this.g=this.b=c;else{var d=function(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a};b=.5>=c?c*(1+b):c+b-c*b;c=2*c-b;this.r=d(c,b,a+1/3);this.g=d(c,b,a);this.b=d(c,b,a-1/3)}return this},setStyle:function(a){if(/^rgb\((\d+), ?(\d+), ?(\d+)\)$/i.test(a))return a=/^rgb\((\d+), ?(\d+), ?(\d+)\)$/i.exec(a),this.r=Math.min(255,parseInt(a[1],10))/255,this.g=Math.min(255,parseInt(a[2],10))/255,this.b=Math.min(255,parseInt(a[3],10))/255,this;if(/^rgb\((\d+)\%, ?(\d+)\%, ?(\d+)\%\)$/i.test(a))return a=/^rgb\((\d+)\%, ?(\d+)\%, ?(\d+)\%\)$/i.exec(a),this.r= Math.min(100,parseInt(a[1],10))/100,this.g=Math.min(100,parseInt(a[2],10))/100,this.b=Math.min(100,parseInt(a[3],10))/100,this;if(/^\#([0-9a-f]{6})$/i.test(a))return a=/^\#([0-9a-f]{6})$/i.exec(a),this.setHex(parseInt(a[1],16)),this;if(/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.test(a))return a=/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(a),this.setHex(parseInt(a[1]+a[1]+a[2]+a[2]+a[3]+a[3],16)),this;if(/^(\w+)$/i.test(a))return this.setHex(THREE.ColorKeywords[a]),this},copy:function(a){this.r=a.r;this.g= @@ -25,37 +26,37 @@ c*d*h-f*g*e,this._w=c*d*e+f*g*h):"ZXY"===a.order?(this._x=f*d*e-c*g*h,this._y=c* b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w=Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],p=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y= .25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+k)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):a.crossVectors(c,d);this._x=a.x;this._y=a.y;this._z=a.z;this._w=b;this.normalize();return this}}(),inverse:function(){this.conjugate().normalize();return this},conjugate:function(){this._x*= -1;this._y*=-1;this._z*=-1;this.onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this.onChangeCallback();return this}, -multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,p=b._w;this._x=c*p+f*g+d*k-e*h;this._y=d*p+f*h+e*g-c*k;this._z=e*p+f*k+c*h-d*g;this._w=f*p-c*g-d*h-e*k;this.onChangeCallback();return this},multiplyVector3:function(a){console.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead."); +multiply:function(a,b){return void 0!==b?(THREE.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,p=b._w;this._x=c*p+f*g+d*k-e*h;this._y=d*p+f*h+e*g-c*k;this._z=e*p+f*k+c*h-d*g;this._w=f*p-c*g-d*h-e*k;this.onChangeCallback();return this},multiplyVector3:function(a){THREE.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead."); return a.applyQuaternion(this)},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;var h=Math.acos(g),k=Math.sqrt(1-g*g);if(.001>Math.abs(k))return this._w=.5*(f+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;g=Math.sin((1-b)*h)/k;h= Math.sin(b*h)/k;this._w=f*g+this._w*h;this._x=c*g+this._x*h;this._y=d*g+this._y*h;this._z=e*g+this._z*h;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback= a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Quaternion(this._x,this._y,this._z,this._w)}};THREE.Quaternion.slerp=function(a,b,c,d){return c.copy(a).slerp(b,d)};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; THREE.Vector2.prototype={constructor:THREE.Vector2,set:function(a,b){this.x=a;this.y=b;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a, -b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this}, +b){if(void 0!==b)return THREE.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this}, subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a):this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector2,b=new THREE.Vector2);a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this}, roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b= this.x-a.x;a=this.y-a.y;return b*b+a*a},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x; a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];return this},clone:function(){return new THREE.Vector2(this.x,this.y)}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+ -a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), -this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y= -a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&&console.error("THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));return this}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),applyMatrix3:function(a){var b=this.x, +a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y= +a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&&THREE.error("THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));return this}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),applyMatrix3:function(a){var b=this.x, c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z= (a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,p=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-p*-f;this.y=k*a+b*-f+p*-e-h*-g;this.z=p*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0=== a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},min:function(a){this.x> a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3,b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a, b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z); return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/ -b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},cross:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c= +b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},cross:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c= a.x,d=a.y,e=a.z,f=b.x,g=b.y,h=b.z;this.x=d*h-e*g;this.y=e*f-c*h;this.z=c*g-d*f;return this},projectOnVector:function(){var a,b;return function(c){void 0===a&&(a=new THREE.Vector3);a.copy(c).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);return this.sub(a.copy(b).multiplyScalar(2* -this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/(this.length()*a.length());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},setEulerFromRotationMatrix:function(a,b){console.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")},setEulerFromQuaternion:function(a,b){console.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")}, -getPositionFromMatrix:function(a){console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},getScaleFromMatrix:function(a){console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a,b){console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(a, -b)},setFromMatrixPosition:function(a){this.x=a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},setFromMatrixScale:function(a){var b=this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length();a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x=== -this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];return this},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)}}; +this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/(this.length()*a.length());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},setEulerFromRotationMatrix:function(a,b){THREE.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")},setEulerFromQuaternion:function(a,b){THREE.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")}, +getPositionFromMatrix:function(a){THREE.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},getScaleFromMatrix:function(a){THREE.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a,b){THREE.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(a,b)},setFromMatrixPosition:function(a){this.x= +a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},setFromMatrixScale:function(a){var b=this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length();a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x===this.x&&a.y===this.y&& +a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];return this},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)}}; THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x; -case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this}, -addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b= +case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a, +b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b= this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a):(this.z=this.y=this.x=0,this.w=1);return this},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this}, setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var p=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+p-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;p=(p+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>p?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>p?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h), b=d/c,d=k/c):.01>p?(c=b=.707106781,d=0):(d=Math.sqrt(p),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+p-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xMath.abs(g)?(this._x=Math.atan2(-p,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(q,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h, k)):(this._y=Math.atan2(-n,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(q,-1,1)),.99999>Math.abs(q)?(this._y=Math.atan2(-n,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._x=Math.atan2(q,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-p,k),this._y=Math.atan2(-n,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z= -Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(q,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-p,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z, +Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(q,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-p,e),this._y=0)):THREE.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z, b||this._order)},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a? a.set(this._x,this._y,this._z):new THREE.Vector3(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Euler(this._x,this._y,this._z,this._order)}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; THREE.Line3.prototype={constructor:THREE.Line3,set:function(a,b){this.start.copy(a);this.end.copy(b);return this},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},center:function(a){return(a||new THREE.Vector3).addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){return(a||new THREE.Vector3).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a, @@ -86,32 +87,32 @@ this.max.add(a);return this},expandByScalar:function(a){this.min.addScalar(-a);t this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},isIntersectionBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},clampPoint:function(a,b){return(b||new THREE.Vector3).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a= new THREE.Vector3;return function(b){b=b||new THREE.Sphere;b.center=this.center();b.radius=.5*this.size(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];return function(b){a[0].set(this.min.x,this.min.y, this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.makeEmpty();this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a); -this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box3).copy(this)}};THREE.Matrix3=function(){this.elements=new Float32Array([1,0,0,0,1,0,0,0,1]);0this.determinant()&&(g=-g);c.x=f[12]; +if(0==c){if(b)throw Error("THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0");THREE.warn("THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0");this.identity();return this}this.multiplyScalar(1/c);return this},translate:function(a){THREE.error("THREE.Matrix4: .translate() has been removed.")},rotateX:function(a){THREE.error("THREE.Matrix4: .rotateX() has been removed.")},rotateY:function(a){THREE.error("THREE.Matrix4: .rotateY() has been removed.")},rotateZ:function(a){THREE.error("THREE.Matrix4: .rotateZ() has been removed.")}, +rotateByAxis:function(a,b){THREE.error("THREE.Matrix4: .rotateByAxis() has been removed.")},scale:function(a){var b=this.elements,c=a.x,d=a.y;a=a.z;b[0]*=c;b[4]*=d;b[8]*=a;b[1]*=c;b[5]*=d;b[9]*=a;b[2]*=c;b[6]*=d;b[10]*=a;b[3]*=c;b[7]*=d;b[11]*=a;return this},getMaxScaleOnAxis:function(){var a=this.elements;return Math.sqrt(Math.max(a[0]*a[0]+a[1]*a[1]+a[2]*a[2],Math.max(a[4]*a[4]+a[5]*a[5]+a[6]*a[6],a[8]*a[8]+a[9]*a[9]+a[10]*a[10])))},makeTranslation:function(a,b,c){this.set(1,0,0,a,0,1,0,b,0,0,1, +c,0,0,0,1);return this},makeRotationX:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(1,0,0,0,0,b,-a,0,0,a,b,0,0,0,0,1);return this},makeRotationY:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,0,a,0,0,1,0,0,-a,0,b,0,0,0,0,1);return this},makeRotationZ:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,-a,0,0,a,b,0,0,0,0,1,0,0,0,0,1);return this},makeRotationAxis:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=1-c,f=a.x,g=a.y,h=a.z,k=e*f,p=e*g;this.set(k*f+c,k*g-d*h,k*h+d*g,0,k*g+ +d*h,p*g+c,p*h-d*f,0,k*h-d*g,p*h+d*f,e*h*h+c,0,0,0,0,1);return this},makeScale:function(a,b,c){this.set(a,0,0,0,0,b,0,0,0,0,c,0,0,0,0,1);return this},compose:function(a,b,c){this.makeRotationFromQuaternion(b);this.scale(c);this.setPosition(a);return this},decompose:function(){var a=new THREE.Vector3,b=new THREE.Matrix4;return function(c,d,e){var f=this.elements,g=a.set(f[0],f[1],f[2]).length(),h=a.set(f[4],f[5],f[6]).length(),k=a.set(f[8],f[9],f[10]).length();0>this.determinant()&&(g=-g);c.x=f[12]; c.y=f[13];c.z=f[14];b.elements.set(this.elements);c=1/g;var f=1/h,p=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=p;b.elements[9]*=p;b.elements[10]*=p;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makeFrustum:function(a,b,c,d,e,f){var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(d-c);g[9]=(d+c)/(d-c);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0; g[11]=-1;g[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(THREE.Math.degToRad(.5*a));var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=b-a,k=c-d,p=f-e;g[0]=2/h;g[4]=0;g[8]=0;g[12]=-((b+a)/h);g[1]=0;g[5]=2/k;g[9]=0;g[13]=-((c+d)/k);g[2]=0;g[6]=0;g[10]=-2/p;g[14]=-((f+e)/p);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0], a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]]},clone:function(){return(new THREE.Matrix4).fromArray(this.elements)}};THREE.Ray=function(a,b){this.origin=void 0!==a?a:new THREE.Vector3;this.direction=void 0!==b?b:new THREE.Vector3}; @@ -153,54 +154,54 @@ a=.001*(b-this.oldTime);this.oldTime=b;this.elapsedTime+=a}return a}};THREE.Even THREE.EventDispatcher.prototype={constructor:THREE.EventDispatcher,apply:function(a){a.addEventListener=THREE.EventDispatcher.prototype.addEventListener;a.hasEventListener=THREE.EventDispatcher.prototype.hasEventListener;a.removeEventListener=THREE.EventDispatcher.prototype.removeEventListener;a.dispatchEvent=THREE.EventDispatcher.prototype.dispatchEvent},addEventListener:function(a,b){void 0===this._listeners&&(this._listeners={});var c=this._listeners;void 0===c[a]&&(c[a]=[]);-1===c[a].indexOf(b)&& c[a].push(b)},hasEventListener:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)?!0:!1},removeEventListener:function(a,b){if(void 0!==this._listeners){var c=this._listeners[a];if(void 0!==c){var d=c.indexOf(b);-1!==d&&c.splice(d,1)}}},dispatchEvent:function(a){if(void 0!==this._listeners){var b=this._listeners[a.type];if(void 0!==b){a.target=this;for(var c=[],d=b.length,e=0;eja?-1:1;h[4*a]=na.x;h[4*a+1]=na.y;h[4*a+2]=na.z;h[4*a+3]=xa}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],p=[],n=0;nja?-1:1;h[4*a]=na.x;h[4*a+1]=na.y;h[4*a+2]=na.z;h[4*a+3]=xa}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, +e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],p=[],n=0;nr;r++)t=a[3*c+r],-1==m[t]?(q[2*r]=t,q[2*r+1]=-1,n++):m[t]k.index+b)for(k={start:f,count:0,index:g},h.push(k),n=0;6>n;n+=2)r=q[n+1],-1n;n+=2)t=q[n],r=q[n+1],-1===r&&(r=g++),m[t]=r,s[r]=t,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,s,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hn;n+=2)t=q[n],r=q[n+1],-1===r&&(r=g++),m[t]=r,s[r]=t,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,s,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cg;g++)m=x[k++],v=u[2*m],m=u[2*m+1],v=new THREE.Vector2(v,m),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]),r.normal.copy(s.normal));if(t)for(d=0;4>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++], C[q++],C[q]),2!==d&&s.vertexNormals.push(t),0!==d&&r.vertexNormals.push(t);n&&(n=x[k++],n=w[n],s.color.setHex(n),r.color.setHex(n));if(b)for(d=0;4>d;d++)n=x[k++],n=w[n],2!==d&&s.vertexColors.push(new THREE.Color(n)),0!==d&&r.vertexColors.push(new THREE.Color(n));c.faces.push(s);c.faces.push(r)}else{s=new THREE.Face3;s.a=x[k++];s.b=x[k++];s.c=x[k++];h&&(h=x[k++],s.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)m=x[k++],v=u[2*m],m=u[2*m+1], v=new THREE.Vector2(v,m),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]));if(t)for(d=0;3>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++],C[q++],C[q]),s.vertexNormals.push(t);n&&(n=x[k++],s.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=x[k++],s.vertexColors.push(new THREE.Color(w[n]));c.faces.push(s)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;dthis.opacity&&(a.opacity=this.opacity);!1!==this.transparent&&(a.transparent=this.transparent);!1!==this.wireframe&&(a.wireframe=this.wireframe);return a},clone:function(a){void 0===a&&(a=new THREE.Material);a.name=this.name;a.side=this.side;a.opacity=this.opacity;a.transparent=this.transparent;a.blending=this.blending;a.blendSrc=this.blendSrc;a.blendDst=this.blendDst;a.blendEquation=this.blendEquation;a.blendSrcAlpha=this.blendSrcAlpha;a.blendDstAlpha= -this.blendDstAlpha;a.blendEquationAlpha=this.blendEquationAlpha;a.depthTest=this.depthTest;a.depthWrite=this.depthWrite;a.polygonOffset=this.polygonOffset;a.polygonOffsetFactor=this.polygonOffsetFactor;a.polygonOffsetUnits=this.polygonOffsetUnits;a.alphaTest=this.alphaTest;a.overdraw=this.overdraw;a.visible=this.visible;return a},update:function(){this.dispatchEvent({type:"update"})},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Material.prototype); -THREE.MaterialIdCount=0;THREE.LineBasicMaterial=function(a){THREE.Material.call(this);this.type="LineBasicMaterial";this.color=new THREE.Color(16777215);this.linewidth=1;this.linejoin=this.linecap="round";this.vertexColors=THREE.NoColors;this.fog=!0;this.setValues(a)};THREE.LineBasicMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineBasicMaterial.prototype.constructor=THREE.LineBasicMaterial; -THREE.LineBasicMaterial.prototype.clone=function(){var a=new THREE.LineBasicMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.linewidth=this.linewidth;a.linecap=this.linecap;a.linejoin=this.linejoin;a.vertexColors=this.vertexColors;a.fog=this.fog;return a}; +THREE.MeshNormalMaterial?(this.shading!==THREE.FlatShading&&(a.shading=this.shading),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshDepthMaterial?(this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.PointCloudMaterial?(a.size=this.size,a.sizeAttenuation=this.sizeAttenuation,a.color=this.color.getHex(),this.vertexColors!==THREE.NoColors&& +(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending)):this instanceof THREE.ShaderMaterial?(a.uniforms=this.uniforms,a.vertexShader=this.vertexShader,a.fragmentShader=this.fragmentShader):this instanceof THREE.SpriteMaterial&&(a.color=this.color.getHex());1>this.opacity&&(a.opacity=this.opacity);!1!==this.transparent&&(a.transparent=this.transparent);!1!==this.wireframe&&(a.wireframe=this.wireframe);return a},clone:function(a){void 0===a&&(a=new THREE.Material); +a.name=this.name;a.side=this.side;a.opacity=this.opacity;a.transparent=this.transparent;a.blending=this.blending;a.blendSrc=this.blendSrc;a.blendDst=this.blendDst;a.blendEquation=this.blendEquation;a.blendSrcAlpha=this.blendSrcAlpha;a.blendDstAlpha=this.blendDstAlpha;a.blendEquationAlpha=this.blendEquationAlpha;a.depthTest=this.depthTest;a.depthWrite=this.depthWrite;a.polygonOffset=this.polygonOffset;a.polygonOffsetFactor=this.polygonOffsetFactor;a.polygonOffsetUnits=this.polygonOffsetUnits;a.alphaTest= +this.alphaTest;a.overdraw=this.overdraw;a.visible=this.visible;return a},update:function(){this.dispatchEvent({type:"update"})},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Material.prototype);THREE.MaterialIdCount=0;THREE.LineBasicMaterial=function(a){THREE.Material.call(this);this.type="LineBasicMaterial";this.color=new THREE.Color(16777215);this.linewidth=1;this.linejoin=this.linecap="round";this.vertexColors=THREE.NoColors;this.fog=!0;this.setValues(a)}; +THREE.LineBasicMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineBasicMaterial.prototype.constructor=THREE.LineBasicMaterial;THREE.LineBasicMaterial.prototype.clone=function(){var a=new THREE.LineBasicMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.linewidth=this.linewidth;a.linecap=this.linecap;a.linejoin=this.linejoin;a.vertexColors=this.vertexColors;a.fog=this.fog;return a}; THREE.LineDashedMaterial=function(a){THREE.Material.call(this);this.type="LineDashedMaterial";this.color=new THREE.Color(16777215);this.scale=this.linewidth=1;this.dashSize=3;this.gapSize=1;this.vertexColors=!1;this.fog=!0;this.setValues(a)};THREE.LineDashedMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineDashedMaterial.prototype.constructor=THREE.LineDashedMaterial; THREE.LineDashedMaterial.prototype.clone=function(){var a=new THREE.LineDashedMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.linewidth=this.linewidth;a.scale=this.scale;a.dashSize=this.dashSize;a.gapSize=this.gapSize;a.vertexColors=this.vertexColors;a.fog=this.fog;return a}; THREE.MeshBasicMaterial=function(a){THREE.Material.call(this);this.type="MeshBasicMaterial";this.color=new THREE.Color(16777215);this.envMap=this.alphaMap=this.specularMap=this.lightMap=this.map=null;this.combine=THREE.MultiplyOperation;this.reflectivity=1;this.refractionRatio=.98;this.fog=!0;this.shading=THREE.SmoothShading;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.vertexColors=THREE.NoColors;this.morphTargets=this.skinning=!1;this.setValues(a)}; @@ -319,8 +323,8 @@ THREE.MeshDepthMaterial.prototype.clone=function(){var a=new THREE.MeshDepthMate THREE.MeshNormalMaterial.prototype.constructor=THREE.MeshNormalMaterial;THREE.MeshNormalMaterial.prototype.clone=function(){var a=new THREE.MeshNormalMaterial;THREE.Material.prototype.clone.call(this,a);a.shading=this.shading;a.wireframe=this.wireframe;a.wireframeLinewidth=this.wireframeLinewidth;return a};THREE.MeshFaceMaterial=function(a){this.uuid=THREE.Math.generateUUID();this.type="MeshFaceMaterial";this.materials=a instanceof Array?a:[]}; THREE.MeshFaceMaterial.prototype={constructor:THREE.MeshFaceMaterial,toJSON:function(){for(var a={metadata:{version:4.2,type:"material",generator:"MaterialExporter"},uuid:this.uuid,type:this.type,materials:[]},b=0,c=this.materials.length;bf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, object:this}))}}else for(m=m.position.array,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld), index:g,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(a){void 0===a&&(a=new THREE.Line(this.geometry,this.material,this.mode));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype); THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=n.position.array,t=k=0,w=r.length;k @@ -352,18 +356,18 @@ g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,m,THREE.Triangle.norm 0,0);for(var w=0,F=y.length;wg.far||h.push({distance:A,point:y,face:C,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(this.boneTextureHeight=this.boneTextureWidth=a=256h.end&&(h.end=e);b||(b=g)}}a.firstAnimation=b}; -THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){this.geometry.animations||(this.geometry.animations={});this.geometry.animations[a]={start:b,end:c}};THREE.MorphAnimMesh.prototype.playAnimation=function(a,b){var c=this.geometry.animations[a];c?(this.setFrameRange(c.start,c.end),this.duration=(c.end-c.start)/b*1E3,this.time=0):console.warn("animation["+a+"] undefined")}; +THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){this.geometry.animations||(this.geometry.animations={});this.geometry.animations[a]={start:b,end:c}};THREE.MorphAnimMesh.prototype.playAnimation=function(a,b){var c=this.geometry.animations[a];c?(this.setFrameRange(c.start,c.end),this.duration=(c.end-c.start)/b*1E3,this.time=0):THREE.warn("THREE.MorphAnimMesh: animation["+a+"] undefined in .playAnimation()")}; THREE.MorphAnimMesh.prototype.updateAnimation=function(a){var b=this.duration/this.length;this.time+=this.direction*a;if(this.mirroredLoop){if(this.time>this.duration||0>this.time)this.direction*=-1,this.time>this.duration&&(this.time=this.duration,this.directionBackwards=!0),0>this.time&&(this.time=0,this.directionBackwards=!1)}else this.time%=this.duration,0>this.time&&(this.time+=this.duration);a=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/b),0,this.length-1);a!==this.currentKeyframe&& (this.morphTargetInfluences[this.lastKeyframe]=0,this.morphTargetInfluences[this.currentKeyframe]=1,this.morphTargetInfluences[a]=0,this.lastKeyframe=this.currentKeyframe,this.currentKeyframe=a);b=this.time%b/b;this.directionBackwards&&(b=1-b);this.morphTargetInfluences[this.currentKeyframe]=b;this.morphTargetInfluences[this.lastKeyframe]=1-b}; THREE.MorphAnimMesh.prototype.interpolateTargets=function(a,b,c){for(var d=this.morphTargetInfluences,e=0,f=d.length;eV;V++)ra=M[V],Va[Ya]=ra.x,Va[Ya+1]=ra.y,Va[Ya+2]=ra.z,Ya+=3;else for(V=0;3>V;V++)Va[Ya]=Q.x,Va[Ya+1]= +u.__webglSkinWeightsBuffer),l.bufferData(l.ARRAY_BUFFER,Ka,C))}if(Pb){y=0;for(z=Y.length;yV;V++)ra=L[V],Va[Ya]=ra.x,Va[Ya+1]=ra.y,Va[Ya+2]=ra.z,Ya+=3;else for(V=0;3>V;V++)Va[Ya]=Q.x,Va[Ya+1]= Q.y,Va[Ya+2]=Q.z,Ya+=3;l.bindBuffer(l.ARRAY_BUFFER,u.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Va,C)}if(Bb&&lb){y=0;for(z=Y.length;yV;V++)na=T[V],Ra[rb]=na.x,Ra[rb+1]=na.y,rb+=2;0V;V++)cb=R[V],sb[xa]=cb.x,sb[xa+1]=cb.y,xa+=2;0ta;ta++)mb[ta]=!B.autoScaleCubemaps||ba||zb?zb?la.image[ta].image:la.image[ta]:M(la.image[ta],Gc);var Rb=mb[0],Ob=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height), -nb=T(la.format),Sb=T(la.type);z(l.TEXTURE_CUBE_MAP,la,Ob);for(ta=0;6>ta;ta++)if(ba)for(var fb,Eb=mb[ta].mipmaps,Ab=0,Yb=Eb.length;Ab=sc&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Kb+=1;return a}function A(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function F(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a){a*=Q;a!==tc&&(l.lineWidth(a), -tc=a)}function E(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function z(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,T(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,T(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,T(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,T(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&& -b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT is set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,L(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,L(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter is set to THREE.LinearFilter or THREE.NearestFilter. ( "+ -b.sourceFile+" )"));(c=$.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height, -0,0,d.width,d.height);console.log("THREE.WebGLRenderer:",a,"is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height+".");return d}return a}function J(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, -l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function K(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function L(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? +(la.addEventListener("dispose",Gb),la.image.__webglTextureCube=l.createTexture(),B.info.memory.textures++);l.activeTexture(l.TEXTURE0+Db);l.bindTexture(l.TEXTURE_CUBE_MAP,la.image.__webglTextureCube);l.pixelStorei(l.UNPACK_FLIP_Y_WEBGL,la.flipY);for(var ba=la instanceof THREE.CompressedTexture,zb=la.image[0]instanceof THREE.DataTexture,mb=[],ta=0;6>ta;ta++)mb[ta]=!B.autoScaleCubemaps||ba||zb?zb?la.image[ta].image:la.image[ta]:L(la.image[ta],Gc);var Rb=mb[0],Ob=THREE.Math.isPowerOfTwo(Rb.width)&&THREE.Math.isPowerOfTwo(Rb.height), +nb=T(la.format),Sb=T(la.type);z(l.TEXTURE_CUBE_MAP,la,Ob);for(ta=0;6>ta;ta++)if(ba)for(var fb,Eb=mb[ta].mipmaps,Ab=0,Yb=Eb.length;Ab=sc&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Kb+=1;return a}function A(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function F(a,b,c,d){a[b]=c.r*d; +a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a){a*=Q;a!==tc&&(l.lineWidth(a),tc=a)}function E(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function z(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,T(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,T(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,T(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,T(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE), +l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,K(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,K(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+ +b.sourceFile+" )"));(c=$.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height, +0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function J(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER, +l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function M(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function K(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? l.NEAREST:l.LINEAR}function T(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a=== THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT; if(a===THREE.FloatType)return l.FLOAT;b=$.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return l.ALPHA;if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT; @@ -519,60 +523,60 @@ a.context?a.context:null,Q=1,U=void 0!==a.precision?a.precision:"highp",I=void 0 this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,cb=[],Wb=null,ob=null,Bb=-1,La="", Fb=null,Kb=0,pb=-1,Nb=-1,Xb=-1,Ob=-1,Yb=-1,Zb=-1,ec=-1,fc=-1,gc=-1,hc=-1,ic=-1,uc=null,vc=null,wc=null,tc=null,gb=0,db=0,hb=P.width,Qa=P.height,xc=0,yc=0,ub=new Uint8Array(16),Ra=new Uint8Array(16),vb=new THREE.Frustum,wb=new THREE.Matrix4;new THREE.Matrix4;var Ca=new THREE.Vector3,ma=new THREE.Vector3,Mb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[], anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},l;try{var zc={alpha:I,depth:na,stencil:ca,antialias:sa,premultipliedAlpha:R,preserveDrawingBuffer:xa};l=N||P.getContext("webgl",zc)||P.getContext("experimental-webgl",zc);if(null===l){if(null!==P.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}P.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();za={}}, -!1)}catch(Hc){console.error(Hc)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var $=new THREE.WebGLExtensions(l);$.get("OES_texture_float");$.get("OES_texture_float_linear");$.get("OES_texture_half_float");$.get("OES_texture_half_float_linear");$.get("OES_standard_derivatives");ra&&$.get("EXT_frag_depth");var jc=function(a,b,c,d){!0===R&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1); -l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND);l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(gb,db,hb,Qa);jc(ja.r,ja.g,ja.b,wa)},Ac=function(){Fb=Wb=null;Nb=pb=ic=hc=Xb=-1;La="";Bb=-1;Mb=!0;for(var a=0;ab;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b= -"__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mb;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--}, +pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."), +q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0, -h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),z(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture, -0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a? -(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=hb,a=Qa,d=gb,e=db);b!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),ob=b);xc=c;yc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); -else{var g=!1;a.__webglFramebuffer!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)===l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,ob)}};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}; -this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +a.image=L(a.image,Jc);var b=a.image,c=THREE.Math.isPowerOfTwo(b.width)&&THREE.Math.isPowerOfTwo(b.height),d=T(a.format),e=T(a.type);z(l.TEXTURE_2D,a,c);var f=a.mipmaps;if(a instanceof THREE.DataTexture)if(0f;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER, +l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),z(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0, +d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER, +null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=hb,a=Qa,d=gb,e=db);b!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),ob=b);xc=c;yc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); +else{var g=!1;a.__webglFramebuffer!==ob&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)===l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,ob)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}; +this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; a.shareDepthFrom=this.shareDepthFrom;return a},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube.prototype.constructor=THREE.WebGLRenderTargetCube; THREE.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c])return b[c];var d;switch(c){case "EXT_texture_filter_anisotropic":d=a.getExtension("EXT_texture_filter_anisotropic")||a.getExtension("MOZ_EXT_texture_filter_anisotropic")||a.getExtension("WEBKIT_EXT_texture_filter_anisotropic");break;case "WEBGL_compressed_texture_s3tc":d=a.getExtension("WEBGL_compressed_texture_s3tc")||a.getExtension("MOZ_WEBGL_compressed_texture_s3tc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc"); -break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;default:d=a.getExtension(c)}null===d&&console.log("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}; +break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;default:d=a.getExtension(c)}null===d&&THREE.warn("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}; THREE.WebGLProgram=function(){var a=0;return function(b,c,d,e){var f=b.context,g=d.defines,h=d.__webglShader.uniforms,k=d.attributes,p=d.__webglShader.vertexShader,n=d.__webglShader.fragmentShader,q=d.index0AttributeName;void 0===q&&!0===e.morphTargets&&(q="position");var m="SHADOWMAP_TYPE_BASIC";e.shadowMapType===THREE.PCFShadowMap?m="SHADOWMAP_TYPE_PCF":e.shadowMapType===THREE.PCFSoftShadowMap&&(m="SHADOWMAP_TYPE_PCF_SOFT");var s="ENVMAP_TYPE_CUBE",t="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY"; if(e.envMap){switch(d.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:s="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:s="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:s="ENVMAP_TYPE_SPHERE"}switch(d.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:t="ENVMAP_MODE_REFRACTION"}switch(d.combine){case THREE.MultiplyOperation:r="ENVMAP_BLENDING_MULTIPLY"; break;case THREE.MixOperation:r="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:r="ENVMAP_BLENDING_ADD"}}var u=0T;T++)M[T]=new THREE.Vector3,E[T]=new THREE.Vector3;M=z.shadowCascadeNearZ[L];z=z.shadowCascadeFarZ[L];E[0].set(-1,-1,M);E[1].set(1,-1,M);E[2].set(-1,1,M);E[3].set(1,1,M);E[4].set(-1,-1,z);E[5].set(1,-1,z);E[6].set(-1,1,z);E[7].set(1,1,z);K.originalCamera=u;E=new THREE.Gyroscope;E.position.copy(A.shadowCascadeOffset);E.add(K);E.add(K.target);u.add(E);A.shadowCascadeArray[G]=K;console.log("Created virtualLight",K)}L= -A;M=G;z=L.shadowCascadeArray[M];z.position.copy(L.position);z.target.position.copy(L.target.position);z.lookAt(z.target);z.shadowCameraVisible=L.shadowCameraVisible;z.shadowDarkness=L.shadowDarkness;z.shadowBias=L.shadowCascadeBias[M];E=L.shadowCascadeNearZ[M];L=L.shadowCascadeFarZ[M];z=z.pointsFrustum;z[0].z=E;z[1].z=E;z[2].z=E;z[3].z=E;z[4].z=L;z[5].z=L;z[6].z=L;z[7].z=L;J[F]=K;F++}else J[F]=A,F++;v=0;for(y=J.length;vL;L++)M=z[L],M.copy(E[L]),M.unproject(G),M.applyMatrix4(F.matrixWorldInverse),M.xs.x&&(s.x=M.x),M.ys.y&&(s.y=M.y),M.zs.z&&(s.z=M.z);F.left=m.x;F.right=s.x;F.top=s.y;F.bottom=m.y;F.updateProjectionMatrix()}F=A.shadowMap;E=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);t.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(t);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& -(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();E.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);E.multiply(G.projectionMatrix);E.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);n.setFromMatrix(q);a.setRenderTarget(F);a.clear();r.length=0;e(c,c,G);A=0;for(F=r.length;AT;T++)L[T]=new THREE.Vector3,E[T]=new THREE.Vector3;L=z.shadowCascadeNearZ[K];z=z.shadowCascadeFarZ[K];E[0].set(-1,-1,L);E[1].set(1,-1,L);E[2].set(-1,1,L);E[3].set(1,1,L);E[4].set(-1,-1,z);E[5].set(1,-1,z);E[6].set(-1,1,z);E[7].set(1,1,z);M.originalCamera=u;E=new THREE.Gyroscope;E.position.copy(A.shadowCascadeOffset);E.add(M);E.add(M.target);u.add(E);A.shadowCascadeArray[G]=M}K=A;L=G;z=K.shadowCascadeArray[L];z.position.copy(K.position); +z.target.position.copy(K.target.position);z.lookAt(z.target);z.shadowCameraVisible=K.shadowCameraVisible;z.shadowDarkness=K.shadowDarkness;z.shadowBias=K.shadowCascadeBias[L];E=K.shadowCascadeNearZ[L];K=K.shadowCascadeFarZ[L];z=z.pointsFrustum;z[0].z=E;z[1].z=E;z[2].z=E;z[3].z=E;z[4].z=K;z[5].z=K;z[6].z=K;z[7].z=K;J[F]=M;F++}else J[F]=A,F++;v=0;for(y=J.length;v +K;K++)L=z[K],L.copy(E[K]),L.unproject(G),L.applyMatrix4(F.matrixWorldInverse),L.xs.x&&(s.x=L.x),L.ys.y&&(s.y=L.y),L.zs.z&&(s.z=L.z);F.left=m.x;F.right=s.x;F.top=s.y;F.bottom=m.y;F.updateProjectionMatrix()}F=A.shadowMap;E=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);t.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(t);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& +(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();E.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);E.multiply(G.projectionMatrix);E.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);n.setFromMatrix(q);a.setRenderTarget(F);a.clear();r.length=0;e(c,c,G);A=0;for(F=r.length;A 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); -w.compileShader(T);w.compileShader(P);w.attachShader(L,T);w.attachShader(L,P);w.linkProgram(L);F=L;v=w.getAttribLocation(F,"position");x=w.getAttribLocation(F,"uv");c=w.getUniformLocation(F,"uvOffset");d=w.getUniformLocation(F,"uvScale");e=w.getUniformLocation(F,"rotation");f=w.getUniformLocation(F,"scale");g=w.getUniformLocation(F,"color");h=w.getUniformLocation(F,"map");k=w.getUniformLocation(F,"opacity");p=w.getUniformLocation(F,"modelViewMatrix");n=w.getUniformLocation(F,"projectionMatrix");q= -w.getUniformLocation(F,"fogType");m=w.getUniformLocation(F,"fogDensity");s=w.getUniformLocation(F,"fogNear");t=w.getUniformLocation(F,"fogFar");r=w.getUniformLocation(F,"fogColor");u=w.getUniformLocation(F,"alphaTest");L=document.createElement("canvas");L.width=8;L.height=8;T=L.getContext("2d");T.fillStyle="white";T.fillRect(0,0,8,8);G=new THREE.Texture(L);G.needsUpdate=!0}w.useProgram(F);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, -y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(n,!1,K.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);T=L=0;(P=J.fog)?(w.uniform3f(r,P.color.r,P.color.g,P.color.b),P instanceof THREE.Fog?(w.uniform1f(s,P.near),w.uniform1f(t,P.far),w.uniform1i(q,1),T=L=1):P instanceof THREE.FogExp2&&(w.uniform1f(m,P.density),w.uniform1i(q,2),T=L=2)):(w.uniform1i(q,0),T=L=0);for(var P=0,N=b.length;P< -N;P++){var Q=b[P];Q._modelViewMatrix.multiplyMatrices(K.matrixWorldInverse,Q.matrixWorld);Q.z=-Q._modelViewMatrix.elements[14]}b.sort(C);for(var U=[],P=0,N=b.length;Pq-1?0:q-1,s=q+1>e-1?e-1:q+1,t=0>n-1?0:n-1,r=n+1>d-1?d-1:n+1,u=[],v=[0,0,h[4*(q*d+n)]/255*b];u.push([-1,0,h[4*(q*d+t)]/255*b]);u.push([-1,-1,h[4*(m*d+t)]/255*b]);u.push([0,-1,h[4*(m*d+n)]/255*b]);u.push([1,-1,h[4*(m*d+r)]/255*b]);u.push([1,0,h[4*(q*d+r)]/255*b]);u.push([1,1,h[4*(s*d+r)]/255*b]);u.push([0,1,h[4*(s*d+n)]/255* b]);u.push([-1,1,h[4*(s*d+t)]/255*b]);m=[];t=u.length;for(s=0;se)return null;var f=[],g=[],h=[],k,p,n;if(0=q--){console.log("Warning, unable to triangulate polygon!");break}k=p;e<=k&&(k=0);p=k+1;e<=p&&(p=0);n=p+1;e<=n&&(n=0);var m;a:{var s=m=void 0,t=void 0,r=void 0,u=void 0,v=void 0,x=void 0,C=void 0,w=void 0, -s=a[g[k]].x,t=a[g[k]].y,r=a[g[p]].x,u=a[g[p]].y,v=a[g[n]].x,x=a[g[n]].y;if(1E-10>(r-s)*(x-t)-(u-t)*(v-s))m=!1;else{var y=void 0,A=void 0,F=void 0,G=void 0,E=void 0,z=void 0,M=void 0,J=void 0,K=void 0,L=void 0,K=J=M=w=C=void 0,y=v-r,A=x-u,F=s-v,G=t-x,E=r-s,z=u-t;for(m=0;me)return null;var f=[],g=[],h=[],k,p,n;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=p;e<=k&&(k=0);p=k+1;e<=p&&(p=0);n=p+1;e<=n&&(n=0);var m;a:{var s=m=void 0,t=void 0,r=void 0, +u=void 0,v=void 0,x=void 0,C=void 0,w=void 0,s=a[g[k]].x,t=a[g[k]].y,r=a[g[p]].x,u=a[g[p]].y,v=a[g[n]].x,x=a[g[n]].y;if(1E-10>(r-s)*(x-t)-(u-t)*(v-s))m=!1;else{var y=void 0,A=void 0,F=void 0,G=void 0,E=void 0,z=void 0,L=void 0,J=void 0,M=void 0,K=void 0,M=J=L=w=C=void 0,y=v-r,A=x-u,F=s-v,G=t-x,E=r-s,z=u-t;for(m=0;mk)g=d+1;else if(0b&&(b=0);1G||G>F)return[];k=n*p-k*q;if(0>k||k>F)return[]}else{if(0d?[]:k==d?f?[]:[g]:a<=d?[g,h]: -[g,n]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]);if(!d)return!1; -d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;cL){console.log("Infinite Loop! Holes left:"+ -n.length+", Probably Hole outside Shape!");break}for(q=z;qh;h++)p=k[h].x+":"+k[h].y, -p=n[p],void 0!==p&&(k[h]=p);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a, -b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)};THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()}; -THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve;THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b=new THREE.Vector2;b.x=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);return b}; -THREE.QuadraticBezierCurve.prototype.getTangent=function(a){var b=new THREE.Vector2;b.x=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.y,this.v1.y,this.v2.y);return b.normalize()};THREE.CubicBezierCurve=function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d};THREE.CubicBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.CubicBezierCurve.prototype.constructor=THREE.CubicBezierCurve; -THREE.CubicBezierCurve.prototype.getPoint=function(a){var b;b=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);a=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);return new THREE.Vector2(b,a)};THREE.CubicBezierCurve.prototype.getTangent=function(a){var b;b=THREE.Curve.Utils.tangentCubicBezier(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);a=THREE.Curve.Utils.tangentCubicBezier(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);b=new THREE.Vector2(b,a);b.normalize();return b}; -THREE.SplineCurve=function(a){this.points=void 0==a?[]:a};THREE.SplineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.SplineCurve.prototype.constructor=THREE.SplineCurve; +[g,n]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]); +if(!d)return!1;d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c +K){console.log("Infinite Loop! Holes left:"+n.length+", Probably Hole outside Shape!");break}for(q=z;qh;h++)p=k[h].x+":"+k[h].y,p=n[p],void 0!==p&&(k[h]=p);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a* +a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)}; +THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()};THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve; +THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b=new THREE.Vector2;b.x=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);return b};THREE.QuadraticBezierCurve.prototype.getTangent=function(a){var b=new THREE.Vector2;b.x=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.y,this.v1.y,this.v2.y);return b.normalize()}; +THREE.CubicBezierCurve=function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d};THREE.CubicBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.CubicBezierCurve.prototype.constructor=THREE.CubicBezierCurve;THREE.CubicBezierCurve.prototype.getPoint=function(a){var b;b=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);a=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);return new THREE.Vector2(b,a)}; +THREE.CubicBezierCurve.prototype.getTangent=function(a){var b;b=THREE.Curve.Utils.tangentCubicBezier(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);a=THREE.Curve.Utils.tangentCubicBezier(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);b=new THREE.Vector2(b,a);b.normalize();return b};THREE.SplineCurve=function(a){this.points=void 0==a?[]:a};THREE.SplineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.SplineCurve.prototype.constructor=THREE.SplineCurve; THREE.SplineCurve.prototype.getPoint=function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0==c?c:c-1],e=b[c],f=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=new THREE.Vector2;c.x=THREE.Curve.Utils.interpolate(d.x,e.x,f.x,b.x,a);c.y=THREE.Curve.Utils.interpolate(d.y,e.y,f.y,b.y,a);return c};THREE.EllipseCurve=function(a,b,c,d,e,f,g){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=g}; THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype);THREE.EllipseCurve.prototype.constructor=THREE.EllipseCurve;THREE.EllipseCurve.prototype.getPoint=function(a){var b=this.aEndAngle-this.aStartAngle;0>b&&(b+=2*Math.PI);b>2*Math.PI&&(b-=2*Math.PI);a=!0===this.aClockwise?this.aEndAngle+(1-a)*(2*Math.PI-b):this.aStartAngle+a*b;b=new THREE.Vector2;b.x=this.aX+this.xRadius*Math.cos(a);b.y=this.aY+this.yRadius*Math.sin(a);return b}; THREE.ArcCurve=function(a,b,c,d,e,f){THREE.EllipseCurve.call(this,a,b,c,c,d,e,f)};THREE.ArcCurve.prototype=Object.create(THREE.EllipseCurve.prototype);THREE.ArcCurve.prototype.constructor=THREE.ArcCurve;THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b}); @@ -684,7 +688,7 @@ THREE.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1 THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b=new THREE.Vector3;b.x=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);b.y=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);b.z=THREE.Shape.Utils.b3(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z);return b}); THREE.SplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0==c?c:c-1],e=b[c],f=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=new THREE.Vector3;c.x=THREE.Curve.Utils.interpolate(d.x,e.x,f.x,b.x,a);c.y=THREE.Curve.Utils.interpolate(d.y,e.y,f.y,b.y,a);c.z=THREE.Curve.Utils.interpolate(d.z,e.z,f.z,b.z,a);return c}); THREE.ClosedSplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-0;var c=Math.floor(a);a-=c;var c=c+(0a.hierarchy[b].keys[c].time&&(a.hierarchy[b].keys[c].time= +THREE.AnimationHandler={LINEAR:0,CATMULLROM:1,CATMULLROM_FORWARD:2,add:function(){THREE.warn("THREE.AnimationHandler.add() has been deprecated.")},get:function(){THREE.warn("THREE.AnimationHandler.get() has been deprecated.")},remove:function(){THREE.warn("THREE.AnimationHandler.remove() has been deprecated.")},animations:[],init:function(a){if(!0===a.initialized)return a;for(var b=0;ba.hierarchy[b].keys[c].time&&(a.hierarchy[b].keys[c].time= 0),void 0!==a.hierarchy[b].keys[c].rot&&!(a.hierarchy[b].keys[c].rot instanceof THREE.Quaternion)){var d=a.hierarchy[b].keys[c].rot;a.hierarchy[b].keys[c].rot=(new THREE.Quaternion).fromArray(d)}if(a.hierarchy[b].keys.length&&void 0!==a.hierarchy[b].keys[0].morphTargets){d={};for(c=0;c=this.currentTime?f.interpolate(g,this.currentTime):f.inter THREE.KeyFrameAnimation.prototype.getPrevKeyWith=function(a,b,c){b=this.data.hierarchy[b].keys;for(c=0<=c?c:c+b.length;0<=c;c--)if(b[c].hasTarget(a))return b[c];return b[b.length-1]};THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);a=this.duration/this.frames;var b=Math.floor(this.currentTime/a);b!=this.currentFrame&&(this.mesh.morphTargetInfluences[this.lastFrame]=0,this.mesh.morphTargetInfluences[this.currentFrame]= 1,this.mesh.morphTargetInfluences[b]=0,this.lastFrame=this.currentFrame,this.currentFrame=b);this.mesh.morphTargetInfluences[b]=this.currentTime%a/a;this.mesh.morphTargetInfluences[this.lastFrame]=1-this.mesh.morphTargetInfluences[b]}}}; -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,r){var u,v=h.widthSegments,x=h.heightSegments,C=e/2,w=f/2,y=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",x=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",v=h.depthSegments;var A=v+1,F=x+1,G=e/v,E=f/x,z=new THREE.Vector3;z[u]=0=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)== -Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(R=a.length;0<=--R;){c=R;d=R-1;0>d&&(d=a.length-1);for(var e=0,f=s+2*n,e=0;e=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(R=a.length;0<=--R;){c=R;d=R-1;0>d&&(d=a.length-1);for(var e=0,f=s+2*n,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;ct;t++){d[0]=s[g[t]];d[1]=s[g[(t+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1],face1:q,face2:void 0},n++):e[r].face2=q}d=new Float32Array(6*n);f=0;for(r in e)if(g=e[r],void 0===g.face2|| -.9999>k[g.face1].normal.dot(k[g.face2].normal))n=p[g.vert1],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z,n=p[g.vert2],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype);THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper; -THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=new THREE.Geometry;c=0;for(var e=this.object.geometry.faces.length;ct;t++){d[0]=s[g[t]];d[1]=s[g[(t+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1], +face1:q,face2:void 0},n++):e[r].face2=q}d=new Float32Array(6*n);f=0;for(r in e)if(g=e[r],void 0===g.face2||.9999>k[g.face1].normal.dot(k[g.face2].normal))n=p[g.vert1],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z,n=p[g.vert2],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype); +THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper;THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=new THREE.Geometry;c=0;for(var e=this.object.geometry.faces.length;ch.end&&(h.end=f);c||(c=k)}}for(k in d)h=d[k],this.createAnimation(k,h.start,h.end,a);this.firstAnimation=c}; THREE.MorphBlendMesh.prototype.setAnimationDirectionForward=function(a){if(a=this.animationsMap[a])a.direction=1,a.directionBackwards=!1};THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward=function(a){if(a=this.animationsMap[a])a.direction=-1,a.directionBackwards=!0};THREE.MorphBlendMesh.prototype.setAnimationFPS=function(a,b){var c=this.animationsMap[a];c&&(c.fps=b,c.duration=(c.end-c.start)/c.fps)}; THREE.MorphBlendMesh.prototype.setAnimationDuration=function(a,b){var c=this.animationsMap[a];c&&(c.duration=b,c.fps=(c.end-c.start)/c.duration)};THREE.MorphBlendMesh.prototype.setAnimationWeight=function(a,b){var c=this.animationsMap[a];c&&(c.weight=b)};THREE.MorphBlendMesh.prototype.setAnimationTime=function(a,b){var c=this.animationsMap[a];c&&(c.time=b)};THREE.MorphBlendMesh.prototype.getAnimationTime=function(a){var b=0;if(a=this.animationsMap[a])b=a.time;return b}; -THREE.MorphBlendMesh.prototype.getAnimationDuration=function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};THREE.MorphBlendMesh.prototype.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):console.warn("animation["+a+"] undefined")};THREE.MorphBlendMesh.prototype.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1}; +THREE.MorphBlendMesh.prototype.getAnimationDuration=function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};THREE.MorphBlendMesh.prototype.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):THREE.warn("THREE.MorphBlendMesh: animation["+a+"] undefined in .playAnimation()")};THREE.MorphBlendMesh.prototype.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1}; THREE.MorphBlendMesh.prototype.update=function(a){for(var b=0,c=this.animationsList.length;bd.duration||0>d.time)d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time&&(d.time=0,d.directionBackwards=!1)}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.startFrame+THREE.Math.clamp(Math.floor(d.time/e),0,d.length-1),g=d.weight; f!==d.currentFrame&&(this.morphTargetInfluences[d.lastFrame]=0,this.morphTargetInfluences[d.currentFrame]=1*g,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);this.morphTargetInfluences[d.currentFrame]=e*g;this.morphTargetInfluences[d.lastFrame]=(1-e)*g}}}; diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 2daab175417fca..4842bd410ca0c4 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -693,12 +693,7 @@ THREE.Object3D.prototype = { data.color = object.color.getHex(); data.groundColor = object.groundColor.getHex(); - } else if ( object instanceof THREE.Mesh || object instanceof THREE.PointCloud ) { - - data.geometry = parseGeometry( object.geometry ); - data.material = parseMaterial( object.material ); - - } else if ( object instanceof THREE.Line ) { + } else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.PointCloud ) { data.geometry = parseGeometry( object.geometry ); data.material = parseMaterial( object.material ); From 9566ec9da2355f3fe4370c52335a21cabfc5f420 Mon Sep 17 00:00:00 2001 From: repsac Date: Tue, 17 Feb 2015 18:40:25 -0800 Subject: [PATCH 141/333] Testing out normalization of quaternion values --- .../blender/addons/io_three/__init__.py | 2 +- .../addons/io_three/exporter/api/animation.py | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 2c6da580f331e8..55b394c13b85c1 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -41,7 +41,7 @@ bl_info = { 'name': "Three.js Format", 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", - 'version': (1, 2, 3), + 'version': (1, 2, 4), 'blender': (2, 7, 3), 'location': "File > Export", 'description': "Export Three.js formatted JSON files.", diff --git a/utils/exporters/blender/addons/io_three/exporter/api/animation.py b/utils/exporters/blender/addons/io_three/exporter/api/animation.py index f51c085cffda9c..76119d6cdaadab 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/animation.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/animation.py @@ -1,3 +1,4 @@ +import math import mathutils from bpy import data, context from .. import constants, logger, utilities @@ -274,6 +275,7 @@ def find_keyframe_at(channel, frame): bone_matrix = parent_matrix.inverted() * bone_matrix pos, rot, scl = bone_matrix.decompose() + rot = _normalize_quaternion(rot) pchange = True or has_keyframe_at( channels_location[bone_index], frame) @@ -569,3 +571,34 @@ def _handle_position_channel(channel, frame, position): position.z = value return change + + +def _quaternion_length(quat): + """Calculate the length of a quaternion + + :param quat: Blender quaternion object + :rtype: float + + """ + return math.sqrt(quat.x * quat.x + quat.y * quat.y + + quat.z * quat.z + quat.w * quat.w) + + +def _normalize_quaternion(quat): + """Normalize a quaternion + + :param quat: Blender quaternion object + :returns: generic quaternion enum object with normalized values + :rtype: object + + """ + enum = type('Enum', (), {'x': 0, 'y': 0, 'z': 0, 'w': 1}) + length = _quaternion_length(quat) + if length is not 0: + length = 1 / length + enum.x = quat.x * length + enum.y = quat.y * length + enum.z = quat.z * length + enum.w = quat.w * length + return enum + From c512ee3f3d04e46e25cd62c849f1acdd333802df Mon Sep 17 00:00:00 2001 From: erichlof Date: Tue, 17 Feb 2015 23:08:47 -0600 Subject: [PATCH 142/333] Update ShadowMesh.js --- src/objects/ShadowMesh.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objects/ShadowMesh.js b/src/objects/ShadowMesh.js index f71b392a223488..f4fbf15b0466d1 100644 --- a/src/objects/ShadowMesh.js +++ b/src/objects/ShadowMesh.js @@ -19,7 +19,7 @@ THREE.ShadowMesh = function ( mesh ) { THREE.Mesh.call( this, mesh.geometry, shadowMaterial ); - this.parentMeshMatrix = mesh.matrixWorld; + this.meshMatrix = mesh.matrixWorld; this.frustumCulled = false; @@ -64,7 +64,7 @@ THREE.ShadowMesh.prototype.update = function () { sme[ 11 ] = - lightPosition4D.w * plane.normal.z; sme[ 15 ] = dot - lightPosition4D.w * -plane.constant; - this.matrix.multiplyMatrices( shadowMatrix, this.parentMeshMatrix ); + this.matrix.multiplyMatrices( shadowMatrix, this.meshMatrix ); }; From d032c716536640e6c5987853b6521a9cfb257102 Mon Sep 17 00:00:00 2001 From: erichlof Date: Tue, 17 Feb 2015 23:10:49 -0600 Subject: [PATCH 143/333] Update ShadowMesh.js --- src/objects/ShadowMesh.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects/ShadowMesh.js b/src/objects/ShadowMesh.js index f4fbf15b0466d1..1ff5768d96a20f 100644 --- a/src/objects/ShadowMesh.js +++ b/src/objects/ShadowMesh.js @@ -4,7 +4,7 @@ * @author erichlof / http://github.com/erichlof */ -// a shadow Mesh that follows its parent Mesh in the scene, but is confined to a single plane. +// a shadow Mesh that follows a shadow-casting Mesh in the scene, but is confined to a single plane. THREE.ShadowMesh = function ( mesh ) { From a66add5d9aa31015c1ccaf72195c2af348b8943a Mon Sep 17 00:00:00 2001 From: makc Date: Wed, 18 Feb 2015 17:09:08 +0100 Subject: [PATCH 144/333] missing type on Bone --- src/objects/Bone.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objects/Bone.js b/src/objects/Bone.js index 9849d505ecbee9..5ef559c8bc523b 100644 --- a/src/objects/Bone.js +++ b/src/objects/Bone.js @@ -10,6 +10,7 @@ THREE.Bone = function ( belongsToSkin ) { this.skin = belongsToSkin; + this.type = 'Bone'; }; THREE.Bone.prototype = Object.create( THREE.Object3D.prototype ); From 6f9491163d129e526664550b9a6dc5513baa26af Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 18 Feb 2015 14:53:52 -0800 Subject: [PATCH 145/333] ObjectLoader: Fixed empty images. See fcf54cd2ed3b9097126c3f6b4fc5764a07f5195e. --- src/loaders/ObjectLoader.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index df9eaf8ca53de4..6e4e9272843664 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -289,25 +289,23 @@ THREE.ObjectLoader.prototype = { var loader = new THREE.ImageLoader( manager ); loader.setCrossOrigin( this.crossOrigin ); - var loadImage = function ( data ) { - - var url = scope.texturePath + data.url; + var loadImage = function ( url ) { scope.manager.itemStart( url ); - loader.load( url, function ( image ) { + return loader.load( url, function () { scope.manager.itemEnd( url ); - images[ data.uuid ] = image; - } ); }; for ( var i = 0, l = json.length; i < l; i ++ ) { - loadImage( json[ i ] ); + var image = json[ i ]; + + images[ image.uuid ] = loadImage( scope.texturePath + image.url ); } From 0391e8f32a08182e7b0f43d225f581ecdfb5c1ff Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 18 Feb 2015 14:55:47 -0800 Subject: [PATCH 146/333] Updated builds. --- build/three.js | 12 +++++------- build/three.min.js | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/build/three.js b/build/three.js index fe2ad654260985..7af6324412ecd0 100644 --- a/build/three.js +++ b/build/three.js @@ -12873,25 +12873,23 @@ THREE.ObjectLoader.prototype = { var loader = new THREE.ImageLoader( manager ); loader.setCrossOrigin( this.crossOrigin ); - var loadImage = function ( data ) { - - var url = scope.texturePath + data.url; + var loadImage = function ( url ) { scope.manager.itemStart( url ); - loader.load( url, function ( image ) { + return loader.load( url, function () { scope.manager.itemEnd( url ); - images[ data.uuid ] = image; - } ); }; for ( var i = 0, l = json.length; i < l; i ++ ) { - loadImage( json[ i ] ); + var image = json[ i ]; + + images[ image.uuid ] = loadImage( scope.texturePath + image.url ); } diff --git a/build/three.min.js b/build/three.min.js index e5e4c3d84d674d..012f59827f4f48 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -283,7 +283,7 @@ d),d=this.parseMaterials(a.materials,d);return this.parseObject(a.object,c,d)},p new THREE.CircleGeometry(h.radius,h.segments);break;case "CylinderGeometry":g=new THREE.CylinderGeometry(h.radiusTop,h.radiusBottom,h.height,h.radialSegments,h.heightSegments,h.openEnded);break;case "SphereGeometry":g=new THREE.SphereGeometry(h.radius,h.widthSegments,h.heightSegments,h.phiStart,h.phiLength,h.thetaStart,h.thetaLength);break;case "IcosahedronGeometry":g=new THREE.IcosahedronGeometry(h.radius,h.detail);break;case "TorusGeometry":g=new THREE.TorusGeometry(h.radius,h.tube,h.radialSegments, h.tubularSegments,h.arc);break;case "TorusKnotGeometry":g=new THREE.TorusKnotGeometry(h.radius,h.tube,h.radialSegments,h.tubularSegments,h.p,h.q,h.heightScale);break;case "BufferGeometry":g=d.parse(h.data);break;case "Geometry":g=c.parse(h.data).geometry}g.uuid=h.uuid;void 0!==h.name&&(g.name=h.name);b[h.uuid]=g}return b},parseMaterials:function(a,b){var c={};if(void 0!==a)for(var d=function(a){void 0===b[a]&&THREE.warn("THREE.ObjectLoader: Undefined texture",a);return b[a]},e=new THREE.MaterialLoader, f=0,g=a.length;f Date: Wed, 18 Feb 2015 15:10:57 -0800 Subject: [PATCH 147/333] Bone: Clean up. --- src/objects/Bone.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objects/Bone.js b/src/objects/Bone.js index 5ef559c8bc523b..daa4c7a5153885 100644 --- a/src/objects/Bone.js +++ b/src/objects/Bone.js @@ -4,15 +4,15 @@ * @author ikerr / http://verold.com */ -THREE.Bone = function ( belongsToSkin ) { +THREE.Bone = function ( skin ) { THREE.Object3D.call( this ); - this.skin = belongsToSkin; - this.type = 'Bone'; + + this.skin = skin; + }; THREE.Bone.prototype = Object.create( THREE.Object3D.prototype ); THREE.Bone.prototype.constructor = THREE.Bone; - From 88dd3d95f3d08b1aeb13c2262120b82fa269fc9a Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 18 Feb 2015 15:11:14 -0800 Subject: [PATCH 148/333] Updated builds. --- build/three.js | 7 ++++--- build/three.min.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build/three.js b/build/three.js index 7af6324412ecd0..077b2a886df53f 100644 --- a/build/three.js +++ b/build/three.js @@ -15573,18 +15573,19 @@ THREE.Mesh.prototype.clone = function ( object, recursive ) { * @author ikerr / http://verold.com */ -THREE.Bone = function ( belongsToSkin ) { +THREE.Bone = function ( skin ) { THREE.Object3D.call( this ); - this.skin = belongsToSkin; + this.type = 'Bone'; + + this.skin = skin; }; THREE.Bone.prototype = Object.create( THREE.Object3D.prototype ); THREE.Bone.prototype.constructor = THREE.Bone; - // File:src/objects/Skeleton.js /** diff --git a/build/three.min.js b/build/three.min.js index 012f59827f4f48..f5b6e24fc143bb 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -354,7 +354,7 @@ this.material;if(void 0!==p){var n=k.attributes,q,m,s=g.precision;if(void 0!==n. var A=g.ray.origin.distanceTo(y);Ag.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=n.position.array,t=k=0,w=r.length;k g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(t=this.material instanceof THREE.MeshFaceMaterial,r=!0===t?this.material.materials:null,s=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:C,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; +Ag.far||h.push({distance:A,point:y,face:C,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.type="Bone";this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(this.boneTextureHeight=this.boneTextureWidth=a=256 Date: Wed, 18 Feb 2015 15:45:40 -0800 Subject: [PATCH 149/333] Allow mouse wheel events through iframe in Mac Safari See issue#6074 See http://kb.tableau.com/articles/issue/scroll-bars-in-embedded-views-do-not-work-in-safari. --- examples/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/index.html b/examples/index.html index f603d31afe931f..d9bfdcf6badabb 100644 --- a/examples/index.html +++ b/examples/index.html @@ -183,7 +183,7 @@

three.js / examples

- + - - - - - -

[name]

- -
A loader for loading a [page:Scene] from a JSON resource.
- - -

Constructor

- -

[name]( [page:LoadingManager manager] )

-
- [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager]. -
-
- Creates a new [name]. -
- -

Properties

- - -

Methods

- -

[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )

-
- [page:String url] — required
- [page:Function onLoad] — Will be called when load completes. The argument will be an [page:Object] containing the loaded components.
- [page:Function onProgress] — Will be called while load progresses. The argument will be the XmlHttpRequest instance, that contain .[page:Integer total] and .[page:Integer loaded] bytes.
- [page:Function onError] — Will be called when load errors.
-
-
- Begin loading from url and call onLoad with the parsed scene. -
- -

[method:Object parse]( [page:Object json], [page:Function callbackFinished], [page:String url] )

-
- [page:Object json] — The JSON structure to parse.
- [page:Function callbackFinished] — Will be called when parse completes.
- [page:String url] — Will be used as base for assets' relative URLs.
-
-
- Parse a JSON scene description and return a new [page:Object] with fully instantiated Three.js objects. -
- -

[method:null setCrossOrigin]( [page:String value] )

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

[method:null addGeometryHandler]( [page:String typeID], [page:Function loaderClass] )

-
- [page:String typeID] — The type to handle.
- [page:Function loaderClass] — The handler class.
-
-
- Add an handler for a specific geometry type. -
- -

[method:null addHierarchyHandler]( [page:String typeID], [page:Function loaderClass] )

-
- [page:String typeID] — The type to handle.
- [page:Function loaderClass] — The handler class.
-
-
- Add an handler for a specific object type. -
- - -

Example

- - - // instantiate a loader - var loader = new THREE.SceneLoader(); - - // Handle STL geometries - loader.addGeometryHandler( "stl", THREE.STLLoader ); - - // Handle OBJ objects - loader.addHierarchyHandler( "obj", THREE.OBJLoader ); - - // load a JSON resource - loader.load( - // resource URL - 'scenes/test_scene.js', - // Function when resource is loaded - function ( result ) { - scene.add( result.scene ); - }, - // Function called when download progresses - function ( xhr ) { - console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); - }, - // Function called when download errors - function ( xhr ) { - console.log( 'An error happened' ); - } - ); - - - [example:webgl_loader_scene] - - -

Source

- - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/SceneLoader.js examples/js/loaders/SceneLoader.js] - - diff --git a/docs/list.js b/docs/list.js index 0c5258ac8a49e7..7a71ca4fe447e7 100644 --- a/docs/list.js +++ b/docs/list.js @@ -63,7 +63,6 @@ var list = { [ "ObjectLoader", "api/loaders/ObjectLoader" ], [ "PDBLoader", "api/loaders/PDBLoader" ], [ "SVGLoader", "api/loaders/SVGLoader" ], - [ "SceneLoader", "api/loaders/SceneLoader" ], [ "TextureLoader", "api/loaders/TextureLoader" ], [ "TGALoader", "api/loaders/TGALoader" ], [ "XHRLoader", "api/loaders/XHRLoader" ] diff --git a/editor/index.html b/editor/index.html index 69e361b686bfa5..51544dfce46c3c 100644 --- a/editor/index.html +++ b/editor/index.html @@ -19,7 +19,6 @@ - @@ -30,6 +29,8 @@ + + diff --git a/examples/js/loaders/SceneLoader.js b/examples/js/loaders/deprecated/SceneLoader.js similarity index 100% rename from examples/js/loaders/SceneLoader.js rename to examples/js/loaders/deprecated/SceneLoader.js diff --git a/examples/webgl_loader_scene.html b/examples/webgl_loader_scene.html index 92055ca3f6bb07..eb726d28b2045d 100644 --- a/examples/webgl_loader_scene.html +++ b/examples/webgl_loader_scene.html @@ -109,7 +109,7 @@ - + From e89ec85990bb0c2a24626232967fb841f51a1ff5 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 18 Feb 2015 16:49:02 -0800 Subject: [PATCH 153/333] Removed Sublime completions. Use https://github.com/mflux/threesublimecompletions instead. --- utils/editors/sublime.py | 65 -------- utils/editors/sublime.sh | 3 - utils/editors/sublimetext2/README.md | 9 -- .../sublimetext2/threejs.sublime-completions | 143 ------------------ 4 files changed, 220 deletions(-) delete mode 100644 utils/editors/sublime.py delete mode 100755 utils/editors/sublime.sh delete mode 100644 utils/editors/sublimetext2/README.md delete mode 100644 utils/editors/sublimetext2/threejs.sublime-completions diff --git a/utils/editors/sublime.py b/utils/editors/sublime.py deleted file mode 100644 index ce232456dc1cdb..00000000000000 --- a/utils/editors/sublime.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python - -import sys - -if sys.version_info < (2, 7): - print("This script requires at least Python 2.7.") - print("Please, update to a newer version: http://www.python.org/download/releases/") - exit() - -import argparse -import json -import os -import re -import shutil -import tempfile - - -def main(argv=None): - - parser = argparse.ArgumentParser() - parser.add_argument('--include', action='append', required=True) - parser.add_argument('--output', default='sublimetext2/threejs.sublime-completions') - - args = parser.parse_args() - - output = args.output - - # parsing - - print(' * Generating ' + output) - - fd, path = tempfile.mkstemp() - tmp = open(path, 'w') - tmp.write('{\n\t"scope": "source.js,source.js.embedded.html,source.coffee",\n\t"version": "r55",\n\t"completions":\n\t[\n') - - for include in args.include: - with open('../build/includes/' + include + '.json','r') as f: files = json.load(f) - for filename in files: - filename = '../../' + filename; - with open(filename, 'r') as f: - string = f.read() - match = re.search('THREE.(\w+)[\ ]+?=[\ ]+?function[\ ]+\(([\w\,\ ]+)?\)', string) - if match: - name = match.group(1) - parameters = match.group(2) - if parameters is None: - parameters = '' - else: - array = parameters.split( ',' ) - for i in range(len(array)): - array[i] = '${'+str(i+1)+':'+array[i].strip()+'}' # ${1:param} - parameters = ' '+', '.join(array)+' ' - tmp.write('\t\t{ "trigger": "THREE.'+name+'", "contents": "THREE.'+name+'('+parameters+')$0" },\n' ) - - tmp.write("\t\t\"THREE\"\n\t]\n}") - tmp.close() - - # save - - shutil.copy(path, output) - os.chmod(output, 0o664); # temp files would usually get 0600 - - -if __name__ == "__main__": - main() diff --git a/utils/editors/sublime.sh b/utils/editors/sublime.sh deleted file mode 100755 index 02d8d999366aad..00000000000000 --- a/utils/editors/sublime.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -python sublime.py --include common --include extras --output sublimetext2/threejs.sublime-completions diff --git a/utils/editors/sublimetext2/README.md b/utils/editors/sublimetext2/README.md deleted file mode 100644 index 518cf9d0cc1d33..00000000000000 --- a/utils/editors/sublimetext2/README.md +++ /dev/null @@ -1,9 +0,0 @@ -### How to install - -1. Compress `threejs.sublime-completions` into `threejs.sublime-package`. - -```shell -zip threejs.sublime-package threejs.sublime-completions -``` - -2. Copy the compressed file into `Sublime Text 2/Pristine Packages`. diff --git a/utils/editors/sublimetext2/threejs.sublime-completions b/utils/editors/sublimetext2/threejs.sublime-completions deleted file mode 100644 index a0fcc117694c36..00000000000000 --- a/utils/editors/sublimetext2/threejs.sublime-completions +++ /dev/null @@ -1,143 +0,0 @@ -{ - "scope": "source.js,source.js.embedded.html,source.coffee,source.ts", - "version": "r55", - "completions": - [ - { "trigger": "THREE.extend", "contents": "THREE.extend( ${1:obj}, ${2:source} )$0" }, - { "trigger": "THREE.Color", "contents": "THREE.Color( ${1:value} )$0" }, - { "trigger": "THREE.Quaternion", "contents": "THREE.Quaternion( ${1:x}, ${2:y}, ${3:z}, ${4:w} )$0" }, - { "trigger": "THREE.Vector2", "contents": "THREE.Vector2( ${1:x}, ${2:y} )$0" }, - { "trigger": "THREE.Vector3", "contents": "THREE.Vector3( ${1:x}, ${2:y}, ${3:z} )$0" }, - { "trigger": "THREE.Vector4", "contents": "THREE.Vector4( ${1:x}, ${2:y}, ${3:z}, ${4:w} )$0" }, - { "trigger": "THREE.Euler", "contents": "THREE.Euler( ${1:x}, ${2:y}, ${3:z}, ${4:order} )$0" }, - { "trigger": "THREE.Line3", "contents": "THREE.Line3( ${1:start}, ${2:end} )$0" }, - { "trigger": "THREE.Box2", "contents": "THREE.Box2( ${1:min}, ${2:max} )$0" }, - { "trigger": "THREE.Box3", "contents": "THREE.Box3( ${1:min}, ${2:max} )$0" }, - { "trigger": "THREE.Matrix3", "contents": "THREE.Matrix3( ${1:n11}, ${2:n12}, ${3:n13}, ${4:n21}, ${5:n22}, ${6:n23}, ${7:n31}, ${8:n32}, ${9:n33} )$0" }, - { "trigger": "THREE.Matrix4", "contents": "THREE.Matrix4( ${1:n11}, ${2:n12}, ${3:n13}, ${4:n14}, ${5:n21}, ${6:n22}, ${7:n23}, ${8:n24}, ${9:n31}, ${10:n32}, ${11:n33}, ${12:n34}, ${13:n41}, ${14:n42}, ${15:n43}, ${16:n44} )$0" }, - { "trigger": "THREE.Ray", "contents": "THREE.Ray( ${1:origin}, ${2:direction} )$0" }, - { "trigger": "THREE.Sphere", "contents": "THREE.Sphere( ${1:center}, ${2:radius} )$0" }, - { "trigger": "THREE.Frustum", "contents": "THREE.Frustum( ${1:p0}, ${2:p1}, ${3:p2}, ${4:p3}, ${5:p4}, ${6:p5} )$0" }, - { "trigger": "THREE.Plane", "contents": "THREE.Plane( ${1:normal}, ${2:constant} )$0" }, - { "trigger": "THREE.Spline", "contents": "THREE.Spline( ${1:points} )$0" }, - { "trigger": "THREE.Triangle", "contents": "THREE.Triangle( ${1:a}, ${2:b}, ${3:c} )$0" }, - { "trigger": "THREE.Vertex", "contents": "THREE.Vertex( ${1:v} )$0" }, - { "trigger": "THREE.UV", "contents": "THREE.UV( ${1:u}, ${2:v} )$0" }, - { "trigger": "THREE.Clock", "contents": "THREE.Clock( ${1:autoStart} )$0" }, - { "trigger": "THREE.EventDispatcher", "contents": "THREE.EventDispatcher()$0" }, - { "trigger": "THREE.Raycaster", "contents": "THREE.Raycaster( ${1:origin}, ${2:direction}, ${3:near}, ${4:far} )$0" }, - { "trigger": "THREE.Object3D", "contents": "THREE.Object3D()$0" }, - { "trigger": "THREE.Projector", "contents": "THREE.Projector()$0" }, - { "trigger": "THREE.Face3", "contents": "THREE.Face3( ${1:a}, ${2:b}, ${3:c}, ${4:normal}, ${5:color}, ${6:materialIndex} )$0" }, - { "trigger": "THREE.Face4", "contents": "THREE.Face4( ${1:a}, ${2:b}, ${3:c}, ${4:d}, ${5:normal}, ${6:color}, ${7:materialIndex} )$0" }, - { "trigger": "THREE.Geometry", "contents": "THREE.Geometry()$0" }, - { "trigger": "THREE.BufferGeometry", "contents": "THREE.BufferGeometry()$0" }, - { "trigger": "THREE.Camera", "contents": "THREE.Camera()$0" }, - { "trigger": "THREE.OrthographicCamera", "contents": "THREE.OrthographicCamera( ${1:left}, ${2:right}, ${3:top}, ${4:bottom}, ${5:near}, ${6:far} )$0" }, - { "trigger": "THREE.PerspectiveCamera", "contents": "THREE.PerspectiveCamera( ${1:fov}, ${2:aspect}, ${3:near}, ${4:far} )$0" }, - { "trigger": "THREE.Light", "contents": "THREE.Light( ${1:hex} )$0" }, - { "trigger": "THREE.AmbientLight", "contents": "THREE.AmbientLight( ${1:hex} )$0" }, - { "trigger": "THREE.AreaLight", "contents": "THREE.AreaLight( ${1:hex}, ${2:intensity} )$0" }, - { "trigger": "THREE.DirectionalLight", "contents": "THREE.DirectionalLight( ${1:hex}, ${2:intensity} )$0" }, - { "trigger": "THREE.HemisphereLight", "contents": "THREE.HemisphereLight( ${1:skyColorHex}, ${2:groundColorHex}, ${3:intensity} )$0" }, - { "trigger": "THREE.PointLight", "contents": "THREE.PointLight( ${1:hex}, ${2:intensity}, ${3:distance} )$0" }, - { "trigger": "THREE.SpotLight", "contents": "THREE.SpotLight( ${1:hex}, ${2:intensity}, ${3:distance}, ${4:angle}, ${5:exponent} )$0" }, - { "trigger": "THREE.Loader", "contents": "THREE.Loader( ${1:showStatus} )$0" }, - { "trigger": "THREE.XHRLoader", "contents": "THREE.XHRLoader( ${1:manager} )$0" }, - { "trigger": "THREE.ImageLoader", "contents": "THREE.ImageLoader( ${1:manager} )$0" }, - { "trigger": "THREE.JSONLoader", "contents": "THREE.JSONLoader( ${1:showStatus} )$0" }, - { "trigger": "THREE.LoadingManager", "contents": "THREE.LoadingManager( ${1:onLoad}, ${2:onProgress}, ${3:onError} )$0" }, - { "trigger": "THREE.BufferGeometryLoader", "contents": "THREE.BufferGeometryLoader( ${1:manager} )$0" }, - { "trigger": "THREE.GeometryLoader", "contents": "THREE.GeometryLoader( ${1:manager} )$0" }, - { "trigger": "THREE.MaterialLoader", "contents": "THREE.MaterialLoader( ${1:manager} )$0" }, - { "trigger": "THREE.ObjectLoader", "contents": "THREE.ObjectLoader( ${1:manager} )$0" }, - { "trigger": "THREE.SceneLoader", "contents": "THREE.SceneLoader()$0" }, - { "trigger": "THREE.TextureLoader", "contents": "THREE.TextureLoader( ${1:manager} )$0" }, - { "trigger": "THREE.Material", "contents": "THREE.Material()$0" }, - { "trigger": "THREE.LineBasicMaterial", "contents": "THREE.LineBasicMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.LineDashedMaterial", "contents": "THREE.LineDashedMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.MeshBasicMaterial", "contents": "THREE.MeshBasicMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.MeshLambertMaterial", "contents": "THREE.MeshLambertMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.MeshPhongMaterial", "contents": "THREE.MeshPhongMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.MeshDepthMaterial", "contents": "THREE.MeshDepthMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.MeshNormalMaterial", "contents": "THREE.MeshNormalMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.MeshFaceMaterial", "contents": "THREE.MeshFaceMaterial( ${1:materials} )$0" }, - { "trigger": "THREE.ParticleBasicMaterial", "contents": "THREE.ParticleBasicMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.ParticleCanvasMaterial", "contents": "THREE.ParticleCanvasMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.ShaderMaterial", "contents": "THREE.ShaderMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.SpriteMaterial", "contents": "THREE.SpriteMaterial( ${1:parameters} )$0" }, - { "trigger": "THREE.Texture", "contents": "THREE.Texture( ${1:image}, ${2:mapping}, ${3:wrapS}, ${4:wrapT}, ${5:magFilter}, ${6:minFilter}, ${7:format}, ${8:type}, ${9:anisotropy} )$0" }, - { "trigger": "THREE.CompressedTexture", "contents": "THREE.CompressedTexture( ${1:mipmaps}, ${2:width}, ${3:height}, ${4:format}, ${5:type}, ${6:mapping}, ${7:wrapS}, ${8:wrapT}, ${9:magFilter}, ${10:minFilter}, ${11:anisotropy} )$0" }, - { "trigger": "THREE.DataTexture", "contents": "THREE.DataTexture( ${1:data}, ${2:width}, ${3:height}, ${4:format}, ${5:type}, ${6:mapping}, ${7:wrapS}, ${8:wrapT}, ${9:magFilter}, ${10:minFilter}, ${11:anisotropy} )$0" }, - { "trigger": "THREE.Particle", "contents": "THREE.Particle( ${1:material} )$0" }, - { "trigger": "THREE.ParticleSystem", "contents": "THREE.ParticleSystem( ${1:geometry}, ${2:material} )$0" }, - { "trigger": "THREE.Line", "contents": "THREE.Line( ${1:geometry}, ${2:material}, ${3:type} )$0" }, - { "trigger": "THREE.Mesh", "contents": "THREE.Mesh( ${1:geometry}, ${2:material} )$0" }, - { "trigger": "THREE.SkinnedMesh", "contents": "THREE.SkinnedMesh( ${1:geometry}, ${2:material}, ${3:useVertexTexture} )$0" }, - { "trigger": "THREE.MorphAnimMesh", "contents": "THREE.MorphAnimMesh( ${1:geometry}, ${2:material} )$0" }, - { "trigger": "THREE.LOD", "contents": "THREE.LOD()$0" }, - { "trigger": "THREE.Sprite", "contents": "THREE.Sprite( ${1:material} )$0" }, - { "trigger": "THREE.Scene", "contents": "THREE.Scene()$0" }, - { "trigger": "THREE.Fog", "contents": "THREE.Fog( ${1:hex}, ${2:near}, ${3:far} )$0" }, - { "trigger": "THREE.FogExp2", "contents": "THREE.FogExp2( ${1:hex}, ${2:density} )$0" }, - { "trigger": "THREE.CanvasRenderer", "contents": "THREE.CanvasRenderer( ${1:parameters} )$0" }, - { "trigger": "THREE.WebGLRenderer", "contents": "THREE.WebGLRenderer( ${1:parameters} )$0" }, - { "trigger": "THREE.WebGLRenderTarget", "contents": "THREE.WebGLRenderTarget( ${1:width}, ${2:height}, ${3:options} )$0" }, - { "trigger": "THREE.WebGLRenderTargetCube", "contents": "THREE.WebGLRenderTargetCube( ${1:width}, ${2:height}, ${3:options} )$0" }, - { "trigger": "THREE.RenderableVertex", "contents": "THREE.RenderableVertex()$0" }, - { "trigger": "THREE.RenderableFace3", "contents": "THREE.RenderableFace3()$0" }, - { "trigger": "THREE.RenderableObject", "contents": "THREE.RenderableObject()$0" }, - { "trigger": "THREE.RenderableParticle", "contents": "THREE.RenderableParticle()$0" }, - { "trigger": "THREE.RenderableLine", "contents": "THREE.RenderableLine()$0" }, - { "trigger": "THREE.Curve", "contents": "THREE.Curve()$0" }, - { "trigger": "THREE.CurvePath", "contents": "THREE.CurvePath()$0" }, - { "trigger": "THREE.Gyroscope", "contents": "THREE.Gyroscope()$0" }, - { "trigger": "THREE.Path", "contents": "THREE.Path( ${1:points} )$0" }, - { "trigger": "THREE.Shape", "contents": "THREE.Shape()$0" }, - { "trigger": "THREE.LineCurve", "contents": "THREE.LineCurve( ${1:v1}, ${2:v2} )$0" }, - { "trigger": "THREE.QuadraticBezierCurve", "contents": "THREE.QuadraticBezierCurve( ${1:v0}, ${2:v1}, ${3:v2} )$0" }, - { "trigger": "THREE.CubicBezierCurve", "contents": "THREE.CubicBezierCurve( ${1:v0}, ${2:v1}, ${3:v2}, ${4:v3} )$0" }, - { "trigger": "THREE.ArcCurve", "contents": "THREE.ArcCurve( ${1:aX}, ${2:aY}, ${3:aRadius}, ${4:aStartAngle}, ${5:aEndAngle}, ${6:aClockwise} )$0" }, - { "trigger": "THREE.Animation", "contents": "THREE.Animation( ${1:root}, ${2:name}, ${3:interpolationType} )$0" }, - { "trigger": "THREE.CubeCamera", "contents": "THREE.CubeCamera( ${1:near}, ${2:far}, ${3:cubeResolution} )$0" }, - { "trigger": "THREE.CombinedCamera", "contents": "THREE.CombinedCamera( ${1:width}, ${2:height}, ${3:fov}, ${4:near}, ${5:far}, ${6:orthoNear}, ${7:orthoFar} )$0" }, - { "trigger": "THREE.CircleGeometry", "contents": "THREE.CircleGeometry( ${1:radius}, ${2:segments}, ${3:thetaStart}, ${4:thetaLength} )$0" }, - { "trigger": "THREE.CubeGeometry", "contents": "THREE.CubeGeometry( ${1:width}, ${2:height}, ${3:depth}, ${4:widthSegments}, ${5:heightSegments}, ${6:depthSegments} )$0" }, - { "trigger": "THREE.CylinderGeometry", "contents": "THREE.CylinderGeometry( ${1:radiusTop}, ${2:radiusBottom}, ${3:height}, ${4:radialSegments}, ${5:heightSegments}, ${6:openEnded} )$0" }, - { "trigger": "THREE.ExtrudeGeometry", "contents": "THREE.ExtrudeGeometry( ${1:shapes}, ${2:options} )$0" }, - { "trigger": "THREE.ShapeGeometry", "contents": "THREE.ShapeGeometry( ${1:shapes}, ${2:options} )$0" }, - { "trigger": "THREE.LatheGeometry", "contents": "THREE.LatheGeometry( ${1:points}, ${2:segments}, ${3:phiStart}, ${4:phiLength} )$0" }, - { "trigger": "THREE.PlaneGeometry", "contents": "THREE.PlaneGeometry( ${1:width}, ${2:height}, ${3:widthSegments}, ${4:heightSegments} )$0" }, - { "trigger": "THREE.RingGeometry", "contents": "THREE.RingGeometry( ${1:innerRadius}, ${2:outerRadius}, ${3:thetaSegments}, ${4:phiSegments}, ${5:thetaStart}, ${6:thetaLength} )$0" }, - { "trigger": "THREE.SphereGeometry", "contents": "THREE.SphereGeometry( ${1:radius}, ${2:widthSegments}, ${3:heightSegments}, ${4:phiStart}, ${5:phiLength}, ${6:thetaStart}, ${7:thetaLength} )$0" }, - { "trigger": "THREE.TextGeometry", "contents": "THREE.TextGeometry( ${1:text}, ${2:parameters} )$0" }, - { "trigger": "THREE.TorusGeometry", "contents": "THREE.TorusGeometry( ${1:radius}, ${2:tube}, ${3:radialSegments}, ${4:tubularSegments}, ${5:arc} )$0" }, - { "trigger": "THREE.TorusKnotGeometry", "contents": "THREE.TorusKnotGeometry( ${1:radius}, ${2:tube}, ${3:radialSegments}, ${4:tubularSegments}, ${5:p}, ${6:q}, ${7:heightScale} )$0" }, - { "trigger": "THREE.PolyhedronGeometry", "contents": "THREE.PolyhedronGeometry( ${1:vertices}, ${2:faces}, ${3:radius}, ${4:detail} )$0" }, - { "trigger": "THREE.IcosahedronGeometry", "contents": "THREE.IcosahedronGeometry( ${1:radius}, ${2:detail} )$0" }, - { "trigger": "THREE.OctahedronGeometry", "contents": "THREE.OctahedronGeometry( ${1:radius}, ${2:detail} )$0" }, - { "trigger": "THREE.TetrahedronGeometry", "contents": "THREE.TetrahedronGeometry( ${1:radius}, ${2:detail} )$0" }, - { "trigger": "THREE.ParametricGeometry", "contents": "THREE.ParametricGeometry( ${1:func}, ${2:slices}, ${3:stacks} )$0" }, - { "trigger": "THREE.AxisHelper", "contents": "THREE.AxisHelper( ${1:size} )$0" }, - { "trigger": "THREE.ArrowHelper", "contents": "THREE.ArrowHelper( ${1:dir}, ${2:origin}, ${3:length}, ${4:hex} )$0" }, - { "trigger": "THREE.BoxHelper", "contents": "THREE.BoxHelper( ${1:object} )$0" }, - { "trigger": "THREE.BoundingBoxHelper", "contents": "THREE.BoundingBoxHelper( ${1:object}, ${2:hex} )$0" }, - { "trigger": "THREE.CameraHelper", "contents": "THREE.CameraHelper( ${1:camera} )$0" }, - { "trigger": "THREE.DirectionalLightHelper", "contents": "THREE.DirectionalLightHelper( ${1:light}, ${2:size} )$0" }, - { "trigger": "THREE.FaceNormalsHelper", "contents": "THREE.FaceNormalsHelper( ${1:object}, ${2:size}, ${3:hex}, ${4:linewidth} )$0" }, - { "trigger": "THREE.GridHelper", "contents": "THREE.GridHelper( ${1:size}, ${2:step} )$0" }, - { "trigger": "THREE.HemisphereLightHelper", "contents": "THREE.HemisphereLightHelper( ${1:light}, ${2:sphereSize}, ${3:arrowLength}, ${4:domeSize} )$0" }, - { "trigger": "THREE.PointLightHelper", "contents": "THREE.PointLightHelper( ${1:light}, ${2:sphereSize} )$0" }, - { "trigger": "THREE.SpotLightHelper", "contents": "THREE.SpotLightHelper( ${1:light} )$0" }, - { "trigger": "THREE.VertexNormalsHelper", "contents": "THREE.VertexNormalsHelper( ${1:object}, ${2:size}, ${3:hex}, ${4:linewidth} )$0" }, - { "trigger": "THREE.VertexTangentsHelper", "contents": "THREE.VertexTangentsHelper( ${1:object}, ${2:size}, ${3:hex}, ${4:linewidth} )$0" }, - { "trigger": "THREE.WireframeHelper", "contents": "THREE.WireframeHelper( ${1:object} )$0" }, - { "trigger": "THREE.ImmediateRenderObject", "contents": "THREE.ImmediateRenderObject()$0" }, - { "trigger": "THREE.LensFlare", "contents": "THREE.LensFlare( ${1:texture}, ${2:size}, ${3:distance}, ${4:blending}, ${5:color} )$0" }, - { "trigger": "THREE.LensFlarePlugin", "contents": "THREE.LensFlarePlugin()$0" }, - { "trigger": "THREE.ShadowMapPlugin", "contents": "THREE.ShadowMapPlugin()$0" }, - { "trigger": "THREE.SpritePlugin", "contents": "THREE.SpritePlugin()$0" }, - { "trigger": "THREE.DepthPassPlugin", "contents": "THREE.DepthPassPlugin()$0" }, - "THREE" - ] -} From f88546724c6dd746258678af4f986edb40f8957e Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 18 Feb 2015 17:33:58 -0800 Subject: [PATCH 154/333] THREE.Cache now global. See #5650. --- src/loaders/Cache.js | 10 ++-------- src/loaders/ImageLoader.js | 18 +++++++----------- src/loaders/XHRLoader.js | 5 ++--- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/loaders/Cache.js b/src/loaders/Cache.js index 6859ae01b62243..87227cba054793 100644 --- a/src/loaders/Cache.js +++ b/src/loaders/Cache.js @@ -2,15 +2,9 @@ * @author mrdoob / http://mrdoob.com/ */ -THREE.Cache = function () { +THREE.Cache = { - this.files = {}; - -}; - -THREE.Cache.prototype = { - - constructor: THREE.Cache, + files: {}, add: function ( key, file ) { diff --git a/src/loaders/ImageLoader.js b/src/loaders/ImageLoader.js index d5ef39ca75aad7..a73a75c46b84f9 100644 --- a/src/loaders/ImageLoader.js +++ b/src/loaders/ImageLoader.js @@ -4,7 +4,6 @@ THREE.ImageLoader = function ( manager ) { - this.cache = new THREE.Cache(); this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; }; @@ -17,7 +16,7 @@ THREE.ImageLoader.prototype = { var scope = this; - var cached = scope.cache.get( url ); + var cached = THREE.Cache.get( url ); if ( cached !== undefined ) { @@ -28,18 +27,15 @@ THREE.ImageLoader.prototype = { var image = document.createElement( 'img' ); - if ( onLoad !== undefined ) { + image.addEventListener( 'load', function ( event ) { - image.addEventListener( 'load', function ( event ) { + THREE.Cache.add( url, this ); - scope.cache.add( url, this ); + if ( onLoad ) onLoad( this ); + + scope.manager.itemEnd( url ); - onLoad( this ); - scope.manager.itemEnd( url ); - - }, false ); - - } + }, false ); if ( onProgress !== undefined ) { diff --git a/src/loaders/XHRLoader.js b/src/loaders/XHRLoader.js index 0440d45a0c956d..1080719a7b52b4 100644 --- a/src/loaders/XHRLoader.js +++ b/src/loaders/XHRLoader.js @@ -4,7 +4,6 @@ THREE.XHRLoader = function ( manager ) { - this.cache = new THREE.Cache(); this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; }; @@ -17,7 +16,7 @@ THREE.XHRLoader.prototype = { var scope = this; - var cached = scope.cache.get( url ); + var cached = THREE.Cache.get( url ); if ( cached !== undefined ) { @@ -31,7 +30,7 @@ THREE.XHRLoader.prototype = { request.addEventListener( 'load', function ( event ) { - scope.cache.add( url, this.response ); + THREE.Cache.add( url, this.response ); if ( onLoad ) onLoad( this.response ); From 092aa7729ab15d010026458320d00a3ab9bf0a63 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 18 Feb 2015 17:34:22 -0800 Subject: [PATCH 155/333] Updated builds. --- build/three.js | 33 +++++++++++---------------------- build/three.min.js | 10 +++++----- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/build/three.js b/build/three.js index 3329a65c3249e4..8ad68686ae1fa5 100644 --- a/build/three.js +++ b/build/three.js @@ -11192,15 +11192,9 @@ THREE.SpotLight.prototype.clone = function () { * @author mrdoob / http://mrdoob.com/ */ -THREE.Cache = function () { +THREE.Cache = { - this.files = {}; - -}; - -THREE.Cache.prototype = { - - constructor: THREE.Cache, + files: {}, add: function ( key, file ) { @@ -11664,7 +11658,6 @@ THREE.Loader.Handlers = { THREE.XHRLoader = function ( manager ) { - this.cache = new THREE.Cache(); this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; }; @@ -11677,7 +11670,7 @@ THREE.XHRLoader.prototype = { var scope = this; - var cached = scope.cache.get( url ); + var cached = THREE.Cache.get( url ); if ( cached !== undefined ) { @@ -11691,7 +11684,7 @@ THREE.XHRLoader.prototype = { request.addEventListener( 'load', function ( event ) { - scope.cache.add( url, this.response ); + THREE.Cache.add( url, this.response ); if ( onLoad ) onLoad( this.response ); @@ -11750,7 +11743,6 @@ THREE.XHRLoader.prototype = { THREE.ImageLoader = function ( manager ) { - this.cache = new THREE.Cache(); this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; }; @@ -11763,7 +11755,7 @@ THREE.ImageLoader.prototype = { var scope = this; - var cached = scope.cache.get( url ); + var cached = THREE.Cache.get( url ); if ( cached !== undefined ) { @@ -11774,18 +11766,15 @@ THREE.ImageLoader.prototype = { var image = document.createElement( 'img' ); - if ( onLoad !== undefined ) { - - image.addEventListener( 'load', function ( event ) { - - scope.cache.add( url, this ); + image.addEventListener( 'load', function ( event ) { - onLoad( this ); - scope.manager.itemEnd( url ); + THREE.Cache.add( url, this ); - }, false ); + if ( onLoad ) onLoad( this ); + + scope.manager.itemEnd( url ); - } + }, false ); if ( onProgress !== undefined ) { diff --git a/build/three.min.js b/build/three.min.js index c31875a2b688d4..b868852cfbd565 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -247,7 +247,7 @@ THREE.PointLight.prototype.clone=function(){var a=new THREE.PointLight;THREE.Lig THREE.SpotLight=function(a,b,c,d,e,f){THREE.Light.call(this,a);this.type="SpotLight";this.position.set(0,1,0);this.target=new THREE.Object3D;this.intensity=void 0!==b?b:1;this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.exponent=void 0!==e?e:10;this.decay=void 0!==f?f:1;this.onlyShadow=this.castShadow=!1;this.shadowCameraNear=50;this.shadowCameraFar=5E3;this.shadowCameraFov=50;this.shadowCameraVisible=!1;this.shadowBias=0;this.shadowDarkness=.5;this.shadowMapHeight=this.shadowMapWidth= 512;this.shadowMatrix=this.shadowCamera=this.shadowMapSize=this.shadowMap=null};THREE.SpotLight.prototype=Object.create(THREE.Light.prototype);THREE.SpotLight.prototype.constructor=THREE.SpotLight; THREE.SpotLight.prototype.clone=function(){var a=new THREE.SpotLight;THREE.Light.prototype.clone.call(this,a);a.target=this.target.clone();a.intensity=this.intensity;a.distance=this.distance;a.angle=this.angle;a.exponent=this.exponent;a.decay=this.decay;a.castShadow=this.castShadow;a.onlyShadow=this.onlyShadow;a.shadowCameraNear=this.shadowCameraNear;a.shadowCameraFar=this.shadowCameraFar;a.shadowCameraFov=this.shadowCameraFov;a.shadowCameraVisible=this.shadowCameraVisible;a.shadowBias=this.shadowBias; -a.shadowDarkness=this.shadowDarkness;a.shadowMapWidth=this.shadowMapWidth;a.shadowMapHeight=this.shadowMapHeight;return a};THREE.Cache=function(){this.files={}};THREE.Cache.prototype={constructor:THREE.Cache,add:function(a,b){this.files[a]=b},get:function(a){return this.files[a]},remove:function(a){delete this.files[a]},clear:function(){this.files={}}}; +a.shadowDarkness=this.shadowDarkness;a.shadowMapWidth=this.shadowMapWidth;a.shadowMapHeight=this.shadowMapHeight;return a};THREE.Cache={files:{},add:function(a,b){this.files[a]=b},get:function(a){return this.files[a]},remove:function(a){delete this.files[a]},clear:function(){this.files={}}}; THREE.Loader=function(a){this.statusDomElement=(this.showStatus=a)?THREE.Loader.prototype.addStatusElement():null;this.imageLoader=new THREE.ImageLoader;this.onLoadStart=function(){};this.onLoadProgress=function(){};this.onLoadComplete=function(){}}; THREE.Loader.prototype={constructor:THREE.Loader,crossOrigin:void 0,addStatusElement:function(){var a=document.createElement("div");a.style.position="absolute";a.style.right="0px";a.style.top="0px";a.style.fontSize="0.8em";a.style.textAlign="left";a.style.background="rgba(0,0,0,0.25)";a.style.color="#fff";a.style.width="120px";a.style.padding="0.5em 0.5em 0.5em 0.5em";a.style.zIndex=1E3;a.innerHTML="Loading ...";return a},updateProgress:function(a){var b="Loaded ",b=a.total?b+((100*a.loaded/a.total).toFixed(0)+ "%"):b+((a.loaded/1024).toFixed(2)+" KB");this.statusDomElement.innerHTML=b},extractUrlBase:function(a){a=a.split("/");if(1===a.length)return"./";a.pop();return a.join("/")+"/"},initMaterials:function(a,b){for(var c=[],d=0;d Date: Wed, 18 Feb 2015 23:21:54 -0600 Subject: [PATCH 156/333] Added ascii art and three.min.js to docs page --- docs/index.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/index.html b/docs/index.html index 7ce1d59f9c0415..a51b6a8fae7327 100644 --- a/docs/index.html +++ b/docs/index.html @@ -405,6 +405,18 @@

three.js / docs

if ( window.location.hash.length > 0 ) goToHash(); + console.log(["\n __________ ____\n", + " /\\ \\/\\ \\ ____ ____ __\n", + " / \\_________\\ \\___\\ _______ /\\ \\ /\\ \\ _ / /\\\n", + " \\ / / / / /\\ \\/ \\___\\/ \\___\\ / /\\ / / /_ \n", + " \\__ ___/ / / \\/ \\______\\ / __ \\ / __ \\ / / / /_/ / \\\n", + " __/ / // / /___\\ / __ / / ____/ / ____/ /_/ \\ \\ \\ / / \n", + "/\\ \\ / / \\ / __ / / /\\/_/\\/ /___\\\\/ /___\\ \\_\\/\\ \\ `/`/ /\n", + "\\ \\ \\/___/ \\/___/\\/__/\\/__/ \\_____/ \\_____/ __ \\_\\ \\ \\_\\/\n", + " \\ \\____________________________________________\\ /_/\\ /_/ /\n", + " \\/____________________________________________/ \\_\\/ \\_\\/\n"].join('')) + + From 62979dfcd60874964135b83cce0812721b93326b Mon Sep 17 00:00:00 2001 From: Greg Tatum Date: Wed, 18 Feb 2015 23:50:39 -0600 Subject: [PATCH 157/333] Fixed little docs issues --- docs/api/cameras/CubeCamera.html | 2 +- docs/api/loaders/OBJMTLLoader.html | 2 +- docs/api/materials/MeshLambertMaterial.html | 5 ----- docs/api/materials/MeshPhongMaterial.html | 9 ++------- docs/scenes/js/material.js | 6 +----- 5 files changed, 5 insertions(+), 19 deletions(-) diff --git a/docs/api/cameras/CubeCamera.html b/docs/api/cameras/CubeCamera.html index f51201bdc61498..d4170ab9398edf 100644 --- a/docs/api/cameras/CubeCamera.html +++ b/docs/api/cameras/CubeCamera.html @@ -24,7 +24,7 @@

Examples

scene.add( cubeCamera ); //Create car - var chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, ambient: 0xffffff, envMap: cubeCamera.renderTarget } ); + var chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeCamera.renderTarget } ); var car = new Mesh( carGeometry, chromeMaterial ); scene.add( car ); diff --git a/docs/api/loaders/OBJMTLLoader.html b/docs/api/loaders/OBJMTLLoader.html index e87c1a283d94f7..31b7ca94dbc5ad 100644 --- a/docs/api/loaders/OBJMTLLoader.html +++ b/docs/api/loaders/OBJMTLLoader.html @@ -47,7 +47,7 @@

[method:Object3D parse]( [page:String text], [page:Function mtllibCallback]
Parse an obj text structure and return an [page:Object3D].
- Found objects are converted to [page:Mesh] with a [page:BufferGeometry] and materials are converted to [page:MeshLambertMaterial]. + Found objects are converted to a [page:Mesh] and materials are converted to [page:MeshLambertMaterial].

Example

diff --git a/docs/api/materials/MeshLambertMaterial.html b/docs/api/materials/MeshLambertMaterial.html index 71da28735a4db6..483dced39f253b 100644 --- a/docs/api/materials/MeshLambertMaterial.html +++ b/docs/api/materials/MeshLambertMaterial.html @@ -49,11 +49,6 @@

[property:Color color]

Diffuse color of the material. Default is white.
-

[property:Color ambient]

-
- Ambient color of the material, multiplied by the color of the [page:AmbientLight]. Default is white.
-
-

[property:Color emissive]

Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.
diff --git a/docs/api/materials/MeshPhongMaterial.html b/docs/api/materials/MeshPhongMaterial.html index 70179ecec63a13..2d84126decc497 100644 --- a/docs/api/materials/MeshPhongMaterial.html +++ b/docs/api/materials/MeshPhongMaterial.html @@ -41,7 +41,7 @@

[name]([page:Object parameters])

Example:
- materials.push( new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ) ); + materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ) );
@@ -54,11 +54,6 @@

[property:Color color]

Diffuse color of the material. Default is white.
-

[property:Color ambient]

-
- Ambient color of the material, multiplied by the color of the [page:AmbientLight]. Default is white.
-
-

[property:Color emissive]

Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.
@@ -70,7 +65,7 @@

[property:Color specular]

[property:Float shininess]

-
How shiny the specular highlight is; a higher value gives a sharper highlight. Default is *30*.
+
How shiny the specular highlight is; a higher value gives a sharper highlight. Default is *30*. It should not be set to 0.

[property:boolean metal]

diff --git a/docs/scenes/js/material.js b/docs/scenes/js/material.js index 98ffbcc16c02d6..6f3bf3fbbdad61 100644 --- a/docs/scenes/js/material.js +++ b/docs/scenes/js/material.js @@ -393,7 +393,6 @@ function guiMeshLambertMaterial ( gui, mesh, material, geometry ) { var data = { color : material.color.getHex(), - ambient : material.ambient.getHex(), emissive : material.emissive.getHex(), envMaps : envMapKeys, map : textureMapKeys, @@ -407,7 +406,6 @@ function guiMeshLambertMaterial ( gui, mesh, material, geometry ) { var folder = gui.addFolder('THREE.MeshLambertMaterial'); folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) ); - folder.addColor( data, 'ambient' ).onChange( handleColorChange( material.ambient ) ); folder.addColor( data, 'emissive' ).onChange( handleColorChange( material.emissive ) ); folder.add( material, 'shading', constants.shading ).onChange( needsUpdate( material, geometry ) ); @@ -433,7 +431,6 @@ function guiMeshPhongMaterial ( gui, mesh, material, geometry ) { var data = { color : material.color.getHex(), - ambient : material.ambient.getHex(), emissive : material.emissive.getHex(), specular : material.specular.getHex(), envMaps : envMapKeys, @@ -446,11 +443,10 @@ function guiMeshPhongMaterial ( gui, mesh, material, geometry ) { var folder = gui.addFolder('THREE.MeshPhongMaterial'); folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) ); - folder.addColor( data, 'ambient' ).onChange( handleColorChange( material.ambient ) ); folder.addColor( data, 'emissive' ).onChange( handleColorChange( material.emissive ) ); folder.addColor( data, 'specular' ).onChange( handleColorChange( material.specular ) ); - folder.add( material, 'shininess', 0, 100); + folder.add( material, 'shininess', 1, 100); folder.add( material, 'shading', constants.shading).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'wireframe' ); folder.add( material, 'wireframeLinewidth', 0, 10 ); From 0d3985f25878250fea0df0347eda2c85ac9900d7 Mon Sep 17 00:00:00 2001 From: erichlof Date: Thu, 19 Feb 2015 00:21:16 -0600 Subject: [PATCH 158/333] Create webgl_shadowmesh.html --- examples/webgl_shadowmesh.html | 306 +++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 examples/webgl_shadowmesh.html diff --git a/examples/webgl_shadowmesh.html b/examples/webgl_shadowmesh.html new file mode 100644 index 00000000000000..651299cffb87fb --- /dev/null +++ b/examples/webgl_shadowmesh.html @@ -0,0 +1,306 @@ + + + + + three.js webgl - ShadowMesh + + + + + + + + +
+ + + +
+ three.js webgl - ShadowMesh +
+ + + + + + + + + From 6aef5b7b7c95b21e2ac075ffeb3ece449afe8401 Mon Sep 17 00:00:00 2001 From: erichlof Date: Thu, 19 Feb 2015 00:31:20 -0600 Subject: [PATCH 159/333] Update webgl_shadowmesh.html --- examples/webgl_shadowmesh.html | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/webgl_shadowmesh.html b/examples/webgl_shadowmesh.html index 651299cffb87fb..df597fd2116207 100644 --- a/examples/webgl_shadowmesh.html +++ b/examples/webgl_shadowmesh.html @@ -240,6 +240,7 @@ document.getElementById( 'lightButton' ).style.fontSize = SCREEN_WIDTH * 0.02 + "px"; document.getElementById( 'info' ).style.fontSize = SCREEN_WIDTH * 0.02 + "px"; + } From fe8493157ef764bb4ca10e3f48dfbec4881acf8a Mon Sep 17 00:00:00 2001 From: gero3 Date: Thu, 19 Feb 2015 13:44:04 +0000 Subject: [PATCH 160/333] codestyle fixes --- editor/js/Sidebar.Material.js | 10 +- editor/js/Storage.js | 2 +- examples/js/AudioObject.js | 2 +- examples/js/BlendCharacter.js | 6 +- examples/js/Car.js | 6 +- examples/js/Cloth.js | 52 ++-- examples/js/CurveExtras.js | 2 +- examples/js/Detector.js | 2 +- examples/js/ImprovedNoise.js | 20 +- examples/js/MD2Character.js | 2 +- examples/js/MD2CharacterComplex.js | 6 +- examples/js/MarchingCubes.js | 46 ++-- examples/js/Ocean.js | 12 +- examples/js/Octree.js | 86 +++--- examples/js/ParametricGeometries.js | 6 +- examples/js/ShaderTerrain.js | 2 +- examples/js/SimplexNoise.js | 254 +++++++++--------- examples/js/SimulationRenderer.js | 4 +- examples/js/Sparks.js | 42 +-- examples/js/TypedArrayUtils.js | 10 +- examples/js/cameras/CombinedCamera.js | 2 +- examples/js/controls/EditorControls.js | 6 +- examples/js/controls/FirstPersonControls.js | 4 +- examples/js/controls/FlyControls.js | 2 +- examples/js/controls/OrbitControls.js | 4 +- .../controls/OrthographicTrackballControls.js | 10 +- examples/js/controls/TrackballControls.js | 14 +- examples/js/controls/TransformControls.js | 54 ++-- examples/js/crossfade/scenes.js | 12 +- examples/js/crossfade/transition.js | 24 +- examples/js/curves/NURBSCurve.js | 2 +- examples/js/curves/NURBSSurface.js | 4 +- examples/js/curves/NURBSUtils.js | 58 ++-- examples/js/effects/AsciiEffect.js | 26 +- examples/js/effects/VREffect.js | 38 +-- examples/js/exporters/SceneExporter.js | 2 +- examples/js/geometries/ConvexGeometry.js | 20 +- examples/js/geometries/DecalGeometry.js | 42 +-- examples/js/geometries/hilbert2D.js | 2 +- examples/js/geometries/hilbert3D.js | 2 +- examples/js/loaders/AWDLoader.js | 116 ++++---- examples/js/loaders/AssimpJSONLoader.js | 54 ++-- examples/js/loaders/BinaryLoader.js | 112 ++++---- examples/js/loaders/ColladaLoader.js | 164 +++++------ examples/js/loaders/DDSLoader.js | 26 +- examples/js/loaders/MTLLoader.js | 6 +- examples/js/loaders/PDBLoader.js | 34 +-- examples/js/loaders/PLYLoader.js | 20 +- examples/js/loaders/PVRLoader.js | 16 +- examples/js/loaders/RGBELoader.js | 60 ++--- examples/js/loaders/STLLoader.js | 20 +- examples/js/loaders/TGALoader.js | 28 +- examples/js/loaders/UTF8Loader.js | 110 ++++---- examples/js/loaders/VRMLLoader.js | 36 +-- examples/js/loaders/ctm/CTMLoader.js | 2 +- examples/js/loaders/ctm/ctm.js | 202 +++++++------- examples/js/loaders/ctm/lzma.js | 218 +++++++-------- examples/js/loaders/deprecated/SceneLoader.js | 2 +- examples/js/loaders/gltf/glTF-parser.js | 22 +- examples/js/loaders/gltf/glTFAnimation.js | 10 +- examples/js/loaders/gltf/glTFLoader.js | 110 ++++---- examples/js/loaders/gltf/glTFLoaderUtils.js | 16 +- examples/js/math/Lut.js | 20 +- examples/js/modifiers/SubdivisionModifier.js | 16 +- .../postprocessing/AdaptiveToneMappingPass.js | 4 +- examples/js/postprocessing/GlitchPass.js | 64 ++--- examples/js/renderers/SVGRenderer.js | 4 +- examples/js/renderers/SoftwareRenderer.js | 124 ++++----- .../js/renderers/plugins/DepthPassPlugin.js | 8 +- examples/js/shaders/BokehShader2.js | 2 +- examples/js/shaders/ConvolutionShader.js | 4 +- examples/js/shaders/FXAAShader.js | 2 +- .../js/shaders/NormalDisplacementShader.js | 2 +- examples/js/shaders/TriangleBlurShader.js | 2 +- examples/js/utils/UVsDebug.js | 6 +- examples/js/wip/ProxyGeometry.js | 44 +-- examples/js/wip/benchmark/BoxGeometry2.js | 4 +- examples/js/wip/benchmark/Geometry4.js | 2 +- examples/js/wip/proxies/MultiColor.js | 2 +- examples/js/wip/proxies/MultiVector3.js | 2 +- src/core/Object3D.js | 4 +- src/extras/FontUtils.js | 4 +- src/extras/ImageUtils.js | 2 +- src/extras/animation/Animation.js | 4 +- src/extras/core/Curve.js | 8 +- src/extras/core/CurvePath.js | 2 +- src/extras/core/Path.js | 4 +- src/extras/core/Shape.js | 24 +- src/extras/curves/SplineCurve.js | 4 +- src/extras/geometries/ExtrudeGeometry.js | 16 +- src/extras/geometries/TubeGeometry.js | 12 +- src/lights/DirectionalLight.js | 2 +- src/loaders/BinaryTextureLoader.js | 2 +- src/math/Ray.js | 2 +- src/math/Sphere.js | 2 +- src/objects/LensFlare.js | 4 +- src/objects/Line.js | 2 +- src/objects/Mesh.js | 4 +- src/objects/PointCloud.js | 2 +- src/objects/SkinnedMesh.js | 4 +- src/renderers/WebGLRenderer.js | 2 +- src/renderers/webgl/WebGLProgram.js | 2 +- .../webgl/plugins/ShadowMapPlugin.js | 2 +- 103 files changed, 1355 insertions(+), 1355 deletions(-) diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index e92e06ef8ad80b..29822577da2a92 100644 --- a/editor/js/Sidebar.Material.js +++ b/editor/js/Sidebar.Material.js @@ -463,7 +463,7 @@ Sidebar.Material = function ( editor ) { var mapEnabled = materialMapEnabled.getValue() === true; - if ( objectHasUvs ) { + if ( objectHasUvs ) { material.map = mapEnabled ? materialMap.getValue() : null; material.needsUpdate = true; @@ -480,7 +480,7 @@ Sidebar.Material = function ( editor ) { var mapEnabled = materialAlphaMapEnabled.getValue() === true; - if ( objectHasUvs ) { + if ( objectHasUvs ) { material.alphaMap = mapEnabled ? materialAlphaMap.getValue() : null; material.needsUpdate = true; @@ -516,7 +516,7 @@ Sidebar.Material = function ( editor ) { var bumpMapEnabled = materialBumpMapEnabled.getValue() === true; - if ( objectHasUvs ) { + if ( objectHasUvs ) { material.bumpMap = bumpMapEnabled ? materialBumpMap.getValue() : null; material.bumpScale = materialBumpScale.getValue(); @@ -534,7 +534,7 @@ Sidebar.Material = function ( editor ) { var normalMapEnabled = materialNormalMapEnabled.getValue() === true; - if ( objectHasUvs ) { + if ( objectHasUvs ) { material.normalMap = normalMapEnabled ? materialNormalMap.getValue() : null; material.needsUpdate = true; @@ -551,7 +551,7 @@ Sidebar.Material = function ( editor ) { var specularMapEnabled = materialSpecularMapEnabled.getValue() === true; - if ( objectHasUvs ) { + if ( objectHasUvs ) { material.specularMap = specularMapEnabled ? materialSpecularMap.getValue() : null; material.needsUpdate = true; diff --git a/editor/js/Storage.js b/editor/js/Storage.js index e4e6551f1973de..8d8533c653836b 100644 --- a/editor/js/Storage.js +++ b/editor/js/Storage.js @@ -8,7 +8,7 @@ var Storage = function () { if ( indexedDB === undefined ) { console.warn( 'Storage: IndexedDB not available.' ); - return { init: function (){}, get: function (){}, set: function (){}, clear: function (){} }; + return { init: function () {}, get: function () {}, set: function () {}, clear: function () {} }; } var name = 'threejs-editor'; diff --git a/examples/js/AudioObject.js b/examples/js/AudioObject.js index 5244ed7658342a..b71721edd6602d 100644 --- a/examples/js/AudioObject.js +++ b/examples/js/AudioObject.js @@ -40,7 +40,7 @@ THREE.AudioObject = function ( url, volume, playbackRate, loop ) { THREE.AudioObject.prototype.context = new webkitAudioContext(); - } catch( error ) { + } catch ( error ) { console.warn( "THREE.AudioObject: webkitAudioContext not found" ); return this; diff --git a/examples/js/BlendCharacter.js b/examples/js/BlendCharacter.js index c9f10b322434d0..ca7a142a95c329 100644 --- a/examples/js/BlendCharacter.js +++ b/examples/js/BlendCharacter.js @@ -22,7 +22,7 @@ THREE.BlendCharacter = function () { // Create the animations - for ( var i = 0; i < geometry.animations.length; ++i ) { + for ( var i = 0; i < geometry.animations.length; ++ i ) { var animName = geometry.animations[ i ].name; scope.animations[ animName ] = new THREE.Animation( scope, geometry.animations[ i ] ); @@ -46,7 +46,7 @@ THREE.BlendCharacter = function () { this.update = function( dt ) { - for ( var i = this.weightSchedule.length - 1; i >= 0; --i ) { + for ( var i = this.weightSchedule.length - 1; i >= 0; -- i ) { var data = this.weightSchedule[ i ]; data.timeElapsed += dt; @@ -87,7 +87,7 @@ THREE.BlendCharacter = function () { // lengths match. This is useful for smoothing out transitions that get out of // phase such as between a walk and run cycle - for ( var i = this.warpSchedule.length - 1; i >= 0; --i ) { + for ( var i = this.warpSchedule.length - 1; i >= 0; -- i ) { var data = this.warpSchedule[ i ]; data.timeElapsed += dt; diff --git a/examples/js/Car.js b/examples/js/Car.js index d4f9d66f2e917a..e54ef5daac7d8d 100644 --- a/examples/js/Car.js +++ b/examples/js/Car.js @@ -195,7 +195,7 @@ THREE.Car = function () { var forwardDelta = this.speed * delta; - this.carOrientation += ( forwardDelta * this.STEERING_RADIUS_RATIO )* this.wheelOrientation; + this.carOrientation += ( forwardDelta * this.STEERING_RADIUS_RATIO ) * this.wheelOrientation; // displacement @@ -363,8 +363,8 @@ THREE.Car = function () { }; function quadraticEaseOut( k ) { return - k * ( k - 2 ); } - function cubicEaseOut( k ) { return --k * k * k + 1; } - function circularEaseOut( k ) { return Math.sqrt( 1 - --k * k ); } + function cubicEaseOut( k ) { return -- k * k * k + 1; } + function circularEaseOut( k ) { return Math.sqrt( 1 - -- k * k ); } function sinusoidalEaseOut( k ) { return Math.sin( k * Math.PI / 2 ); } function exponentialEaseOut( k ) { return k === 1 ? 1 : - Math.pow( 2, - 10 * k ) + 1; } diff --git a/examples/js/Cloth.js b/examples/js/Cloth.js index 58d05a74e4b1be..c83a6555329478 100644 --- a/examples/js/Cloth.js +++ b/examples/js/Cloth.js @@ -48,8 +48,8 @@ var lastTime; function plane(width, height) { return function(u, v) { - var x = (u-0.5) * width; - var y = (v+0.5) * height; + var x = (u - 0.5) * width; + var y = (v + 0.5) * height; var z = 0; return new THREE.Vector3(x, y, z); @@ -94,8 +94,8 @@ var diff = new THREE.Vector3(); function satisifyConstrains(p1, p2, distance) { diff.subVectors(p2.position, p1.position); var currentDist = diff.length(); - if (currentDist==0) return; // prevents division by 0 - var correction = diff.multiplyScalar(1 - distance/currentDist); + if (currentDist == 0) return; // prevents division by 0 + var correction = diff.multiplyScalar(1 - distance / currentDist); var correctionHalf = correction.multiplyScalar(0.5); p1.position.add(correctionHalf); p2.position.sub(correctionHalf); @@ -114,47 +114,47 @@ function Cloth(w, h) { var u, v; // Create particles - for (v=0;v<=h;v++) { - for (u=0;u<=w;u++) { + for (v = 0; v <= h; v ++) { + for (u = 0; u <= w; u ++) { particles.push( - new Particle(u/w, v/h, 0, MASS) + new Particle(u / w, v / h, 0, MASS) ); } } // Structural - for (v=0;v 0.0 ) this.field[ y_offset + x ] += val; } @@ -763,38 +763,38 @@ THREE.MarchingCubes.prototype.constructor = THREE.MarchingCubes; // who in turn got them from Cory Gene Bloyd. THREE.edgeTable = new Int32Array([ -0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, +0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, -0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, +0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, -0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, +0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, -0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, +0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, -0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, +0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, -0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, +0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, -0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, +0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, -0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , +0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc, 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, -0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, +0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, -0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, +0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, -0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, +0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, -0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, +0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460, 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, -0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, +0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0, 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, -0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, +0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230, 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, -0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, +0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190, 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, -0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0]) +0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 ]) THREE.triTable = new Int32Array([ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -1052,4 +1052,4 @@ THREE.triTable = new Int32Array([ 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, --1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]); +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ]); diff --git a/examples/js/Ocean.js b/examples/js/Ocean.js index 3a28ed5ecc12e8..67869b940f8581 100644 --- a/examples/js/Ocean.js +++ b/examples/js/Ocean.js @@ -20,8 +20,8 @@ return value !== undefined ? value : defaultValue; }; options = options || {}; - this.clearColor = optionalParameter(options.CLEAR_COLOR, [1.0, 1.0, 1.0, 0.0]); - this.geometryOrigin = optionalParameter(options.GEOMETRY_ORIGIN, [-1000.0, -1000.0]); + this.clearColor = optionalParameter(options.CLEAR_COLOR, [ 1.0, 1.0, 1.0, 0.0 ]); + this.geometryOrigin = optionalParameter(options.GEOMETRY_ORIGIN, [ -1000.0, -1000.0 ]); this.sunDirectionX = optionalParameter(options.SUN_DIRECTION[0], -1.0); this.sunDirectionY = optionalParameter(options.SUN_DIRECTION[1], 1.0); this.sunDirectionZ = optionalParameter(options.SUN_DIRECTION[2], 1.0); @@ -228,8 +228,8 @@ THREE.Ocean.prototype.generateSeedPhaseTexture = function() { // Setup the seed texture this.pingPhase = true; var phaseArray = new window.Float32Array(this.resolution * this.resolution * 4); - for (var i = 0; i < this.resolution; i++) { - for (var j = 0; j < this.resolution; j++) { + for (var i = 0; i < this.resolution; i ++) { + for (var j = 0; j < this.resolution; j ++) { phaseArray[i * this.resolution * 4 + j * 4] = Math.random() * 2.0 * Math.PI; phaseArray[i * this.resolution * 4 + j * 4 + 1] = 0.0; phaseArray[i * this.resolution * 4 + j * 4 + 2] = 0.0; @@ -283,7 +283,7 @@ THREE.Ocean.prototype.renderSpectrumFFT = function() { this.scene.overrideMaterial = this.materialOceanHorizontal; - for (var i = 0; i < iterations; i++) { + for (var i = 0; i < iterations; i ++) { if (i === 0) { this.materialOceanHorizontal.uniforms.u_input.value = this.spectrumFramebuffer; this.materialOceanHorizontal.uniforms.u_subtransformSize.value = Math.pow(2, (i % (iterations)) + 1); @@ -301,7 +301,7 @@ THREE.Ocean.prototype.renderSpectrumFFT = function() { } } this.scene.overrideMaterial = this.materialOceanVertical; - for (var i = iterations; i < iterations*2; i++) { + for (var i = iterations; i < iterations * 2; i ++) { if (i === iterations * 2 - 1) { this.materialOceanVertical.uniforms.u_input.value = (iterations % 2 === 0) ? this.pingTransformFramebuffer : this.pongTransformFramebuffer; this.materialOceanVertical.uniforms.u_subtransformSize.value = Math.pow(2, (i % (iterations)) + 1); diff --git a/examples/js/Octree.js b/examples/js/Octree.js index 58aedb2ecbbaa7..918dedc222fcfa 100644 --- a/examples/js/Octree.js +++ b/examples/js/Octree.js @@ -29,7 +29,7 @@ function indexOfValue( array, value ) { - for ( var i = 0, il = array.length; i < il; i++ ) { + for ( var i = 0, il = array.length; i < il; i ++ ) { if ( array[ i ] === value ) { @@ -45,7 +45,7 @@ function indexOfPropertyWithValue( array, property, value ) { - for ( var i = 0, il = array.length; i < il; i++ ) { + for ( var i = 0, il = array.length; i < il; i ++ ) { if ( array[ i ][ property ] === value ) { @@ -140,7 +140,7 @@ if ( this.objectsDeferred.length > 0 ) { - for ( var i = 0, il = this.objectsDeferred.length; i < il; i++ ) { + for ( var i = 0, il = this.objectsDeferred.length; i < il; i ++ ) { var deferred = this.objectsDeferred[ i ]; @@ -221,7 +221,7 @@ geometry = object.geometry; vertices = geometry.vertices; - for ( i = 0, l = vertices.length; i < l; i++ ) { + for ( i = 0, l = vertices.length; i < l; i ++ ) { this.addObjectData( object, vertices[ i ] ); @@ -232,7 +232,7 @@ geometry = object.geometry; faces = geometry.faces; - for ( i = 0, l = faces.length; i < l; i++ ) { + for ( i = 0, l = faces.length; i < l; i ++ ) { this.addObjectData( object, faces[ i ] ); @@ -297,7 +297,7 @@ // remove from objects data list - for ( i = 0, l = objectsDataRemoved.length; i < l; i++ ) { + for ( i = 0, l = objectsDataRemoved.length; i < l; i ++ ) { objectData = objectsDataRemoved[ i ]; @@ -341,7 +341,7 @@ objectsData = octree.objectsData; - for ( i = 0, l = objectsData.length; i < l; i++ ) { + for ( i = 0, l = objectsData.length; i < l; i ++ ) { objectData = objectsData[ i ]; @@ -366,7 +366,7 @@ // check all object data for changes in position // assumes all object matrices are up to date - for ( i = 0, l = this.objectsData.length; i < l; i++ ) { + for ( i = 0, l = this.objectsData.length; i < l; i ++ ) { objectData = this.objectsData[ i ]; @@ -402,7 +402,7 @@ // update changed objects - for ( i = 0, l = objectsUpdate.length; i < l; i++ ) { + for ( i = 0, l = objectsUpdate.length; i < l; i ++ ) { objectData = objectsUpdate[ i ]; @@ -429,14 +429,14 @@ parent = object.parent; - while( parent ) { + while ( parent ) { parentCascade.push( parent ); parent = parent.parent; } - for ( i = 0, l = parentCascade.length; i < l; i++ ) { + for ( i = 0, l = parentCascade.length; i < l; i ++ ) { parent = parentCascade[ i ]; @@ -494,7 +494,7 @@ // search each node of root - for ( i = 0, l = this.root.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.root.nodesIndices.length; i < l; i ++ ) { node = this.root.nodesByIndex[ this.root.nodesIndices[ i ] ]; @@ -511,7 +511,7 @@ // for each object data found - for ( i = 0, l = objects.length; i < l; i++ ) { + for ( i = 0, l = objects.length; i < l; i ++ ) { objectData = objects[ i ]; object = objectData.object; @@ -739,7 +739,7 @@ // basic properties - this.id = this.tree.nodeCount++; + this.id = this.tree.nodeCount ++; this.position = parameters.position instanceof THREE.Vector3 ? parameters.position : new THREE.Vector3(); this.radius = parameters.radius > 0 ? parameters.radius : 1; this.indexOctant = parameters.indexOctant; @@ -811,7 +811,7 @@ // cascade - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { this.nodesByIndex[ this.nodesIndices[ i ] ].updateProperties(); @@ -832,7 +832,7 @@ // unset parent in nodes - for ( i = 0, l = nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = nodesIndices.length; i < l; i ++ ) { node = nodesByIndex[ nodesIndices[ i ] ]; @@ -949,7 +949,7 @@ var i, l, object; - for ( i = 0, l = objects.length; i < l; i++ ) { + for ( i = 0, l = objects.length; i < l; i ++ ) { object = objects[ i ]; @@ -977,7 +977,7 @@ if ( nodesRemovedFrom.length > 0 ) { - for ( i = 0, l = nodesRemovedFrom.length; i < l; i++ ) { + for ( i = 0, l = nodesRemovedFrom.length; i < l; i ++ ) { nodesRemovedFrom[ i ].shrink(); @@ -1021,7 +1021,7 @@ // search each object data for object and remove (slow) - for ( i = this.objects.length - 1; i >= 0; i-- ) { + for ( i = this.objects.length - 1; i >= 0; i -- ) { objectData = this.objects[ i ]; @@ -1059,7 +1059,7 @@ if ( removeData.searchComplete !== true ) { - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { node = this.nodesByIndex[ this.nodesIndices[ i ] ]; @@ -1106,7 +1106,7 @@ // for each object - for ( i = 0, l = this.objects.length; i < l; i++ ) { + for ( i = 0, l = this.objects.length; i < l; i ++ ) { object = this.objects[ i ]; @@ -1183,7 +1183,7 @@ // for each object - for ( i = 0, l = objects.length; i < l; i++ ) { + for ( i = 0, l = objects.length; i < l; i ++ ) { object = objects[ i ]; @@ -1314,7 +1314,7 @@ // reset counts - for ( i = 0, l = iom.length; i < l; i++ ) { + for ( i = 0, l = iom.length; i < l; i ++ ) { iom[ i ].count = 0; @@ -1322,7 +1322,7 @@ // for all outside objects, find outside octants containing most objects - for ( i = 0, l = objects.length; i < l; i++ ) { + for ( i = 0, l = objects.length; i < l; i ++ ) { object = objects[ i ]; @@ -1344,11 +1344,11 @@ if ( flagsOutside & this.tree.FLAG_POS_X ) { - iom[ this.tree.INDEX_OUTSIDE_POS_X ].count++; + iom[ this.tree.INDEX_OUTSIDE_POS_X ].count ++; } else if ( flagsOutside & this.tree.FLAG_NEG_X ) { - iom[ this.tree.INDEX_OUTSIDE_NEG_X ].count++; + iom[ this.tree.INDEX_OUTSIDE_NEG_X ].count ++; } @@ -1356,11 +1356,11 @@ if ( flagsOutside & this.tree.FLAG_POS_Y ) { - iom[ this.tree.INDEX_OUTSIDE_POS_Y ].count++; + iom[ this.tree.INDEX_OUTSIDE_POS_Y ].count ++; } else if ( flagsOutside & this.tree.FLAG_NEG_Y ) { - iom[ this.tree.INDEX_OUTSIDE_NEG_Y ].count++; + iom[ this.tree.INDEX_OUTSIDE_NEG_Y ].count ++; } @@ -1368,11 +1368,11 @@ if ( flagsOutside & this.tree.FLAG_POS_Z ) { - iom[ this.tree.INDEX_OUTSIDE_POS_Z ].count++; + iom[ this.tree.INDEX_OUTSIDE_POS_Z ].count ++; } else if ( flagsOutside & this.tree.FLAG_NEG_Z ) { - iom[ this.tree.INDEX_OUTSIDE_NEG_Z ].count++; + iom[ this.tree.INDEX_OUTSIDE_NEG_Z ].count ++; } @@ -1474,7 +1474,7 @@ // add all expand objects to parent - for ( i = 0, l = objectsExpand.length; i < l; i++ ) { + for ( i = 0, l = objectsExpand.length; i < l; i ++ ) { this.tree.root.addObject( objectsExpand[ i ] ); @@ -1546,7 +1546,7 @@ nodes = toArray( nodes ); - for ( i = 0, l = nodes.length; i < l; i++ ) { + for ( i = 0, l = nodes.length; i < l; i ++ ) { node = nodes[ i ]; @@ -1586,7 +1586,7 @@ nodeHeaviestObjectsCount = 0; outsideHeaviestObjectsCount = this.objects.length; - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { node = this.nodesByIndex[ this.nodesIndices[ i ] ]; @@ -1625,7 +1625,7 @@ // handle all nodes - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { node = this.nodesByIndex[ this.nodesIndices[ i ] ]; @@ -1848,7 +1848,7 @@ // search subtree - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { node = this.nodesByIndex[ this.nodesIndices[ i ] ]; @@ -1917,7 +1917,7 @@ tmin = Math.max( Math.max( Math.min( t1, t2), Math.min( t3, t4)), Math.min( t5, t6)); // if tmin > tmax or tmin > ray distance, ray doesn't intersect AABB - if( tmin > tmax || tmin > distance ) { + if ( tmin > tmax || tmin > distance ) { return false; } @@ -1932,7 +1932,7 @@ if ( this.nodesIndices.length > 0 ) { - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { node = this.nodesByIndex[ this.nodesIndices[ i ] ]; @@ -1961,7 +1961,7 @@ var i, l, count = this.nodesIndices.length; - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { count += this.nodesByIndex[ this.nodesIndices[ i ] ].getNodeCountRecursive(); @@ -1978,7 +1978,7 @@ objects = ( objects || [] ).concat( this.objects ); - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { node = this.nodesByIndex[ this.nodesIndices[ i ] ]; @@ -1995,7 +1995,7 @@ var i, l, count = this.objects.length; - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { count += this.nodesByIndex[ this.nodesIndices[ i ] ].getObjectCountEnd(); @@ -2010,7 +2010,7 @@ var count = this.objects.length, parent = this.parent; - while( parent instanceof THREE.OctreeNode ) { + while ( parent instanceof THREE.OctreeNode ) { count += parent.objects.length; parent = parent.parent; @@ -2033,7 +2033,7 @@ console.log( ( this.parent ? space + ' ' : ' ' ), '+ objects ( ', this.objects.length, ' ) ', this.objects ); console.log( ( this.parent ? space + ' ' : ' ' ), '+ children ( ', this.nodesIndices.length, ' )', this.nodesIndices, this.nodesByIndex ); - for ( i = 0, l = this.nodesIndices.length; i < l; i++ ) { + for ( i = 0, l = this.nodesIndices.length; i < l; i ++ ) { node = this.nodesByIndex[ this.nodesIndices[ i ] ]; @@ -2101,7 +2101,7 @@ var i, il, intersects = []; - for ( i = 0, il = objects.length; i < il; i++ ) { + for ( i = 0, il = objects.length; i < il; i ++ ) { intersects = intersects.concat( this.intersectOctreeObject( objects[ i ], recursive ) ); diff --git a/examples/js/ParametricGeometries.js b/examples/js/ParametricGeometries.js index 12fda92fb89d49..41cf6aab9b45ec 100644 --- a/examples/js/ParametricGeometries.js +++ b/examples/js/ParametricGeometries.js @@ -48,9 +48,9 @@ THREE.ParametricGeometries = { var x, y, z; var a = 2; - x = Math.cos(v) * (a + u * Math.cos(v/2)); - y = Math.sin(v) * (a + u * Math.cos(v/2)); - z = u * Math.sin(v/2); + x = Math.cos(v) * (a + u * Math.cos(v / 2)); + y = Math.sin(v) * (a + u * Math.cos(v / 2)); + z = u * Math.sin(v / 2); return new THREE.Vector3(x, y, z); }, diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index 51e939de2afe46..4744f45d0d716a 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -217,7 +217,7 @@ THREE.ShaderTerrain = { "#if MAX_HEMI_LIGHTS > 0", "vec3 hemiDiffuse = vec3( 0.0 );", - "vec3 hemiSpecular = vec3( 0.0 );" , + "vec3 hemiSpecular = vec3( 0.0 );", "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {", diff --git a/examples/js/SimplexNoise.js b/examples/js/SimplexNoise.js index 0638192fcbf4a5..d0952c1979d5d6 100644 --- a/examples/js/SimplexNoise.js +++ b/examples/js/SimplexNoise.js @@ -13,72 +13,72 @@ */ var SimplexNoise = function(r) { if (r == undefined) r = Math; - this.grad3 = [[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0], - [1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1], - [0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]]; + this.grad3 = [[ 1,1,0 ],[ -1,1,0 ],[ 1,-1,0 ],[ -1,-1,0 ], + [ 1,0,1 ],[ -1,0,1 ],[ 1,0,-1 ],[ -1,0,-1 ], + [ 0,1,1 ],[ 0,-1,1 ],[ 0,1,-1 ],[ 0,-1,-1 ]]; - this.grad4 = [[0,1,1,1], [0,1,1,-1], [0,1,-1,1], [0,1,-1,-1], - [0,-1,1,1], [0,-1,1,-1], [0,-1,-1,1], [0,-1,-1,-1], - [1,0,1,1], [1,0,1,-1], [1,0,-1,1], [1,0,-1,-1], - [-1,0,1,1], [-1,0,1,-1], [-1,0,-1,1], [-1,0,-1,-1], - [1,1,0,1], [1,1,0,-1], [1,-1,0,1], [1,-1,0,-1], - [-1,1,0,1], [-1,1,0,-1], [-1,-1,0,1], [-1,-1,0,-1], - [1,1,1,0], [1,1,-1,0], [1,-1,1,0], [1,-1,-1,0], - [-1,1,1,0], [-1,1,-1,0], [-1,-1,1,0], [-1,-1,-1,0]]; + this.grad4 = [[ 0,1,1,1 ], [ 0,1,1,-1 ], [ 0,1,-1,1 ], [ 0,1,-1,-1 ], + [ 0,-1,1,1 ], [ 0,-1,1,-1 ], [ 0,-1,-1,1 ], [ 0,-1,-1,-1 ], + [ 1,0,1,1 ], [ 1,0,1,-1 ], [ 1,0,-1,1 ], [ 1,0,-1,-1 ], + [ -1,0,1,1 ], [ -1,0,1,-1 ], [ -1,0,-1,1 ], [ -1,0,-1,-1 ], + [ 1,1,0,1 ], [ 1,1,0,-1 ], [ 1,-1,0,1 ], [ 1,-1,0,-1 ], + [ -1,1,0,1 ], [ -1,1,0,-1 ], [ -1,-1,0,1 ], [ -1,-1,0,-1 ], + [ 1,1,1,0 ], [ 1,1,-1,0 ], [ 1,-1,1,0 ], [ 1,-1,-1,0 ], + [ -1,1,1,0 ], [ -1,1,-1,0 ], [ -1,-1,1,0 ], [ -1,-1,-1,0 ]]; this.p = []; - for (var i=0; i<256; i++) { - this.p[i] = Math.floor(r.random()*256); + for (var i = 0; i < 256; i ++) { + this.p[i] = Math.floor(r.random() * 256); } // To remove the need for index wrapping, double the permutation table length this.perm = []; - for(var i=0; i<512; i++) { - this.perm[i]=this.p[i & 255]; + for (var i = 0; i < 512; i ++) { + this.perm[i] = this.p[i & 255]; } // A lookup table to traverse the simplex around a given point in 4D. // Details can be found where this table is used, in the 4D noise method. this.simplex = [ - [0,1,2,3],[0,1,3,2],[0,0,0,0],[0,2,3,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,3,0], - [0,2,1,3],[0,0,0,0],[0,3,1,2],[0,3,2,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,3,2,0], - [0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0], - [1,2,0,3],[0,0,0,0],[1,3,0,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,3,0,1],[2,3,1,0], - [1,0,2,3],[1,0,3,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,3,1],[0,0,0,0],[2,1,3,0], - [0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0], - [2,0,1,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,0,1,2],[3,0,2,1],[0,0,0,0],[3,1,2,0], - [2,1,0,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,1,0,2],[0,0,0,0],[3,2,0,1],[3,2,1,0]]; + [ 0,1,2,3 ],[ 0,1,3,2 ],[ 0,0,0,0 ],[ 0,2,3,1 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 1,2,3,0 ], + [ 0,2,1,3 ],[ 0,0,0,0 ],[ 0,3,1,2 ],[ 0,3,2,1 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 1,3,2,0 ], + [ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ], + [ 1,2,0,3 ],[ 0,0,0,0 ],[ 1,3,0,2 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 2,3,0,1 ],[ 2,3,1,0 ], + [ 1,0,2,3 ],[ 1,0,3,2 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 2,0,3,1 ],[ 0,0,0,0 ],[ 2,1,3,0 ], + [ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ], + [ 2,0,1,3 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 3,0,1,2 ],[ 3,0,2,1 ],[ 0,0,0,0 ],[ 3,1,2,0 ], + [ 2,1,0,3 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 3,1,0,2 ],[ 0,0,0,0 ],[ 3,2,0,1 ],[ 3,2,1,0 ]]; }; SimplexNoise.prototype.dot = function(g, x, y) { - return g[0]*x + g[1]*y; + return g[0] * x + g[1] * y; }; SimplexNoise.prototype.dot3 = function(g, x, y, z) { - return g[0]*x + g[1]*y + g[2]*z; + return g[0] * x + g[1] * y + g[2] * z; } SimplexNoise.prototype.dot4 = function(g, x, y, z, w) { - return g[0]*x + g[1]*y + g[2]*z + g[3]*w; + return g[0] * x + g[1] * y + g[2] * z + g[3] * w; }; SimplexNoise.prototype.noise = function(xin, yin) { var n0, n1, n2; // Noise contributions from the three corners // Skew the input space to determine which simplex cell we're in - var F2 = 0.5*(Math.sqrt(3.0)-1.0); - var s = (xin+yin)*F2; // Hairy factor for 2D - var i = Math.floor(xin+s); - var j = Math.floor(yin+s); - var G2 = (3.0-Math.sqrt(3.0))/6.0; - var t = (i+j)*G2; - var X0 = i-t; // Unskew the cell origin back to (x,y) space - var Y0 = j-t; - var x0 = xin-X0; // The x,y distances from the cell origin - var y0 = yin-Y0; + var F2 = 0.5 * (Math.sqrt(3.0) - 1.0); + var s = (xin + yin) * F2; // Hairy factor for 2D + var i = Math.floor(xin + s); + var j = Math.floor(yin + s); + var G2 = (3.0 - Math.sqrt(3.0)) / 6.0; + var t = (i + j) * G2; + var X0 = i - t; // Unskew the cell origin back to (x,y) space + var Y0 = j - t; + var x0 = xin - X0; // The x,y distances from the cell origin + var y0 = yin - Y0; // For the 2D case, the simplex shape is an equilateral triangle. // Determine which simplex we are in. var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords - if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1) - else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1) + if (x0 > y0) {i1 = 1; j1 = 0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1) + else {i1 = 0; j1 = 1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1) // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where // c = (3-sqrt(3))/6 @@ -89,24 +89,24 @@ SimplexNoise.prototype.noise = function(xin, yin) { // Work out the hashed gradient indices of the three simplex corners var ii = i & 255; var jj = j & 255; - var gi0 = this.perm[ii+this.perm[jj]] % 12; - var gi1 = this.perm[ii+i1+this.perm[jj+j1]] % 12; - var gi2 = this.perm[ii+1+this.perm[jj+1]] % 12; + var gi0 = this.perm[ii + this.perm[jj]] % 12; + var gi1 = this.perm[ii + i1 + this.perm[jj + j1]] % 12; + var gi2 = this.perm[ii + 1 + this.perm[jj + 1]] % 12; // Calculate the contribution from the three corners - var t0 = 0.5 - x0*x0-y0*y0; - if(t0<0) n0 = 0.0; + var t0 = 0.5 - x0 * x0 - y0 * y0; + if (t0 < 0) n0 = 0.0; else { t0 *= t0; n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient } - var t1 = 0.5 - x1*x1-y1*y1; - if(t1<0) n1 = 0.0; + var t1 = 0.5 - x1 * x1 - y1 * y1; + if (t1 < 0) n1 = 0.0; else { t1 *= t1; n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1); } - var t2 = 0.5 - x2*x2-y2*y2; - if(t2<0) n2 = 0.0; + var t2 = 0.5 - x2 * x2 - y2 * y2; + if (t2 < 0) n2 = 0.0; else { t2 *= t2; n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2); @@ -120,33 +120,33 @@ SimplexNoise.prototype.noise = function(xin, yin) { SimplexNoise.prototype.noise3d = function(xin, yin, zin) { var n0, n1, n2, n3; // Noise contributions from the four corners // Skew the input space to determine which simplex cell we're in - var F3 = 1.0/3.0; - var s = (xin+yin+zin)*F3; // Very nice and simple skew factor for 3D - var i = Math.floor(xin+s); - var j = Math.floor(yin+s); - var k = Math.floor(zin+s); - var G3 = 1.0/6.0; // Very nice and simple unskew factor, too - var t = (i+j+k)*G3; - var X0 = i-t; // Unskew the cell origin back to (x,y,z) space - var Y0 = j-t; - var Z0 = k-t; - var x0 = xin-X0; // The x,y,z distances from the cell origin - var y0 = yin-Y0; - var z0 = zin-Z0; + var F3 = 1.0 / 3.0; + var s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D + var i = Math.floor(xin + s); + var j = Math.floor(yin + s); + var k = Math.floor(zin + s); + var G3 = 1.0 / 6.0; // Very nice and simple unskew factor, too + var t = (i + j + k) * G3; + var X0 = i - t; // Unskew the cell origin back to (x,y,z) space + var Y0 = j - t; + var Z0 = k - t; + var x0 = xin - X0; // The x,y,z distances from the cell origin + var y0 = yin - Y0; + var z0 = zin - Z0; // For the 3D case, the simplex shape is a slightly irregular tetrahedron. // Determine which simplex we are in. var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords - if(x0>=y0) { - if(y0>=z0) - { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order - else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order - else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order + if (x0 >= y0) { + if (y0 >= z0) + { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } // X Y Z order + else if (x0 >= z0) { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1; } // X Z Y order + else { i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1; } // Z X Y order } else { // x0=3 ? 1 : 0; - j1 = simplex[c][1]>=3 ? 1 : 0; - k1 = simplex[c][2]>=3 ? 1 : 0; - l1 = simplex[c][3]>=3 ? 1 : 0; + i1 = simplex[c][0] >= 3 ? 1 : 0; + j1 = simplex[c][1] >= 3 ? 1 : 0; + k1 = simplex[c][2] >= 3 ? 1 : 0; + l1 = simplex[c][3] >= 3 ? 1 : 0; // The number 2 in the "simplex" array is at the second largest coordinate. - i2 = simplex[c][0]>=2 ? 1 : 0; - j2 = simplex[c][1]>=2 ? 1 : 0; k2 = simplex[c][2]>=2 ? 1 : 0; - l2 = simplex[c][3]>=2 ? 1 : 0; + i2 = simplex[c][0] >= 2 ? 1 : 0; + j2 = simplex[c][1] >= 2 ? 1 : 0; k2 = simplex[c][2] >= 2 ? 1 : 0; + l2 = simplex[c][3] >= 2 ? 1 : 0; // The number 1 in the "simplex" array is at the second smallest coordinate. - i3 = simplex[c][0]>=1 ? 1 : 0; - j3 = simplex[c][1]>=1 ? 1 : 0; - k3 = simplex[c][2]>=1 ? 1 : 0; - l3 = simplex[c][3]>=1 ? 1 : 0; + i3 = simplex[c][0] >= 1 ? 1 : 0; + j3 = simplex[c][1] >= 1 ? 1 : 0; + k3 = simplex[c][2] >= 1 ? 1 : 0; + l3 = simplex[c][3] >= 1 ? 1 : 0; // The fifth corner has all coordinate offsets = 1, so no need to look that up. var x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords var y1 = y0 - j1 + G4; var z1 = z0 - k1 + G4; var w1 = w0 - l1 + G4; - var x2 = x0 - i2 + 2.0*G4; // Offsets for third corner in (x,y,z,w) coords - var y2 = y0 - j2 + 2.0*G4; - var z2 = z0 - k2 + 2.0*G4; - var w2 = w0 - l2 + 2.0*G4; - var x3 = x0 - i3 + 3.0*G4; // Offsets for fourth corner in (x,y,z,w) coords - var y3 = y0 - j3 + 3.0*G4; - var z3 = z0 - k3 + 3.0*G4; - var w3 = w0 - l3 + 3.0*G4; - var x4 = x0 - 1.0 + 4.0*G4; // Offsets for last corner in (x,y,z,w) coords - var y4 = y0 - 1.0 + 4.0*G4; - var z4 = z0 - 1.0 + 4.0*G4; - var w4 = w0 - 1.0 + 4.0*G4; + var x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords + var y2 = y0 - j2 + 2.0 * G4; + var z2 = z0 - k2 + 2.0 * G4; + var w2 = w0 - l2 + 2.0 * G4; + var x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords + var y3 = y0 - j3 + 3.0 * G4; + var z3 = z0 - k3 + 3.0 * G4; + var w3 = w0 - l3 + 3.0 * G4; + var x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords + var y4 = y0 - 1.0 + 4.0 * G4; + var z4 = z0 - 1.0 + 4.0 * G4; + var w4 = w0 - 1.0 + 4.0 * G4; // Work out the hashed gradient indices of the five simplex corners var ii = i & 255; var jj = j & 255; var kk = k & 255; var ll = l & 255; - var gi0 = perm[ii+perm[jj+perm[kk+perm[ll]]]] % 32; - var gi1 = perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]] % 32; - var gi2 = perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]] % 32; - var gi3 = perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]] % 32; - var gi4 = perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]] % 32; + var gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32; + var gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32; + var gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32; + var gi3 = perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32; + var gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; // Calculate the contribution from the five corners - var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0 - w0*w0; - if(t0<0) n0 = 0.0; + var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; + if (t0 < 0) n0 = 0.0; else { t0 *= t0; n0 = t0 * t0 * this.dot4(grad4[gi0], x0, y0, z0, w0); } - var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1 - w1*w1; - if(t1<0) n1 = 0.0; + var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; + if (t1 < 0) n1 = 0.0; else { t1 *= t1; n1 = t1 * t1 * this.dot4(grad4[gi1], x1, y1, z1, w1); } - var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2 - w2*w2; - if(t2<0) n2 = 0.0; + var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; + if (t2 < 0) n2 = 0.0; else { t2 *= t2; n2 = t2 * t2 * this.dot4(grad4[gi2], x2, y2, z2, w2); - } var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3 - w3*w3; - if(t3<0) n3 = 0.0; + } var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; + if (t3 < 0) n3 = 0.0; else { t3 *= t3; n3 = t3 * t3 * this.dot4(grad4[gi3], x3, y3, z3, w3); } - var t4 = 0.6 - x4*x4 - y4*y4 - z4*z4 - w4*w4; - if(t4<0) n4 = 0.0; + var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; + if (t4 < 0) n4 = 0.0; else { t4 *= t4; n4 = t4 * t4 * this.dot4(grad4[gi4], x4, y4, z4, w4); diff --git a/examples/js/SimulationRenderer.js b/examples/js/SimulationRenderer.js index 8c43ddd1cb712c..fbca006233a662 100644 --- a/examples/js/SimulationRenderer.js +++ b/examples/js/SimulationRenderer.js @@ -19,12 +19,12 @@ function SimulationRenderer(WIDTH, renderer) { // Init RTT stuff gl = renderer.getContext(); - if( !gl.getExtension( "OES_texture_float" )) { + if ( !gl.getExtension( "OES_texture_float" )) { alert( "No OES_texture_float support for float textures!" ); return; } - if( gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) == 0) { + if ( gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) == 0) { alert( "No support for vertex shader textures!" ); return; } diff --git a/examples/js/Sparks.js b/examples/js/Sparks.js index a3de804b13c6f8..5d2fdea3e82c1a 100644 --- a/examples/js/Sparks.js +++ b/examples/js/Sparks.js @@ -77,14 +77,14 @@ SPARKS.Emitter.prototype = { elapsed = maxBlock; } - while(elapsed >= emitter._TIMESTEP) { + while (elapsed >= emitter._TIMESTEP) { emitter.update(emitter._TIMESTEP / 1000); elapsed -= emitter._TIMESTEP; } emitter._lastTime = time - elapsed; } else { - emitter.update(elapsed/1000); + emitter.update(elapsed / 1000); emitter._lastTime = time; } @@ -103,13 +103,13 @@ SPARKS.Emitter.prototype = { var len = this._counter.updateEmitter( this, time ); // Create particles - for( i = 0; i < len; i++ ) { + for ( i = 0; i < len; i ++ ) { this.createParticle(); } // Update activities len = this._activities.length; - for ( i = 0; i < len; i++ ) + for ( i = 0; i < len; i ++ ) { this._activities[i].update( this, time ); } @@ -121,10 +121,10 @@ SPARKS.Emitter.prototype = { var action; var len2 = this._particles.length; - for( j = 0; j < len; j++ ) + for ( j = 0; j < len; j ++ ) { action = this._actions[j]; - for ( i = 0; i < len2; ++i ) + for ( i = 0; i < len2; ++ i ) { particle = this._particles[i]; action.update( this, particle, time ); @@ -133,7 +133,7 @@ SPARKS.Emitter.prototype = { // remove dead particles - for ( i = len2; i--; ) + for ( i = len2; i --; ) { particle = this._particles[i]; if ( particle.isDead ) @@ -158,7 +158,7 @@ SPARKS.Emitter.prototype = { // In future, use a Particle Factory var len = this._initializers.length, i; - for ( i = 0; i < len; i++ ) { + for ( i = 0; i < len; i ++ ) { this._initializers[i].initialize( this, particle ); } @@ -300,9 +300,9 @@ SPARKS.Particle = function() { * For 3D */ - this.position = SPARKS.VectorPool.get().set(0,0,0); //new THREE.Vector3( 0, 0, 0 ); - this.velocity = SPARKS.VectorPool.get().set(0,0,0); //new THREE.Vector3( 0, 0, 0 ); - this._oldvelocity = SPARKS.VectorPool.get().set(0,0,0); + this.position = SPARKS.VectorPool.get().set(0, 0, 0); //new THREE.Vector3( 0, 0, 0 ); + this.velocity = SPARKS.VectorPool.get().set(0, 0, 0); //new THREE.Vector3( 0, 0, 0 ); + this._oldvelocity = SPARKS.VectorPool.get().set(0, 0, 0); // rotation vec3 // angVelocity vec3 // faceAxis vec3 @@ -327,7 +327,7 @@ SPARKS.Age = function(easing) { SPARKS.Age.prototype.update = function (emitter, particle, time) { particle.age += time; - if( particle.age >= particle.lifetime ) + if ( particle.age >= particle.lifetime ) { particle.energy = 0; particle.isDead = true; @@ -451,7 +451,7 @@ SPARKS.AccelerateFactor.prototype.update = function(emitter, particle, time) { var v = particle.velocity; var len = v.length(); var adjFactor; - if (len>0) { + if (len > 0) { adjFactor = factor * time / len; adjFactor += 1; @@ -595,17 +595,17 @@ SPARKS.CubeZone.prototype.contains = function(position) { var y = this.y; // depth var z = this.z; // height - if (x<0) { + if (x < 0) { startX += x; x = Math.abs(x); } - if (y<0) { + if (y < 0) { startY += y; y = Math.abs(y); } - if (z<0) { + if (z < 0) { startZ += z; z = Math.abs(z); } @@ -683,7 +683,7 @@ SPARKS.SphereCapZone = function(x, y, z, minr, maxr, angle) { }; SPARKS.SphereCapZone.prototype.getLocation = function() { - var theta = Math.PI *2 * SPARKS.Utils.random(); + var theta = Math.PI * 2 * SPARKS.Utils.random(); var r = SPARKS.Utils.random(); //new THREE.Vector3 @@ -691,7 +691,7 @@ SPARKS.SphereCapZone.prototype.getLocation = function() { //v.length = StardustMath.interpolate(0, _minRadius, 1, _maxRadius, Math.random()); - var i = this.minr - ((this.minr-this.maxr) * Math.random() ); + var i = this.minr - ((this.minr - this.maxr) * Math.random() ); v.multiplyScalar(i); v.__markedForReleased = true; @@ -769,7 +769,7 @@ SPARKS.VectorPool = { // Get a new Vector get: function() { - if (this.__pools.length>0) { + if (this.__pools.length > 0) { return this.__pools.pop(); } @@ -786,7 +786,7 @@ SPARKS.VectorPool = { _addToPool: function() { //console.log("creating some pools"); - for (var i=0, size = 100; i < size; i++) { + for (var i = 0, size = 100; i < size; i ++) { this.__pools.push(new THREE.Vector3()); } @@ -821,7 +821,7 @@ SPARKS.Utils = { getPerpendicular: function( v ) { - if( v.x == 0 ) + if ( v.x == 0 ) { return new THREE.Vector3D( 1, 0, 0 ); } diff --git a/examples/js/TypedArrayUtils.js b/examples/js/TypedArrayUtils.js index 2bfa8491c1fc45..4f3560fb77b2ee 100644 --- a/examples/js/TypedArrayUtils.js +++ b/examples/js/TypedArrayUtils.js @@ -33,8 +33,8 @@ THREE.TypedArrayUtils.quicksortIP = function ( arr, eleSize, orderElement ) { for ( y = 0; y < eleSize; y ++ ) { tmp = arr[ a + y ]; - arr[ a + y ]=arr[ b + y ]; - arr[ b + y ]=tmp; + arr[ a + y ] = arr[ b + y ]; + arr[ b + y ] = tmp; } @@ -46,7 +46,7 @@ THREE.TypedArrayUtils.quicksortIP = function ( arr, eleSize, orderElement ) { if ( right - left <= 25 ) { - for ( j= left + 1; j <= right; j ++ ) { + for ( j = left + 1; j <= right; j ++ ) { for ( x = 0; x < eleSize; x ++ ) { @@ -214,7 +214,7 @@ THREE.TypedArrayUtils.quicksortIP = function ( arr, eleSize, orderElement ) { median = Math.floor( plength / 2 ); - node = new self.Node( getPointSet( points, median ) , depth, parent, median + pos ); + node = new self.Node( getPointSet( points, median ), depth, parent, median + pos ); node.left = buildTree( points.subarray( 0, median * eleSize), depth + 1, node, pos ); node.right = buildTree( points.subarray( ( median + 1 ) * eleSize, points.length ), depth + 1, node, pos + median + 1 ); @@ -226,7 +226,7 @@ THREE.TypedArrayUtils.quicksortIP = function ( arr, eleSize, orderElement ) { this.getMaxDepth = function () { return maxDepth; }; - this.nearest = function ( point, maxNodes , maxDistance ) { + this.nearest = function ( point, maxNodes, maxDistance ) { /* point: array of size eleSize maxNodes: max amount of nodes to return diff --git a/examples/js/cameras/CombinedCamera.js b/examples/js/cameras/CombinedCamera.js index dfd79828b1023c..77da6e06c53f6d 100644 --- a/examples/js/cameras/CombinedCamera.js +++ b/examples/js/cameras/CombinedCamera.js @@ -29,7 +29,7 @@ THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orth this.toPerspective(); - var aspect = width/height; + var aspect = width / height; }; diff --git a/examples/js/controls/EditorControls.js b/examples/js/controls/EditorControls.js index 1b301ae03ae728..6a12707a7ff4f1 100644 --- a/examples/js/controls/EditorControls.js +++ b/examples/js/controls/EditorControls.js @@ -262,7 +262,7 @@ THREE.EditorControls = function ( object, domElement ) { case 1: touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ); touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ); - scope.rotate( touches[ 0 ].sub( getClosest( touches[ 0 ] ,prevTouches ) ).multiplyScalar( - 0.005 ) ); + scope.rotate( touches[ 0 ].sub( getClosest( touches[ 0 ], prevTouches ) ).multiplyScalar( - 0.005 ) ); break; case 2: @@ -273,8 +273,8 @@ THREE.EditorControls = function ( object, domElement ) { prevDistance = distance; - var offset0 = touches[ 0 ].clone().sub( getClosest( touches[ 0 ] ,prevTouches ) ); - var offset1 = touches[ 1 ].clone().sub( getClosest( touches[ 1 ] ,prevTouches ) ); + var offset0 = touches[ 0 ].clone().sub( getClosest( touches[ 0 ], prevTouches ) ); + var offset1 = touches[ 1 ].clone().sub( getClosest( touches[ 1 ], prevTouches ) ); offset0.x = -offset0.x; offset1.x = -offset1.x; diff --git a/examples/js/controls/FirstPersonControls.js b/examples/js/controls/FirstPersonControls.js index 7c074b822e951b..e152489ea805e3 100644 --- a/examples/js/controls/FirstPersonControls.js +++ b/examples/js/controls/FirstPersonControls.js @@ -163,7 +163,7 @@ THREE.FirstPersonControls = function ( object, domElement ) { this.onKeyUp = function ( event ) { - switch( event.keyCode ) { + switch ( event.keyCode ) { case 38: /*up*/ case 87: /*W*/ this.moveForward = false; break; @@ -229,7 +229,7 @@ THREE.FirstPersonControls = function ( object, domElement ) { } this.lon += this.mouseX * actualLookSpeed; - if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio; + if ( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio; this.lat = Math.max( - 85, Math.min( 85, this.lat ) ); this.phi = THREE.Math.degToRad( 90 - this.lat ); diff --git a/examples/js/controls/FlyControls.js b/examples/js/controls/FlyControls.js index 2a033ad18b6bea..e5fd6c3195bbc6 100644 --- a/examples/js/controls/FlyControls.js +++ b/examples/js/controls/FlyControls.js @@ -80,7 +80,7 @@ THREE.FlyControls = function ( object, domElement ) { this.keyup = function( event ) { - switch( event.keyCode ) { + switch ( event.keyCode ) { case 16: /* shift */ this.movementSpeedMultiplier = 1; break; diff --git a/examples/js/controls/OrbitControls.js b/examples/js/controls/OrbitControls.js index def12ad84f0615..be5f768ec88da4 100644 --- a/examples/js/controls/OrbitControls.js +++ b/examples/js/controls/OrbitControls.js @@ -121,8 +121,8 @@ THREE.OrbitControls = function ( object, domElement ) { // events var changeEvent = { type: 'change' }; - var startEvent = { type: 'start'}; - var endEvent = { type: 'end'}; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; this.rotateLeft = function ( angle ) { diff --git a/examples/js/controls/OrthographicTrackballControls.js b/examples/js/controls/OrthographicTrackballControls.js index 73d259dbed0b15..304fc80e2847e4 100644 --- a/examples/js/controls/OrthographicTrackballControls.js +++ b/examples/js/controls/OrthographicTrackballControls.js @@ -73,8 +73,8 @@ THREE.OrthographicTrackballControls = function ( object, domElement ) { // events var changeEvent = { type: 'change' }; - var startEvent = { type: 'start'}; - var endEvent = { type: 'end'}; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; // methods @@ -156,7 +156,7 @@ THREE.OrthographicTrackballControls = function ( object, domElement ) { if ( length < Math.SQRT1_2 ) { - mouseOnBall.z = Math.sqrt( 1.0 - length*length ); + mouseOnBall.z = Math.sqrt( 1.0 - length * length ); } else { @@ -186,7 +186,7 @@ THREE.OrthographicTrackballControls = function ( object, domElement ) { }() ); - this.rotateCamera = (function(){ + this.rotateCamera = (function() { var axis = new THREE.Vector3(), quaternion = new THREE.Quaternion(); @@ -264,7 +264,7 @@ THREE.OrthographicTrackballControls = function ( object, domElement ) { }; - this.panCamera = (function(){ + this.panCamera = (function() { var mouseChange = new THREE.Vector2(), objectUp = new THREE.Vector3(), diff --git a/examples/js/controls/TrackballControls.js b/examples/js/controls/TrackballControls.js index 7be25a137b5db7..f57c8c20c79a5f 100644 --- a/examples/js/controls/TrackballControls.js +++ b/examples/js/controls/TrackballControls.js @@ -68,8 +68,8 @@ THREE.TrackballControls = function ( object, domElement ) { // events var changeEvent = { type: 'change' }; - var startEvent = { type: 'start'}; - var endEvent = { type: 'end'}; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; // methods @@ -133,8 +133,8 @@ THREE.TrackballControls = function ( object, domElement ) { return function ( pageX, pageY ) { mouseOnBall.set( - ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5), - ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / (_this.screen.height*.5), + ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width * .5), + ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / (_this.screen.height * .5), 0.0 ); @@ -144,7 +144,7 @@ THREE.TrackballControls = function ( object, domElement ) { if ( length < Math.SQRT1_2 ) { - mouseOnBall.z = Math.sqrt( 1.0 - length*length ); + mouseOnBall.z = Math.sqrt( 1.0 - length * length ); } else { @@ -174,7 +174,7 @@ THREE.TrackballControls = function ( object, domElement ) { }() ); - this.rotateCamera = (function(){ + this.rotateCamera = (function() { var axis = new THREE.Vector3(), quaternion = new THREE.Quaternion(); @@ -245,7 +245,7 @@ THREE.TrackballControls = function ( object, domElement ) { }; - this.panCamera = (function(){ + this.panCamera = (function() { var mouseChange = new THREE.Vector2(), objectUp = new THREE.Vector3(), diff --git a/examples/js/controls/TransformControls.js b/examples/js/controls/TransformControls.js index 2dcd4ec399e20f..809c28374d142d 100644 --- a/examples/js/controls/TransformControls.js +++ b/examples/js/controls/TransformControls.js @@ -110,8 +110,8 @@ this.activePlane = planes["XYZE"]; - planes["YZ"].rotation.set( 0, Math.PI/2, 0 ); - planes["XZ"].rotation.set( -Math.PI/2, 0, 0 ); + planes["YZ"].rotation.set( 0, Math.PI / 2, 0 ); + planes["XZ"].rotation.set( -Math.PI / 2, 0, 0 ); for (var i in planes) { planes[i].name = i; @@ -126,7 +126,7 @@ for ( var name in gizmoMap ) { - for ( i = gizmoMap[name].length; i--;) { + for ( i = gizmoMap[name].length; i --;) { var object = gizmoMap[name][i][0]; var position = gizmoMap[name][i][1]; @@ -183,7 +183,7 @@ this.highlight = function ( axis ) { this.traverse(function( child ) { - if ( child.material && child.material.highlight ){ + if ( child.material && child.material.highlight ) { if ( child.name == axis ) { child.material.highlight( true ); } else { @@ -236,7 +236,7 @@ this.handleGizmos = { X: [ - [ new THREE.Mesh( arrowGeometry, new GizmoMaterial( { color: 0xff0000 } ) ), [ 0.5, 0, 0 ], [ 0, 0, -Math.PI/2 ] ], + [ new THREE.Mesh( arrowGeometry, new GizmoMaterial( { color: 0xff0000 } ) ), [ 0.5, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ], [ new THREE.Line( lineXGeometry, new GizmoLineMaterial( { color: 0xff0000 } ) ) ] ], Y: [ @@ -244,7 +244,7 @@ [ new THREE.Line( lineYGeometry, new GizmoLineMaterial( { color: 0x00ff00 } ) ) ] ], Z: [ - [ new THREE.Mesh( arrowGeometry, new GizmoMaterial( { color: 0x0000ff } ) ), [ 0, 0, 0.5 ], [ Math.PI/2, 0, 0 ] ], + [ new THREE.Mesh( arrowGeometry, new GizmoMaterial( { color: 0x0000ff } ) ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ] ], [ new THREE.Line( lineZGeometry, new GizmoLineMaterial( { color: 0x0000ff } ) ) ] ], XYZ: [ @@ -254,22 +254,22 @@ [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.29, 0.29 ), new GizmoMaterial( { color: 0xffff00, opacity: 0.25 } ) ), [ 0.15, 0.15, 0 ] ] ], YZ: [ - [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.29, 0.29 ), new GizmoMaterial( { color: 0x00ffff, opacity: 0.25 } ) ), [ 0, 0.15, 0.15 ], [ 0, Math.PI/2, 0 ] ] + [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.29, 0.29 ), new GizmoMaterial( { color: 0x00ffff, opacity: 0.25 } ) ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ] ] ], XZ: [ - [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.29, 0.29 ), new GizmoMaterial( { color: 0xff00ff, opacity: 0.25 } ) ), [ 0.15, 0, 0.15 ], [ -Math.PI/2, 0, 0 ] ] + [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.29, 0.29 ), new GizmoMaterial( { color: 0xff00ff, opacity: 0.25 } ) ), [ 0.15, 0, 0.15 ], [ -Math.PI / 2, 0, 0 ] ] ] }; this.pickerGizmos = { X: [ - [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0xff0000, opacity: 0.25 } ) ), [ 0.6, 0, 0 ], [ 0, 0, -Math.PI/2 ] ] + [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0xff0000, opacity: 0.25 } ) ), [ 0.6, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ] ], Y: [ [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0x00ff00, opacity: 0.25 } ) ), [ 0, 0.6, 0 ] ] ], Z: [ - [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0x0000ff, opacity: 0.25 } ) ), [ 0, 0, 0.6 ], [ Math.PI/2, 0, 0 ] ] + [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0x0000ff, opacity: 0.25 } ) ), [ 0, 0, 0.6 ], [ Math.PI / 2, 0, 0 ] ] ], XYZ: [ [ new THREE.Mesh( new THREE.OctahedronGeometry( 0.2, 0 ), new GizmoMaterial( { color: 0xffffff, opacity: 0.25 } ) ) ] @@ -278,10 +278,10 @@ [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.4, 0.4 ), new GizmoMaterial( { color: 0xffff00, opacity: 0.25 } ) ), [ 0.2, 0.2, 0 ] ] ], YZ: [ - [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.4, 0.4 ), new GizmoMaterial( { color: 0x00ffff, opacity: 0.25 } ) ), [ 0, 0.2, 0.2 ], [ 0, Math.PI/2, 0 ] ] + [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.4, 0.4 ), new GizmoMaterial( { color: 0x00ffff, opacity: 0.25 } ) ), [ 0, 0.2, 0.2 ], [ 0, Math.PI / 2, 0 ] ] ], XZ: [ - [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.4, 0.4 ), new GizmoMaterial( { color: 0xff00ff, opacity: 0.25 } ) ), [ 0.2, 0, 0.2 ], [ -Math.PI/2, 0, 0 ] ] + [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.4, 0.4 ), new GizmoMaterial( { color: 0xff00ff, opacity: 0.25 } ) ), [ 0.2, 0, 0.2 ], [ -Math.PI / 2, 0, 0 ] ] ] }; @@ -295,12 +295,12 @@ if ( Math.abs(eye.y) > Math.abs(eye.z) ) this.activePlane = this.planes[ "XZ" ]; } - if ( axis == "Y" ){ + if ( axis == "Y" ) { this.activePlane = this.planes[ "XY" ]; if ( Math.abs(eye.x) > Math.abs(eye.z) ) this.activePlane = this.planes[ "YZ" ]; } - if ( axis == "Z" ){ + if ( axis == "Z" ) { this.activePlane = this.planes[ "XZ" ]; if ( Math.abs(eye.x) > Math.abs(eye.y) ) this.activePlane = this.planes[ "YZ" ]; } @@ -333,7 +333,7 @@ var geometry = new THREE.Geometry(); arc = arc ? arc : 1; - for ( var i = 0; i <= 64 * arc; ++i ) { + for ( var i = 0; i <= 64 * arc; ++ i ) { if ( facing == 'x' ) geometry.vertices.push( new THREE.Vector3( 0, Math.cos( i / 32 * Math.PI ), Math.sin( i / 32 * Math.PI ) ).multiplyScalar(radius) ); if ( facing == 'y' ) geometry.vertices.push( new THREE.Vector3( Math.cos( i / 32 * Math.PI ), 0, Math.sin( i / 32 * Math.PI ) ).multiplyScalar(radius) ); if ( facing == 'z' ) geometry.vertices.push( new THREE.Vector3( Math.sin( i / 32 * Math.PI ), Math.cos( i / 32 * Math.PI ), 0 ).multiplyScalar(radius) ); @@ -362,13 +362,13 @@ this.pickerGizmos = { X: [ - [ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.12, 4, 12, Math.PI ), new GizmoMaterial( { color: 0xff0000, opacity: 0.25 } ) ), [ 0, 0, 0 ], [ 0, -Math.PI/2, -Math.PI/2 ] ] + [ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.12, 4, 12, Math.PI ), new GizmoMaterial( { color: 0xff0000, opacity: 0.25 } ) ), [ 0, 0, 0 ], [ 0, -Math.PI / 2, -Math.PI / 2 ] ] ], Y: [ - [ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.12, 4, 12, Math.PI ), new GizmoMaterial( { color: 0x00ff00, opacity: 0.25 } ) ), [ 0, 0, 0 ], [ Math.PI/2, 0, 0 ] ] + [ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.12, 4, 12, Math.PI ), new GizmoMaterial( { color: 0x00ff00, opacity: 0.25 } ) ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ] ] ], Z: [ - [ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.12, 4, 12, Math.PI ), new GizmoMaterial( { color: 0x0000ff, opacity: 0.25 } ) ), [ 0, 0, 0 ], [ 0, 0, -Math.PI/2 ] ] + [ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.12, 4, 12, Math.PI ), new GizmoMaterial( { color: 0x0000ff, opacity: 0.25 } ) ), [ 0, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ] ], E: [ [ new THREE.Mesh( new THREE.TorusGeometry( 1.25, 0.12, 2, 24 ), new GizmoMaterial( { color: 0xffff00, opacity: 0.25 } ) ) ] @@ -474,7 +474,7 @@ this.handleGizmos = { X: [ - [ new THREE.Mesh( arrowGeometry, new GizmoMaterial( { color: 0xff0000 } ) ), [ 0.5, 0, 0 ], [ 0, 0, -Math.PI/2 ] ], + [ new THREE.Mesh( arrowGeometry, new GizmoMaterial( { color: 0xff0000 } ) ), [ 0.5, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ], [ new THREE.Line( lineXGeometry, new GizmoLineMaterial( { color: 0xff0000 } ) ) ] ], Y: [ @@ -482,7 +482,7 @@ [ new THREE.Line( lineYGeometry, new GizmoLineMaterial( { color: 0x00ff00 } ) ) ] ], Z: [ - [ new THREE.Mesh( arrowGeometry, new GizmoMaterial( { color: 0x0000ff } ) ), [ 0, 0, 0.5 ], [ Math.PI/2, 0, 0 ] ], + [ new THREE.Mesh( arrowGeometry, new GizmoMaterial( { color: 0x0000ff } ) ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ] ], [ new THREE.Line( lineZGeometry, new GizmoLineMaterial( { color: 0x0000ff } ) ) ] ], XYZ: [ @@ -492,13 +492,13 @@ this.pickerGizmos = { X: [ - [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0xff0000, opacity: 0.25 } ) ), [ 0.6, 0, 0 ], [ 0, 0, -Math.PI/2 ] ] + [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0xff0000, opacity: 0.25 } ) ), [ 0.6, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ] ], Y: [ [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0x00ff00, opacity: 0.25 } ) ), [ 0, 0.6, 0 ] ] ], Z: [ - [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0x0000ff, opacity: 0.25 } ) ), [ 0, 0, 0.6 ], [ Math.PI/2, 0, 0 ] ] + [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), new GizmoMaterial( { color: 0x0000ff, opacity: 0.25 } ) ), [ 0, 0, 0.6 ], [ Math.PI / 2, 0, 0 ] ] ], XYZ: [ [ new THREE.Mesh( new THREE.BoxGeometry( 0.4, 0.4, 0.4 ), new GizmoMaterial( { color: 0xffffff, opacity: 0.25 } ) ) ] @@ -515,12 +515,12 @@ if ( Math.abs(eye.y) > Math.abs(eye.z) ) this.activePlane = this.planes[ "XZ" ]; } - if ( axis == "Y" ){ + if ( axis == "Y" ) { this.activePlane = this.planes[ "XY" ]; if ( Math.abs(eye.x) > Math.abs(eye.z) ) this.activePlane = this.planes[ "YZ" ]; } - if ( axis == "Z" ){ + if ( axis == "Z" ) { this.activePlane = this.planes[ "XZ" ]; if ( Math.abs(eye.x) > Math.abs(eye.y) ) this.activePlane = this.planes[ "YZ" ]; } @@ -775,7 +775,7 @@ scope.gizmo[_mode].setActivePlane( scope.axis, eye ); - var planeIntersect = intersectObjects( pointer, [scope.gizmo[_mode].activePlane] ); + var planeIntersect = intersectObjects( pointer, [ scope.gizmo[_mode].activePlane ] ); oldPosition.copy( scope.object.position ); oldScale.copy( scope.object.scale ); @@ -803,9 +803,9 @@ event.preventDefault(); event.stopPropagation(); - var pointer = event.changedTouches? event.changedTouches[0] : event; + var pointer = event.changedTouches ? event.changedTouches[0] : event; - var planeIntersect = intersectObjects( pointer, [scope.gizmo[_mode].activePlane] ); + var planeIntersect = intersectObjects( pointer, [ scope.gizmo[_mode].activePlane ] ); point.copy( planeIntersect.point ); diff --git a/examples/js/crossfade/scenes.js b/examples/js/crossfade/scenes.js index f3d2628f05fc37..d491d1cbdf4d23 100644 --- a/examples/js/crossfade/scenes.js +++ b/examples/js/crossfade/scenes.js @@ -8,7 +8,7 @@ function generateGeometry(objectType, numObjects) { var n = ( f instanceof THREE.Face3 ) ? 3 : 4; - for( var j = 0; j < n; j ++ ) { + for ( var j = 0; j < n; j ++ ) { f.vertexColors[ j ] = c; @@ -43,13 +43,13 @@ function generateGeometry(objectType, numObjects) { geom = new THREE.BoxGeometry( 1, 1, 1 ); scale.y = Math.random() * 200 + 100; scale.z = Math.random() * 200 + 100; - color.setRGB( 0, 0, Math.random()+0.1 ); + color.setRGB( 0, 0, Math.random() + 0.1 ); } else if ( objectType == "sphere" ) { geom = new THREE.IcosahedronGeometry( 1, 1 ) scale.y = scale.z = scale.x; - color.setRGB( Math.random()+0.1, 0, 0 ); + color.setRGB( Math.random() + 0.1, 0, 0 ); } // give the geom's vertices a random color, to be displayed @@ -94,9 +94,9 @@ function Scene ( type, numObjects, cameraZ, fov, rotationSpeed, clearColor ) { this.render = function( delta, rtt ) { - this.mesh.rotation.x += delta*this.rotationSpeed.x; - this.mesh.rotation.y += delta*this.rotationSpeed.y; - this.mesh.rotation.z += delta*this.rotationSpeed.z; + this.mesh.rotation.x += delta * this.rotationSpeed.x; + this.mesh.rotation.y += delta * this.rotationSpeed.y; + this.mesh.rotation.z += delta * this.rotationSpeed.z; renderer.setClearColor( this.clearColor ); diff --git a/examples/js/crossfade/transition.js b/examples/js/crossfade/transition.js index 14f87634b67cda..7d5f79632c4149 100644 --- a/examples/js/crossfade/transition.js +++ b/examples/js/crossfade/transition.js @@ -5,8 +5,8 @@ function Transition ( sceneA, sceneB ) { this.cameraOrtho = new THREE.OrthographicCamera(window.innerWidth / -2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / -2, -10, 10); this.textures = []; - for (var i=0;i<6;i++) - this.textures[i]=new THREE.ImageUtils.loadTexture('textures/transition/transition'+(i+1)+'.png'); + for (var i = 0; i < 6; i ++) + this.textures[i] = new THREE.ImageUtils.loadTexture('textures/transition/transition' + (i + 1) + '.png'); this.quadmaterial = new THREE.ShaderMaterial({ @@ -101,13 +101,13 @@ function Transition ( sceneA, sceneB ) { this.setTextureThreshold = function ( value ) { - this.quadmaterial.uniforms.threshold.value=value; + this.quadmaterial.uniforms.threshold.value = value; } this.useTexture = function ( value ) { - this.quadmaterial.uniforms.useTexture.value = value?1:0; + this.quadmaterial.uniforms.useTexture.value = value ? 1 : 0; } @@ -122,32 +122,32 @@ function Transition ( sceneA, sceneB ) { // Transition animation if (transitionParams.animateTransition) { - var t=(1+Math.sin(transitionParams.transitionSpeed*clock.getElapsedTime()/Math.PI))/2; - transitionParams.transition=THREE.Math.smoothstep(t,0.3,0.7); + var t = (1 + Math.sin(transitionParams.transitionSpeed * clock.getElapsedTime() / Math.PI)) / 2; + transitionParams.transition = THREE.Math.smoothstep(t, 0.3, 0.7); // Change the current alpha texture after each transition - if (transitionParams.loopTexture && (transitionParams.transition==0 || transitionParams.transition==1)) + if (transitionParams.loopTexture && (transitionParams.transition == 0 || transitionParams.transition == 1)) { if (this.needChange) { - transitionParams.texture=(transitionParams.texture+1)%this.textures.length; + transitionParams.texture = (transitionParams.texture + 1)%this.textures.length; this.quadmaterial.uniforms.tMixTexture.value = this.textures[transitionParams.texture]; - this.needChange=false; + this.needChange = false; } } else - this.needChange=true; + this.needChange = true; } this.quadmaterial.uniforms.mixRatio.value = transitionParams.transition; // Prevent render both scenes when it's not necessary - if (transitionParams.transition==0) { + if (transitionParams.transition == 0) { this.sceneB.render( delta, false ); - } else if (transitionParams.transition==1) { + } else if (transitionParams.transition == 1) { this.sceneA.render( delta, false ); diff --git a/examples/js/curves/NURBSCurve.js b/examples/js/curves/NURBSCurve.js index b70719b2cb85e2..ac8b5312b3d008 100644 --- a/examples/js/curves/NURBSCurve.js +++ b/examples/js/curves/NURBSCurve.js @@ -18,7 +18,7 @@ THREE.NURBSCurve = function ( degree, knots /* array of reals */, controlPoints this.degree = degree; this.knots = knots; this.controlPoints = []; - for (var i = 0; i < controlPoints.length; ++i) { // ensure Vector4 for control points + for (var i = 0; i < controlPoints.length; ++ i) { // ensure Vector4 for control points var point = controlPoints[i]; this.controlPoints[i] = new THREE.Vector4(point.x, point.y, point.z, point.w); } diff --git a/examples/js/curves/NURBSSurface.js b/examples/js/curves/NURBSSurface.js index bfb2d54a6300d1..da61dc3df7b5ae 100644 --- a/examples/js/curves/NURBSSurface.js +++ b/examples/js/curves/NURBSSurface.js @@ -23,9 +23,9 @@ THREE.NURBSSurface = function ( degree1, degree2, knots1, knots2 /* arrays of re var len2 = knots2.length - degree2 - 1; // ensure Vector4 for control points - for (var i = 0; i < len1; ++i) { + for (var i = 0; i < len1; ++ i) { this.controlPoints[i] = [] - for (var j = 0; j < len2; ++j) { + for (var j = 0; j < len2; ++ j) { var point = controlPoints[i][j]; this.controlPoints[i][j] = new THREE.Vector4(point.x, point.y, point.z, point.w); } diff --git a/examples/js/curves/NURBSUtils.js b/examples/js/curves/NURBSUtils.js index 9df5b5f89d608f..5ce00d10115f30 100644 --- a/examples/js/curves/NURBSUtils.js +++ b/examples/js/curves/NURBSUtils.js @@ -68,14 +68,14 @@ THREE.NURBSUtils = { var right = []; N[0] = 1.0; - for (var j = 1; j <= p; ++j) { + for (var j = 1; j <= p; ++ j) { left[j] = u - U[span + 1 - j]; right[j] = U[span + j] - u; var saved = 0.0; - for (var r = 0; r < j; ++r) { + for (var r = 0; r < j; ++ r) { var rv = right[r + 1]; var lv = left[j - r]; @@ -106,7 +106,7 @@ THREE.NURBSUtils = { var N = this.calcBasisFunctions(span, u, p, U); var C = new THREE.Vector4(0, 0, 0, 0); - for (var j = 0; j <= p; ++j) { + for (var j = 0; j <= p; ++ j) { var point = P[span - p + j]; var Nj = N[j]; var wNj = point.w * Nj; @@ -134,15 +134,15 @@ THREE.NURBSUtils = { calcBasisFunctionDerivatives: function( span, u, p, n, U ) { var zeroArr = []; - for (var i = 0; i <= p; ++i) + for (var i = 0; i <= p; ++ i) zeroArr[i] = 0.0; var ders = []; - for (var i = 0; i <= n; ++i) + for (var i = 0; i <= n; ++ i) ders[i] = zeroArr.slice(0); var ndu = []; - for (var i = 0; i <= p; ++i) + for (var i = 0; i <= p; ++ i) ndu[i] = zeroArr.slice(0); ndu[0][0] = 1.0; @@ -150,13 +150,13 @@ THREE.NURBSUtils = { var left = zeroArr.slice(0); var right = zeroArr.slice(0); - for (var j = 1; j <= p; ++j) { + for (var j = 1; j <= p; ++ j) { left[j] = u - U[span + 1 - j]; right[j] = U[span + j] - u; var saved = 0.0; - for (var r = 0; r < j; ++r) { + for (var r = 0; r < j; ++ r) { var rv = right[r + 1]; var lv = left[j - r]; ndu[j][r] = rv + lv; @@ -169,21 +169,21 @@ THREE.NURBSUtils = { ndu[j][j] = saved; } - for (var j = 0; j <= p; ++j) { + for (var j = 0; j <= p; ++ j) { ders[0][j] = ndu[j][p]; } - for (var r = 0; r <= p; ++r) { + for (var r = 0; r <= p; ++ r) { var s1 = 0; var s2 = 1; var a = []; - for (var i = 0; i <= p; ++i) { + for (var i = 0; i <= p; ++ i) { a[i] = zeroArr.slice(0); } a[0][0] = 1.0; - for (var k = 1; k <= n; ++k) { + for (var k = 1; k <= n; ++ k) { var d = 0.0; var rk = r - k; var pk = p - k; @@ -196,7 +196,7 @@ THREE.NURBSUtils = { var j1 = (rk >= -1) ? 1 : -rk; var j2 = (r - 1 <= pk) ? k - 1 : p - r; - for (var j = j1; j <= j2; ++j) { + for (var j = j1; j <= j2; ++ j) { a[s2][j] = (a[s1][j] - a[s1][j - 1]) / ndu[pk + 1][rk + j]; d += a[s2][j] * ndu[rk + j][pk]; } @@ -216,8 +216,8 @@ THREE.NURBSUtils = { var r = p; - for (var k = 1; k <= n; ++k) { - for (var j = 0; j <= p; ++j) { + for (var k = 1; k <= n; ++ k) { + for (var j = 0; j <= p; ++ j) { ders[k][j] *= r; } r *= p - k; @@ -245,7 +245,7 @@ THREE.NURBSUtils = { var nders = this.calcBasisFunctionDerivatives(span, u, p, du, U); var Pw = []; - for (var i = 0; i < P.length; ++i) { + for (var i = 0; i < P.length; ++ i) { var point = P[i].clone(); var w = point.w; @@ -255,17 +255,17 @@ THREE.NURBSUtils = { Pw[i] = point; } - for (var k = 0; k <= du; ++k) { + for (var k = 0; k <= du; ++ k) { var point = Pw[span - p].clone().multiplyScalar(nders[k][0]); - for (var j = 1; j <= p; ++j) { + for (var j = 1; j <= p; ++ j) { point.add(Pw[span - p + j].clone().multiplyScalar(nders[k][j])); } CK[k] = point; } - for (var k = du + 1; k <= nd + 1; ++k) { + for (var k = du + 1; k <= nd + 1; ++ k) { CK[k] = new THREE.Vector4(0, 0, 0); } @@ -281,17 +281,17 @@ THREE.NURBSUtils = { calcKoverI: function( k, i ) { var nom = 1; - for (var j = 2; j <= k; ++j) { + for (var j = 2; j <= k; ++ j) { nom *= j; } var denom = 1; - for (var j = 2; j <= i; ++j) { + for (var j = 2; j <= i; ++ j) { denom *= j; } - for (var j = 2; j <= k - i; ++j) { + for (var j = 2; j <= k - i; ++ j) { denom *= j; } @@ -311,7 +311,7 @@ THREE.NURBSUtils = { var Aders = []; var wders = []; - for (var i = 0; i < nd; ++i) { + for (var i = 0; i < nd; ++ i) { var point = Pders[i]; Aders[i] = new THREE.Vector3(point.x, point.y, point.z); wders[i] = point.w; @@ -319,11 +319,11 @@ THREE.NURBSUtils = { var CK = []; - for (var k = 0; k < nd; ++k) { + for (var k = 0; k < nd; ++ k) { var v = Aders[k].clone(); - for (var i = 1; i <= k; ++i) { - v.sub(CK[k - i].clone().multiplyScalar(this.calcKoverI(k,i) * wders[i])); + for (var i = 1; i <= k; ++ i) { + v.sub(CK[k - i].clone().multiplyScalar(this.calcKoverI(k, i) * wders[i])); } CK[k] = v.divideScalar(wders[0]); @@ -367,9 +367,9 @@ THREE.NURBSUtils = { var Nv = this.calcBasisFunctions(vspan, v, q, V); var temp = []; - for (var l = 0; l <= q; ++l) { + for (var l = 0; l <= q; ++ l) { temp[l] = new THREE.Vector4(0, 0, 0, 0); - for (var k = 0; k <= p; ++k) { + for (var k = 0; k <= p; ++ k) { var point = P[uspan - p + k][vspan - q + l].clone(); var w = point.w; point.x *= w; @@ -380,7 +380,7 @@ THREE.NURBSUtils = { } var Sw = new THREE.Vector4(0, 0, 0, 0); - for (var l = 0; l <= q; ++l) { + for (var l = 0; l <= q; ++ l) { Sw.add(temp[l].multiplyScalar(Nv[l])); } diff --git a/examples/js/effects/AsciiEffect.js b/examples/js/effects/AsciiEffect.js index 5431417faaacfa..371c89e7e84adc 100644 --- a/examples/js/effects/AsciiEffect.js +++ b/examples/js/effects/AsciiEffect.js @@ -96,8 +96,8 @@ THREE.AsciiEffect = function ( renderer, charSet, options ) { var oStyle = oAscii.style; oStyle.display = "inline"; - oStyle.width = Math.round(iWidth/fResolution*iScale) + "px"; - oStyle.height = Math.round(iHeight/fResolution*iScale) + "px"; + oStyle.width = Math.round(iWidth / fResolution * iScale) + "px"; + oStyle.height = Math.round(iHeight / fResolution * iScale) + "px"; oStyle.whiteSpace = "pre"; oStyle.margin = "0px"; oStyle.padding = "0px"; @@ -144,8 +144,8 @@ THREE.AsciiEffect = function ( renderer, charSet, options ) { // Setup dom - var fFontSize = (2/fResolution)*iScale; - var fLineHeight = (2/fResolution)*iScale; + var fFontSize = (2 / fResolution) * iScale; + var fLineHeight = (2 / fResolution) * iScale; // adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width. @@ -204,9 +204,9 @@ THREE.AsciiEffect = function ( renderer, charSet, options ) { // console.time('rendering'); - for (var y=0;y" + strThisChar + ""; } else { strChars += strThisChar; diff --git a/examples/js/effects/VREffect.js b/examples/js/effects/VREffect.js index 58e217c67a6a71..8e71ea7f2d48ae 100644 --- a/examples/js/effects/VREffect.js +++ b/examples/js/effects/VREffect.js @@ -43,7 +43,7 @@ THREE.VREffect = function ( renderer, done ) { function gotVRDevices( devices ) { var vrHMD; var error; - for ( var i = 0; i < devices.length; ++i ) { + for ( var i = 0; i < devices.length; ++ i ) { if ( devices[i] instanceof HMDVRDevice ) { vrHMD = devices[i]; self._vrHMD = vrHMD; @@ -155,7 +155,7 @@ THREE.VREffect = function ( renderer, done ) { var vrHMD = this._vrHMD; var canvas = renderer.domElement; var fullScreenChange = - canvas.mozRequestFullScreen? 'mozfullscreenchange' : 'webkitfullscreenchange'; + canvas.mozRequestFullScreen ? 'mozfullscreenchange' : 'webkitfullscreenchange'; document.addEventListener( fullScreenChange, onFullScreenChanged, false ); function onFullScreenChanged() { @@ -175,7 +175,7 @@ THREE.VREffect = function ( renderer, done ) { var pxoffset = (fov.leftTan - fov.rightTan) * pxscale * 0.5; var pyscale = 2.0 / (fov.upTan + fov.downTan); var pyoffset = (fov.upTan - fov.downTan) * pyscale * 0.5; - return { scale: [pxscale, pyscale], offset: [pxoffset, pyoffset] }; + return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] }; }; this.FovPortToProjection = function( fov, rightHanded /* = true */, zNear /* = 0.01 */, zFar /* = 10000.0 */ ) @@ -194,30 +194,30 @@ THREE.VREffect = function ( renderer, done ) { var scaleAndOffset = this.FovToNDCScaleOffset(fov); // X result, map clip edges to [-w,+w] - m[0*4+0] = scaleAndOffset.scale[0]; - m[0*4+1] = 0.0; - m[0*4+2] = scaleAndOffset.offset[0] * handednessScale; - m[0*4+3] = 0.0; + m[0 * 4 + 0] = scaleAndOffset.scale[0]; + m[0 * 4 + 1] = 0.0; + m[0 * 4 + 2] = scaleAndOffset.offset[0] * handednessScale; + m[0 * 4 + 3] = 0.0; // Y result, map clip edges to [-w,+w] // Y offset is negated because this proj matrix transforms from world coords with Y=up, // but the NDC scaling has Y=down (thanks D3D?) - m[1*4+0] = 0.0; - m[1*4+1] = scaleAndOffset.scale[1]; - m[1*4+2] = -scaleAndOffset.offset[1] * handednessScale; - m[1*4+3] = 0.0; + m[1 * 4 + 0] = 0.0; + m[1 * 4 + 1] = scaleAndOffset.scale[1]; + m[1 * 4 + 2] = -scaleAndOffset.offset[1] * handednessScale; + m[1 * 4 + 3] = 0.0; // Z result (up to the app) - m[2*4+0] = 0.0; - m[2*4+1] = 0.0; - m[2*4+2] = zFar / (zNear - zFar) * -handednessScale; - m[2*4+3] = (zFar * zNear) / (zNear - zFar); + m[2 * 4 + 0] = 0.0; + m[2 * 4 + 1] = 0.0; + m[2 * 4 + 2] = zFar / (zNear - zFar) * -handednessScale; + m[2 * 4 + 3] = (zFar * zNear) / (zNear - zFar); // W result (= Z in) - m[3*4+0] = 0.0; - m[3*4+1] = 0.0; - m[3*4+2] = handednessScale; - m[3*4+3] = 0.0; + m[3 * 4 + 0] = 0.0; + m[3 * 4 + 1] = 0.0; + m[3 * 4 + 2] = handednessScale; + m[3 * 4 + 3] = 0.0; mobj.transpose(); diff --git a/examples/js/exporters/SceneExporter.js b/examples/js/exporters/SceneExporter.js index 169b1d093bb0f0..d3a7e3fedd8662 100644 --- a/examples/js/exporters/SceneExporter.js +++ b/examples/js/exporters/SceneExporter.js @@ -182,7 +182,7 @@ THREE.SceneExporter.prototype = { function NumConstantString( c ) { - var constants = [ "NearestFilter", "NearestMipMapNearestFilter" , "NearestMipMapLinearFilter", + var constants = [ "NearestFilter", "NearestMipMapNearestFilter", "NearestMipMapLinearFilter", "LinearFilter", "LinearMipMapNearestFilter", "LinearMipMapLinearFilter" ]; for ( var i = 0; i < constants.length; i ++ ) { diff --git a/examples/js/geometries/ConvexGeometry.js b/examples/js/geometries/ConvexGeometry.js index 53133c74f2589d..37b41a643087cc 100644 --- a/examples/js/geometries/ConvexGeometry.js +++ b/examples/js/geometries/ConvexGeometry.js @@ -23,7 +23,7 @@ THREE.ConvexGeometry = function( vertices ) { var faces = [ [ 0, 1, 2 ], [ 0, 2, 1 ] ]; - for ( var i = 3; i < vertices.length; i++ ) { + for ( var i = 3; i < vertices.length; i ++ ) { addPoint( i ); @@ -49,13 +49,13 @@ THREE.ConvexGeometry = function( vertices ) { // then we try to add the face's edges into the hole. if ( visible( face, vertex ) ) { - for ( var e = 0; e < 3; e++ ) { + for ( var e = 0; e < 3; e ++ ) { var edge = [ face[ e ], face[ ( e + 1 ) % 3 ] ]; var boundary = true; // remove duplicated edges. - for ( var h = 0; h < hole.length; h++ ) { + for ( var h = 0; h < hole.length; h ++ ) { if ( equalEdge( hole[ h ], edge ) ) { @@ -82,13 +82,13 @@ THREE.ConvexGeometry = function( vertices ) { } else { // not visible - f++; + f ++; } } // construct the new faces formed by the edges of the hole and the vertex - for ( var h = 0; h < hole.length; h++ ) { + for ( var h = 0; h < hole.length; h ++ ) { faces.push( [ hole[ h ][ 0 ], @@ -170,15 +170,15 @@ THREE.ConvexGeometry = function( vertices ) { var id = 0; var newId = new Array( vertices.length ); // map from old vertex id to new id - for ( var i = 0; i < faces.length; i++ ) { + for ( var i = 0; i < faces.length; i ++ ) { var face = faces[ i ]; - for ( var j = 0; j < 3; j++ ) { + for ( var j = 0; j < 3; j ++ ) { if ( newId[ face[ j ] ] === undefined ) { - newId[ face[ j ] ] = id++; + newId[ face[ j ] ] = id ++; this.vertices.push( vertices[ face[ j ] ] ); } @@ -190,7 +190,7 @@ THREE.ConvexGeometry = function( vertices ) { } // Convert faces into instances of THREE.Face3 - for ( var i = 0; i < faces.length; i++ ) { + for ( var i = 0; i < faces.length; i ++ ) { this.faces.push( new THREE.Face3( faces[ i ][ 0 ], @@ -201,7 +201,7 @@ THREE.ConvexGeometry = function( vertices ) { } // Compute UVs - for ( var i = 0; i < this.faces.length; i++ ) { + for ( var i = 0; i < this.faces.length; i ++ ) { var face = this.faces[ i ]; diff --git a/examples/js/geometries/DecalGeometry.js b/examples/js/geometries/DecalGeometry.js index 759aae9c3e0a73..bc3c2cd008edc4 100644 --- a/examples/js/geometries/DecalGeometry.js +++ b/examples/js/geometries/DecalGeometry.js @@ -15,7 +15,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { THREE.Geometry.call( this ); - if( check === undefined ) check = null; + if ( check === undefined ) check = null; check = check || new THREE.Vector3( 1, 1, 1 ); this.uvs = []; @@ -60,10 +60,10 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { } - if( inVertices.length === 0 ) return []; + if ( inVertices.length === 0 ) return []; var outVertices = []; - for( var j = 0; j < inVertices.length; j += 3 ) { + for ( var j = 0; j < inVertices.length; j += 3 ) { var v1Out, v2Out, v3Out, total = 0; @@ -75,24 +75,24 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { v2Out = d2 > 0; v3Out = d3 > 0; - total = ( v1Out?1:0 ) + ( v2Out?1:0 ) + ( v3Out?1:0 ); + total = ( v1Out ? 1 : 0 ) + ( v2Out ? 1 : 0 ) + ( v3Out ? 1 : 0 ); - switch( total ) { - case 0:{ + switch ( total ) { + case 0: { outVertices.push( inVertices[ j ] ); outVertices.push( inVertices[ j + 1 ] ); outVertices.push( inVertices[ j + 2 ] ); break; } - case 1:{ + case 1: { var nV1, nV2, nV3; - if( v1Out ) { + if ( v1Out ) { nV1 = inVertices[ j + 1 ]; nV2 = inVertices[ j + 2 ]; nV3 = clip( inVertices[ j ], nV1, plane ); nV4 = clip( inVertices[ j ], nV2, plane ); } - if( v2Out ) { + if ( v2Out ) { nV1 = inVertices[ j ]; nV2 = inVertices[ j + 2 ]; nV3 = clip( inVertices[ j + 1 ], nV1, plane ); @@ -107,7 +107,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { outVertices.push( nV4 ); break; } - if( v3Out ) { + if ( v3Out ) { nV1 = inVertices[ j ]; nV2 = inVertices[ j + 1 ]; nV3 = clip( inVertices[ j + 2 ], nV1, plane ); @@ -126,7 +126,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { } case 2: { var nV1, nV2, nV3; - if( !v1Out ) { + if ( !v1Out ) { nV1 = inVertices[ j ].clone(); nV2 = clip( nV1, inVertices[ j + 1 ], plane ); nV3 = clip( nV1, inVertices[ j + 2 ], plane ); @@ -134,7 +134,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { outVertices.push( nV2 ); outVertices.push( nV3 ); } - if( !v2Out ) { + if ( !v2Out ) { nV1 = inVertices[ j + 1 ].clone(); nV2 = clip( nV1, inVertices[ j + 2 ], plane ); nV3 = clip( nV1, inVertices[ j ], plane ); @@ -142,7 +142,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { outVertices.push( nV2 ); outVertices.push( nV3 ); } - if( !v3Out ) { + if ( !v3Out ) { nV1 = inVertices[ j + 2 ].clone(); nV2 = clip( nV1, inVertices[ j ], plane ); nV3 = clip( nV1, inVertices[ j + 1 ], plane ); @@ -164,7 +164,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { } - this.pushVertex = function( vertices, id, n ){ + this.pushVertex = function( vertices, id, n ) { var v = mesh.geometry.vertices[ id ].clone(); v.applyMatrix4( mesh.matrix ); @@ -177,7 +177,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { var finalVertices = []; - for( var i = 0; i < mesh.geometry.faces.length; i++ ) { + for ( var i = 0; i < mesh.geometry.faces.length; i ++ ) { var f = mesh.geometry.faces[ i ]; var vertices = []; @@ -186,20 +186,20 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { this.pushVertex( vertices, f[ this.faceIndices[ 1 ] ], f.vertexNormals[ 1 ] ); this.pushVertex( vertices, f[ this.faceIndices[ 2 ] ], f.vertexNormals[ 2 ] ); - if( check.x ) { + if ( check.x ) { vertices = this.clipFace( vertices, new THREE.Vector3( 1, 0, 0 ) ); vertices = this.clipFace( vertices, new THREE.Vector3( -1, 0, 0 ) ); } - if( check.y ) { + if ( check.y ) { vertices = this.clipFace( vertices, new THREE.Vector3( 0, 1, 0 ) ); vertices = this.clipFace( vertices, new THREE.Vector3( 0, -1, 0 ) ); } - if( check.z ) { + if ( check.z ) { vertices = this.clipFace( vertices, new THREE.Vector3( 0, 0, 1 ) ); vertices = this.clipFace( vertices, new THREE.Vector3( 0, 0, -1 ) ); } - for( var j = 0; j < vertices.length; j++ ) { + for ( var j = 0; j < vertices.length; j ++ ) { var v = vertices[ j ]; @@ -212,13 +212,13 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { } - if( vertices.length === 0 ) continue; + if ( vertices.length === 0 ) continue; finalVertices = finalVertices.concat( vertices ); } - for( var k = 0; k < finalVertices.length; k += 3 ) { + for ( var k = 0; k < finalVertices.length; k += 3 ) { this.vertices.push( finalVertices[ k ].vertex, diff --git a/examples/js/geometries/hilbert2D.js b/examples/js/geometries/hilbert2D.js index 111fb9a02b7d81..a4ee274847ab5d 100644 --- a/examples/js/geometries/hilbert2D.js +++ b/examples/js/geometries/hilbert2D.js @@ -42,7 +42,7 @@ function hilbert2D (center, size, iterations, v0, v1, v2, v3) { ]; // Recurse iterations - if (0 <= --iterations) { + if (0 <= -- iterations) { var tmp = []; Array.prototype.push.apply( tmp, hilbert2D ( vec[ 0 ], half, iterations, v0, v3, v2, v1 ) ); diff --git a/examples/js/geometries/hilbert3D.js b/examples/js/geometries/hilbert3D.js index 25a8b9261843fa..a0320252ffb949 100644 --- a/examples/js/geometries/hilbert3D.js +++ b/examples/js/geometries/hilbert3D.js @@ -63,7 +63,7 @@ function hilbert3D(center, size, iterations, v0, v1, v2, v3, v4, v5, v6, v7) { ]; // Recurse iterations - if( --iterations >= 0 ) { + if ( -- iterations >= 0 ) { var tmp = []; Array.prototype.push.apply( tmp, hilbert3D ( vec[ 0 ], half, iterations, v0, v3, v4, v7, v6, v5, v2, v1 ) ); diff --git a/examples/js/loaders/AWDLoader.js b/examples/js/loaders/AWDLoader.js index 6634bedad93511..d0dcc1daaf8927 100644 --- a/examples/js/loaders/AWDLoader.js +++ b/examples/js/loaders/AWDLoader.js @@ -3,7 +3,7 @@ * Date: 09/12/2013 17:21 */ -THREE.AWDLoader = (function (){ +THREE.AWDLoader = (function () { @@ -51,9 +51,9 @@ THREE.AWDLoader = (function (){ // ResourcesLoader // ============= // handle loading for external resources - function ResourcesLoader( awdUrl ){ + function ResourcesLoader( awdUrl ) { - this._baseDir = awdUrl.substr( 0, awdUrl.lastIndexOf( '/' )+1 ); + this._baseDir = awdUrl.substr( 0, awdUrl.lastIndexOf( '/' ) + 1 ); this._loadingManager = new THREE.LoadingManager(); @@ -61,12 +61,12 @@ THREE.AWDLoader = (function (){ ResourcesLoader.prototype = { - loadTexture : function( path ){ + loadTexture : function( path ) { var tex = new THREE.Texture(); var loader = new THREE.ImageLoader( this._loadingManager ); - loader.load( this._baseDir+path, function( image ) { + loader.load( this._baseDir + path, function( image ) { tex.image = image; tex.needsUpdate = true; }); @@ -78,7 +78,7 @@ THREE.AWDLoader = (function (){ - function Block(){ + function Block() { this.id = 0; this.data = null; } @@ -158,12 +158,12 @@ THREE.AWDLoader = (function (){ this._parseHeader( ); - if( this._compression != 0 ) { + if ( this._compression != 0 ) { console.error( 'compressed AWD not supported' ); } if (!this._streaming && this._bodylen != data.byteLength - this._ptr ) { - console.error('AWDLoader: body len does not match file length', this._bodylen , blen - this._ptr); + console.error('AWDLoader: body len does not match file length', this._bodylen, blen - this._ptr); } while ( this._ptr < blen ) { @@ -251,7 +251,7 @@ THREE.AWDLoader = (function (){ | ( this.readU8()<<8 ) | this.readU8(); - if( awdmagic != 4282180 ) + if ( awdmagic != 4282180 ) throw new Error( "AWDLoader - bad magic" ); version[0] = this.readU8(); @@ -328,7 +328,7 @@ THREE.AWDLoader = (function (){ materials = []; materials_parsed = 0; - for ( i = 0; i < num_materials; i++) { + for ( i = 0; i < num_materials; i ++) { mat_id = this.readU32(); mat = this.getBlock( mat_id ); materials.push( mat ); @@ -341,9 +341,9 @@ THREE.AWDLoader = (function (){ // TODO : BufferGeometry don't support "geometryGroups" for now. // so we create sub meshes for each groups - if( meshLen > 1 ) { + if ( meshLen > 1 ) { mesh = new THREE.Object3D() - for ( i = 0; i < meshLen; i++) { + for ( i = 0; i < meshLen; i ++) { var sm = new THREE.Mesh( geometries[i] ); meshes.push( sm ); mesh.add( sm ); @@ -364,7 +364,7 @@ THREE.AWDLoader = (function (){ var matLen = materials.length; var maxLen = Math.max( meshLen, matLen); - for( i = 0; i< maxLen; i++ ) + for ( i = 0; i < maxLen; i ++ ) meshes[ i%meshLen ].material = materials[ i % matLen ]; @@ -405,7 +405,7 @@ THREE.AWDLoader = (function (){ methods_parsed = 0; - while( methods_parsed < num_methods ) { + while ( methods_parsed < num_methods ) { var method_type = this.readU16(); this.parseProperties( null ); this.parseUserAttributes(); @@ -413,9 +413,9 @@ THREE.AWDLoader = (function (){ attributes = this.parseUserAttributes(); - if( this.materialFactory !== undefined ) { + if ( this.materialFactory !== undefined ) { mat = this.materialFactory( name ); - if( mat ) return mat; + if ( mat ) return mat; } mat = new THREE.MeshPhongMaterial(); @@ -466,7 +466,7 @@ THREE.AWDLoader = (function (){ AWDLoader.prototype.loadTexture = function( url ) { - if( null === this._resourceLoader ) + if ( null === this._resourceLoader ) this._resourceLoader = new ResourcesLoader( this._url ); return this._resourceLoader.loadTexture( url ); @@ -500,7 +500,7 @@ THREE.AWDLoader = (function (){ this.parseUserAttributes(); skeleton.push(joint); - joints_parsed++; + joints_parsed ++; } // Discard attributes for now @@ -542,7 +542,7 @@ THREE.AWDLoader = (function (){ mtx_data = new THREE.Matrix4(); } pose[joints_parsed] = mtx_data; - joints_parsed++; + joints_parsed ++; } // Skip attributes for now this.parseUserAttributes(); @@ -580,7 +580,7 @@ THREE.AWDLoader = (function (){ duration : frame_dur } ); - frames_parsed++; + frames_parsed ++; } if (clip.length == 0) { // debug("Could not this SkeletonClipNode, because no Frames where set."); @@ -598,14 +598,14 @@ THREE.AWDLoader = (function (){ var poseBlockAdress, name = this.readUTF(), num_frames = this.readU16(), - props = this.parseProperties({1:UINT16}), + props = this.parseProperties({ 1:UINT16 }), frames_parsed = 0, skeletonFrames = []; while (frames_parsed < num_frames) { poseBlockAdress = this.readU32(); skeletonFrames.push(this._blocks[poseBlockAdress].data); - frames_parsed++; + frames_parsed ++; } this.parseUserAttributes(); @@ -626,14 +626,14 @@ THREE.AWDLoader = (function (){ var name = this.readUTF(); var type = this.readU16(); - var props = this.parseProperties({1:BADDR}); + var props = this.parseProperties({ 1:BADDR }); animSetBlockAdress = this.readU32(); var targetMeshLength = this.readU16(); var meshAdresses = []; //:Vector. = new Vector.; - for (var i = 0; i < targetMeshLength; i++) + for (var i = 0; i < targetMeshLength; i ++) meshAdresses.push( this.readU32() ); var activeState = this.readU16(); @@ -644,7 +644,7 @@ THREE.AWDLoader = (function (){ var returnedArray; var targetMeshes = []; //:Vector. = new Vector.; - for (i = 0; i < meshAdresses.length; i++) { + for (i = 0; i < meshAdresses.length; i ++) { // returnedArray = getAssetByID(meshAdresses[i], [AssetType.MESH]); // if (returnedArray[0]) targetMeshes.push(this._blocks[meshAdresses[i]].data); @@ -666,7 +666,7 @@ THREE.AWDLoader = (function (){ } - for (i = 0; i < targetMeshes.length; i++) { + for (i = 0; i < targetMeshes.length; i ++) { targetMeshes[i].animator = thisAnimator; } // debug("Parsed a Animator: Name = " + name); @@ -716,7 +716,7 @@ THREE.AWDLoader = (function (){ // Ignore for now - this.parseProperties({1:this._geoNrType, 2:this._geoNrType}); + this.parseProperties({ 1:this._geoNrType, 2:this._geoNrType }); // Loop through data streams while ( this._ptr < sm_end ) { @@ -744,8 +744,8 @@ THREE.AWDLoader = (function (){ while (this._ptr < str_end) { buffer[idx] = -this.readF32(); - buffer[idx+1] = this.readF32(); - buffer[idx+2] = this.readF32(); + buffer[idx + 1] = this.readF32(); + buffer[idx + 2] = this.readF32(); idx+=3; } } @@ -762,15 +762,15 @@ THREE.AWDLoader = (function (){ geom.offsets.push({ start: 0, index: 0, - count: str_len/2 + count: str_len / 2 }); idx = 0; while (this._ptr < str_end) { - buffer[idx+1] = this.readU16(); + buffer[idx + 1] = this.readU16(); buffer[idx] = this.readU16(); - buffer[idx+2] = this.readU16(); + buffer[idx + 2] = this.readU16(); idx+=3; } } @@ -787,7 +787,7 @@ THREE.AWDLoader = (function (){ while (this._ptr < str_end) { buffer[idx] = this.readF32(); - buffer[idx+1] = 1.0-this.readF32(); + buffer[idx + 1] = 1.0 - this.readF32(); idx+=2; } } @@ -802,8 +802,8 @@ THREE.AWDLoader = (function (){ while (this._ptr < str_end) { buffer[idx] = -this.readF32(); - buffer[idx+1] = this.readF32(); - buffer[idx+2] = this.readF32(); + buffer[idx + 1] = this.readF32(); + buffer[idx + 2] = this.readF32(); idx+=3; } @@ -840,7 +840,7 @@ THREE.AWDLoader = (function (){ geom.computeBoundingSphere(); - subs_parsed++; + subs_parsed ++; } @@ -903,9 +903,9 @@ THREE.AWDLoader = (function (){ streamsParsed = 0; while (streamsParsed < num_Streams) { streamtypes.push(this.readU16()); - streamsParsed++; + streamsParsed ++; } - props = this.parseProperties({1:BOOL, 2:BOOL}); + props = this.parseProperties({ 1:BOOL, 2:BOOL }); clip.looping = props.get(1, true); clip.stitchFinalFrame = props.get(2, false); @@ -928,7 +928,7 @@ THREE.AWDLoader = (function (){ if (streamtypes[streamsParsed] == 1) { //geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 ); - var buffer = new Float32Array(str_len/4); + var buffer = new Float32Array(str_len / 4); geom.morphTargets.push( { array : buffer }); @@ -938,21 +938,21 @@ THREE.AWDLoader = (function (){ while ( this._ptr < str_end ) { buffer[idx] = this.readF32(); - buffer[idx+1] = this.readF32(); - buffer[idx+2] = this.readF32(); + buffer[idx + 1] = this.readF32(); + buffer[idx + 2] = this.readF32(); idx += 3; } - subMeshParsed++; + subMeshParsed ++; } else this._ptr = str_end; - streamsParsed++; + streamsParsed ++; } } - frames_parsed++; + frames_parsed ++; } this.parseUserAttributes(); @@ -1009,15 +1009,15 @@ THREE.AWDLoader = (function (){ var props = new AWDProperties(); - if( expected ) { + if ( expected ) { - while( this._ptr < list_end ) { + while ( this._ptr < list_end ) { var key = this.readU16(); var len = this.readU32(); var type; - if( expected.hasOwnProperty( key ) ) { + if ( expected.hasOwnProperty( key ) ) { type = expected[ key ]; props.set( key, this.parseAttrValue( type, len ) ); } else { @@ -1102,7 +1102,7 @@ THREE.AWDLoader = (function (){ while (num_read < num_elems) { list.push(read_func.call( this ) ); - num_read++; + num_read ++; } return list; @@ -1115,10 +1115,10 @@ THREE.AWDLoader = (function (){ AWDLoader.prototype.readU8 = function () { - return this._data.getUint8( this._ptr++ ); + return this._data.getUint8( this._ptr ++ ); } AWDLoader.prototype.readI8 = function () { - return this._data.getInt8( this._ptr++ ); + return this._data.getInt8( this._ptr ++ ); } AWDLoader.prototype.readU16 = function () { @@ -1178,16 +1178,16 @@ THREE.AWDLoader = (function (){ var out = [], c = 0; while ( out.length < len ) { - var c1 = this._data.getUint8( this._ptr++, littleEndian ); + var c1 = this._data.getUint8( this._ptr ++, littleEndian ); if (c1 < 128) { - out[c++] = String.fromCharCode(c1); + out[c ++] = String.fromCharCode(c1); } else if (c1 > 191 && c1 < 224) { - var c2 = this._data.getUint8( this._ptr++, littleEndian ); - out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); + var c2 = this._data.getUint8( this._ptr ++, littleEndian ); + out[c ++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); } else { - var c2 = this._data.getUint8( this._ptr++, littleEndian ); - var c3 = this._data.getUint8( this._ptr++, littleEndian ); - out[c++] = String.fromCharCode( + var c2 = this._data.getUint8( this._ptr ++, littleEndian ); + var c3 = this._data.getUint8( this._ptr ++, littleEndian ); + out[c ++] = String.fromCharCode( (c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63 ); } @@ -1203,7 +1203,7 @@ THREE.AWDLoader = (function (){ - AWDProperties = function(){} + AWDProperties = function() {} AWDProperties.prototype = { diff --git a/examples/js/loaders/AssimpJSONLoader.js b/examples/js/loaders/AssimpJSONLoader.js index dffc583f8919ab..a94c0984e08b6d 100644 --- a/examples/js/loaders/AssimpJSONLoader.js +++ b/examples/js/loaders/AssimpJSONLoader.js @@ -74,7 +74,7 @@ THREE.AssimpJSONLoader.prototype = { parseList : function(json, handler) { var meshes = new Array(json.length); - for(var i = 0; i < json.length; ++i) { + for (var i = 0; i < json.length; ++ i) { meshes[i] = handler.call(this, json[i]); } return meshes; @@ -87,13 +87,13 @@ THREE.AssimpJSONLoader.prototype = { geometry = new THREE.Geometry(); // read vertex positions - for(in_data = json.vertices, i = 0, e = in_data.length; i < e; ) { - geometry.vertices.push( new THREE.Vector3( in_data[ i++ ], in_data[ i++ ], in_data[ i++ ] ) ); + for (in_data = json.vertices, i = 0, e = in_data.length; i < e; ) { + geometry.vertices.push( new THREE.Vector3( in_data[ i ++ ], in_data[ i ++ ], in_data[ i ++ ] ) ); } // read faces var cnt = 0; - for(in_data = json.faces, i = 0, e = in_data.length; i < e; ++i) { + for (in_data = json.faces, i = 0, e = in_data.length; i < e; ++ i) { face = new THREE.Face3(); src = in_data[i]; face.a = src[0]; @@ -106,12 +106,12 @@ THREE.AssimpJSONLoader.prototype = { // read texture coordinates - three.js attaches them to its faces json.texturecoords = json.texturecoords || []; - for(i = 0, e = json.texturecoords.length; i < e; ++i) { + for (i = 0, e = json.texturecoords.length; i < e; ++ i) { function convertTextureCoords(in_uv, out_faces, out_vertex_uvs) { var i, e, face, a, b, c; - for(i = 0, e = out_faces.length; i < e; ++i) { + for (i = 0, e = out_faces.length; i < e; ++ i) { face = out_faces[i]; a = face.a * 2; b = face.b * 2; @@ -128,12 +128,12 @@ THREE.AssimpJSONLoader.prototype = { } // read normals - three.js also attaches them to its faces - if(json.normals) { + if (json.normals) { function convertNormals(in_nor, out_faces) { var i, e, face, a, b, c; - for(i = 0, e = out_faces.length; i < e; ++i) { + for (i = 0, e = out_faces.length; i < e; ++ i) { face = out_faces[i]; a = face.a * 3; b = face.b * 3; @@ -150,7 +150,7 @@ THREE.AssimpJSONLoader.prototype = { } // read vertex colors - three.js also attaches them to its faces - if(json.colors && json.colors[0]) { + if (json.colors && json.colors[0]) { function convertColors(in_color, out_faces) { var i, e, face, a, b, c; @@ -162,7 +162,7 @@ THREE.AssimpJSONLoader.prototype = { return col; } - for(i = 0, e = out_faces.length; i < e; ++i) { + for (i = 0, e = out_faces.length; i < e; ++ i) { face = out_faces[i]; a = face.a * 4; b = face.b * 4; @@ -198,7 +198,7 @@ THREE.AssimpJSONLoader.prototype = { function toColor(value_arr) { var col = new THREE.Color(); - col.setRGB(value_arr[0],value_arr[1],value_arr[2]); + col.setRGB(value_arr[0], value_arr[1], value_arr[2]); return col; } @@ -212,28 +212,28 @@ THREE.AssimpJSONLoader.prototype = { for (var i in json.properties) { prop = json.properties[i]; - if(prop.key === '$tex.file') { + if (prop.key === '$tex.file') { // prop.semantic gives the type of the texture // 1: diffuse // 2: specular mao // 5: height map (bumps) // 6: normal map // more values (i.e. emissive, environment) are known by assimp and may be relevant - if(prop.semantic === 1 || prop.semantic === 5 || prop.semantic === 6 || prop.semantic === 2) { + if (prop.semantic === 1 || prop.semantic === 5 || prop.semantic === 6 || prop.semantic === 2) { (function(semantic) { var loader = new THREE.TextureLoader(scope.manager), keyname; - if(semantic === 1) { + if (semantic === 1) { keyname = 'map'; } - else if(semantic === 5) { + else if (semantic === 5) { keyname = 'bumpMap'; } - else if(semantic === 6) { + else if (semantic === 6) { keyname = 'normalMap'; } - else if(semantic === 2) { + else if (semantic === 2) { keyname = 'specularMap'; } @@ -243,7 +243,7 @@ THREE.AssimpJSONLoader.prototype = { var material_url = scope.texturePath + '/' + prop.value material_url = material_url.replace(/\\/g, '/'); loader.load(material_url, function(tex) { - if(tex) { + if (tex) { // TODO: read texture settings from assimp. // Wrapping is the default, though. tex.wrapS = tex.wrapT = THREE.RepeatWrapping; @@ -255,19 +255,19 @@ THREE.AssimpJSONLoader.prototype = { })(prop.semantic); } } - else if(prop.key === '?mat.name') { + else if (prop.key === '?mat.name') { init_props.name = prop.value; } - else if(prop.key === '$clr.diffuse') { + else if (prop.key === '$clr.diffuse') { init_props.color = toColor(prop.value); } - else if(prop.key === '$clr.specular') { + else if (prop.key === '$clr.specular') { init_props.specular = toColor(prop.value); } - else if(prop.key === '$clr.emissive') { + else if (prop.key === '$clr.emissive') { init_props.emissive = toColor(prop.value); } - else if(prop.key === '$mat.shadingm') { + else if (prop.key === '$mat.shadingm') { // aiShadingMode_Flat if (prop.value === 1) { init_props.shading = THREE.FlatShading; @@ -281,8 +281,8 @@ THREE.AssimpJSONLoader.prototype = { // note: three.js does not like it when a texture is added after the geometry // has been rendered once, see http://stackoverflow.com/questions/16531759/. // for this reason we fill all slots upfront with default textures - if(has_textures.length) { - for(i = has_textures.length-1; i >= 0; --i) { + if (has_textures.length) { + for (i = has_textures.length - 1; i >= 0; -- i) { init_props[has_textures[i]] = defaultTexture(); } } @@ -301,12 +301,12 @@ THREE.AssimpJSONLoader.prototype = { obj.matrix = new THREE.Matrix4().fromArray(node.transformation).transpose(); obj.matrix.decompose( obj.position, obj.quaternion, obj.scale ); - for(i = 0; node.meshes && i < node.meshes.length; ++i) { + for (i = 0; node.meshes && i < node.meshes.length; ++ i) { idx = node.meshes[i]; obj.add(new THREE.Mesh( meshes[idx], materials[json.meshes[idx].materialindex] )); } - for(i = 0; node.children && i < node.children.length; ++i) { + for (i = 0; node.children && i < node.children.length; ++ i) { obj.add(this.parseObject(json, node.children[i], meshes, materials)); } diff --git a/examples/js/loaders/BinaryLoader.js b/examples/js/loaders/BinaryLoader.js index a731612102037c..0c2db6c0ee9501 100644 --- a/examples/js/loaders/BinaryLoader.js +++ b/examples/js/loaders/BinaryLoader.js @@ -192,7 +192,7 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture start_quad_flat = start_tri_smooth_uv + len_tri_smooth_uv + handlePadding( md.ntri_smooth_uv * 2 ); start_quad_smooth = start_quad_flat + len_quad_flat + handlePadding( md.nquad_flat * 2 ); start_quad_flat_uv = start_quad_smooth + len_quad_smooth + handlePadding( md.nquad_smooth * 2 ); - start_quad_smooth_uv= start_quad_flat_uv + len_quad_flat_uv + handlePadding( md.nquad_flat_uv * 2 ); + start_quad_smooth_uv = start_quad_flat_uv + len_quad_flat_uv + handlePadding( md.nquad_flat_uv * 2 ); // have to first process faces with uvs // so that face and uv indices match @@ -236,18 +236,18 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture 'material_index_bytes' :parseUChar8( data, offset + 19 ), 'nvertices' :parseUInt32( data, offset + 20 ), - 'nnormals' :parseUInt32( data, offset + 20 + 4*1 ), - 'nuvs' :parseUInt32( data, offset + 20 + 4*2 ), + 'nnormals' :parseUInt32( data, offset + 20 + 4 * 1 ), + 'nuvs' :parseUInt32( data, offset + 20 + 4 * 2 ), - 'ntri_flat' :parseUInt32( data, offset + 20 + 4*3 ), - 'ntri_smooth' :parseUInt32( data, offset + 20 + 4*4 ), - 'ntri_flat_uv' :parseUInt32( data, offset + 20 + 4*5 ), - 'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4*6 ), + 'ntri_flat' :parseUInt32( data, offset + 20 + 4 * 3 ), + 'ntri_smooth' :parseUInt32( data, offset + 20 + 4 * 4 ), + 'ntri_flat_uv' :parseUInt32( data, offset + 20 + 4 * 5 ), + 'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4 * 6 ), - 'nquad_flat' :parseUInt32( data, offset + 20 + 4*7 ), - 'nquad_smooth' :parseUInt32( data, offset + 20 + 4*8 ), - 'nquad_flat_uv' :parseUInt32( data, offset + 20 + 4*9 ), - 'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4*10 ) + 'nquad_flat' :parseUInt32( data, offset + 20 + 4 * 7 ), + 'nquad_smooth' :parseUInt32( data, offset + 20 + 4 * 8 ), + 'nquad_flat_uv' :parseUInt32( data, offset + 20 + 4 * 9 ), + 'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4 * 10 ) }; /* @@ -336,7 +336,7 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var i, x, y, z; - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { x = coordArray[ i * 3 ]; y = coordArray[ i * 3 + 1 ]; @@ -360,13 +360,13 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var i, x, y, z; - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { x = normalArray[ i * 3 ]; y = normalArray[ i * 3 + 1 ]; z = normalArray[ i * 3 + 2 ]; - normals.push( x/127, y/127, z/127 ); + normals.push( x / 127, y / 127, z / 127 ); } @@ -386,7 +386,7 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var i, u, v; - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { u = uvArray[ i * 2 ]; v = uvArray[ i * 2 + 1 ]; @@ -407,20 +407,20 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements ); - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { uva = uvIndexBuffer[ i * 3 ]; uvb = uvIndexBuffer[ i * 3 + 1 ]; uvc = uvIndexBuffer[ i * 3 + 2 ]; - u1 = uvs[ uva*2 ]; - v1 = uvs[ uva*2 + 1 ]; + u1 = uvs[ uva * 2 ]; + v1 = uvs[ uva * 2 + 1 ]; - u2 = uvs[ uvb*2 ]; - v2 = uvs[ uvb*2 + 1 ]; + u2 = uvs[ uvb * 2 ]; + v2 = uvs[ uvb * 2 + 1 ]; - u3 = uvs[ uvc*2 ]; - v3 = uvs[ uvc*2 + 1 ]; + u3 = uvs[ uvc * 2 ]; + v3 = uvs[ uvc * 2 + 1 ]; scope.faceVertexUvs[ 0 ].push( [ new THREE.Vector2( u1, v1 ), @@ -438,24 +438,24 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements ); - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { uva = uvIndexBuffer[ i * 4 ]; uvb = uvIndexBuffer[ i * 4 + 1 ]; uvc = uvIndexBuffer[ i * 4 + 2 ]; uvd = uvIndexBuffer[ i * 4 + 3 ]; - u1 = uvs[ uva*2 ]; - v1 = uvs[ uva*2 + 1 ]; + u1 = uvs[ uva * 2 ]; + v1 = uvs[ uva * 2 + 1 ]; - u2 = uvs[ uvb*2 ]; - v2 = uvs[ uvb*2 + 1 ]; + u2 = uvs[ uvb * 2 ]; + v2 = uvs[ uvb * 2 + 1 ]; - u3 = uvs[ uvc*2 ]; - v3 = uvs[ uvc*2 + 1 ]; + u3 = uvs[ uvc * 2 ]; + v3 = uvs[ uvc * 2 + 1 ]; - u4 = uvs[ uvd*2 ]; - v4 = uvs[ uvd*2 + 1 ]; + u4 = uvs[ uvd * 2 ]; + v4 = uvs[ uvd * 2 + 1 ]; scope.faceVertexUvs[ 0 ].push( [ new THREE.Vector2( u1, v1 ), @@ -480,7 +480,7 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements ); var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements ); - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { a = vertexIndexBuffer[ i * 3 ]; b = vertexIndexBuffer[ i * 3 + 1 ]; @@ -501,7 +501,7 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements ); var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements ); - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { a = vertexIndexBuffer[ i * 4 ]; b = vertexIndexBuffer[ i * 4 + 1 ]; @@ -526,7 +526,7 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements ); var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements ); - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { a = vertexIndexBuffer[ i * 3 ]; b = vertexIndexBuffer[ i * 3 + 1 ]; @@ -538,17 +538,17 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture m = materialIndexBuffer[ i ]; - var nax = normals[ na*3 ], - nay = normals[ na*3 + 1 ], - naz = normals[ na*3 + 2 ], + var nax = normals[ na * 3 ], + nay = normals[ na * 3 + 1 ], + naz = normals[ na * 3 + 2 ], - nbx = normals[ nb*3 ], - nby = normals[ nb*3 + 1 ], - nbz = normals[ nb*3 + 2 ], + nbx = normals[ nb * 3 ], + nby = normals[ nb * 3 + 1 ], + nbz = normals[ nb * 3 + 2 ], - ncx = normals[ nc*3 ], - ncy = normals[ nc*3 + 1 ], - ncz = normals[ nc*3 + 2 ]; + ncx = normals[ nc * 3 ], + ncy = normals[ nc * 3 + 1 ], + ncz = normals[ nc * 3 + 2 ]; scope.faces.push( new THREE.Face3( a, b, c, [ new THREE.Vector3( nax, nay, naz ), @@ -569,7 +569,7 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements ); var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements ); - for( i = 0; i < nElements; i ++ ) { + for ( i = 0; i < nElements; i ++ ) { a = vertexIndexBuffer[ i * 4 ]; b = vertexIndexBuffer[ i * 4 + 1 ]; @@ -583,21 +583,21 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture m = materialIndexBuffer[ i ]; - var nax = normals[ na*3 ], - nay = normals[ na*3 + 1 ], - naz = normals[ na*3 + 2 ], + var nax = normals[ na * 3 ], + nay = normals[ na * 3 + 1 ], + naz = normals[ na * 3 + 2 ], - nbx = normals[ nb*3 ], - nby = normals[ nb*3 + 1 ], - nbz = normals[ nb*3 + 2 ], + nbx = normals[ nb * 3 ], + nby = normals[ nb * 3 + 1 ], + nbz = normals[ nb * 3 + 2 ], - ncx = normals[ nc*3 ], - ncy = normals[ nc*3 + 1 ], - ncz = normals[ nc*3 + 2 ], + ncx = normals[ nc * 3 ], + ncy = normals[ nc * 3 + 1 ], + ncz = normals[ nc * 3 + 2 ], - ndx = normals[ nd*3 ], - ndy = normals[ nd*3 + 1 ], - ndz = normals[ nd*3 + 2 ]; + ndx = normals[ nd * 3 ], + ndy = normals[ nd * 3 + 1 ], + ndz = normals[ nd * 3 + 2 ]; scope.faces.push( new THREE.Face3( a, b, d, [ new THREE.Vector3( nax, nay, naz ), diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index 127e33a47da94c..1d0f43d00747e6 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -66,9 +66,9 @@ THREE.ColladaLoader = function () { request.onreadystatechange = function() { - if( request.readyState === 4 ) { + if ( request.readyState === 4 ) { - if( request.status === 0 || request.status === 200 ) { + if ( request.status === 0 || request.status === 200 ) { if ( request.responseXML ) { @@ -334,7 +334,7 @@ THREE.ColladaLoader = function () { animData.push(newData); - for ( var i = 0, il = n.keys.length; i < il; i++ ) { + for ( var i = 0, il = n.keys.length; i < il; i ++ ) { newData.length = Math.max( newData.length, n.keys[i].time ); @@ -351,7 +351,7 @@ THREE.ColladaLoader = function () { } - for ( var i = 0, il = node.children.length; i < il; i++ ) { + for ( var i = 0, il = node.children.length; i < il; i ++ ) { var d = recurseHierarchy( node.children[i] ); @@ -505,7 +505,7 @@ THREE.ColladaLoader = function () { node.world.copy( m ); node.localworld.copy(m); - if(frame === 0) + if (frame === 0) node.matrix.copy(m); } @@ -599,24 +599,24 @@ THREE.ColladaLoader = function () { bone.name = node.sid; bone.parent = parentid; bone.matrix = node.matrix; - var data = [new THREE.Vector3(),new THREE.Quaternion(),new THREE.Vector3()]; - bone.matrix.decompose(data[0],data[1],data[2]); + var data = [ new THREE.Vector3(),new THREE.Quaternion(),new THREE.Vector3() ]; + bone.matrix.decompose(data[0], data[1], data[2]); - bone.pos = [data[0].x,data[0].y,data[0].z]; + bone.pos = [ data[0].x,data[0].y,data[0].z ]; - bone.scl = [data[2].x,data[2].y,data[2].z]; - bone.rotq = [data[1].x,data[1].y,data[1].z,data[1].w]; + bone.scl = [ data[2].x,data[2].y,data[2].z ]; + bone.rotq = [ data[1].x,data[1].y,data[1].z,data[1].w ]; list.push(bone); - for(var i in node.nodes) { + for (var i in node.nodes) { - walk(node.sid,node.nodes[i],list); + walk(node.sid, node.nodes[i], list); } }; - walk(-1,skeleton,list); + walk(-1, skeleton, list); return list; } @@ -630,7 +630,7 @@ THREE.ColladaLoader = function () { v = new THREE.Vector3(); var skinned = []; - for(var i =0; i < geometry.vertices.length; i++) { + for (var i = 0; i < geometry.vertices.length; i ++) { skinned.push(new THREE.Vector3()); @@ -662,7 +662,7 @@ THREE.ColladaLoader = function () { } - for(var i =0; i < geometry.vertices.length; i++) { + for (var i = 0; i < geometry.vertices.length; i ++) { geometry.vertices[i] = skinned[i]; @@ -700,11 +700,11 @@ THREE.ColladaLoader = function () { //sort that list so that the order reflects the order in the joint list var sortedbones = []; - for(var i = 0; i < joints.length; i++) { + for (var i = 0; i < joints.length; i ++) { - for(var j =0; j < bonelist.length; j++) { + for (var j = 0; j < bonelist.length; j ++) { - if(bonelist[j].name === joints[i]) { + if (bonelist[j].name === joints[i]) { sortedbones[i] = bonelist[j]; @@ -715,11 +715,11 @@ THREE.ColladaLoader = function () { } //hook up the parents by index instead of name - for(var i = 0; i < sortedbones.length; i++) { + for (var i = 0; i < sortedbones.length; i ++) { - for(var j =0; j < sortedbones.length; j++) { + for (var j = 0; j < sortedbones.length; j ++) { - if(sortedbones[i].parent === sortedbones[j].name) { + if (sortedbones[i].parent === sortedbones[j].name) { sortedbones[i].parent = j; @@ -744,10 +744,10 @@ THREE.ColladaLoader = function () { //hook up the skin weights // TODO - this might be a good place to choose greatest 4 weights - for(var i =0; i < weights.length; i++) { + for (var i = 0; i < weights.length; i ++) { - var indicies = new THREE.Vector4(weights[i][0]?weights[i][0].joint:0,weights[i][1]?weights[i][1].joint:0,weights[i][2]?weights[i][2].joint:0,weights[i][3]?weights[i][3].joint:0); - var weight = new THREE.Vector4(weights[i][0]?weights[i][0].weight:0,weights[i][1]?weights[i][1].weight:0,weights[i][2]?weights[i][2].weight:0,weights[i][3]?weights[i][3].weight:0); + var indicies = new THREE.Vector4(weights[i][0] ? weights[i][0].joint : 0,weights[i][1] ? weights[i][1].joint : 0,weights[i][2] ? weights[i][2].joint : 0,weights[i][3] ? weights[i][3].joint : 0); + var weight = new THREE.Vector4(weights[i][0] ? weights[i][0].weight : 0,weights[i][1] ? weights[i][1].weight : 0,weights[i][2] ? weights[i][2].weight : 0,weights[i][3] ? weights[i][3].weight : 0); skinIndices.push(indicies); skinWeights.push(weight); @@ -761,11 +761,11 @@ THREE.ColladaLoader = function () { //create an animation for the animated bones //NOTE: this has no effect when using morphtargets - var animationdata = {"name":animationBounds.ID,"fps":30,"length":animationBounds.frames/30,"hierarchy":[]}; + var animationdata = { "name":animationBounds.ID,"fps":30,"length":animationBounds.frames / 30,"hierarchy":[] }; - for(var j =0; j < sortedbones.length; j++) { + for (var j = 0; j < sortedbones.length; j ++) { - animationdata.hierarchy.push({parent:sortedbones[j].parent, name:sortedbones[j].name, keys:[]}); + animationdata.hierarchy.push({ parent:sortedbones[j].parent, name:sortedbones[j].name, keys:[] }); } @@ -773,7 +773,7 @@ THREE.ColladaLoader = function () { - skinToBindPose(geometry,skeleton,skinController); + skinToBindPose(geometry, skeleton, skinController); for ( frame = 0; frame < animationBounds.frames; frame ++ ) { @@ -786,25 +786,25 @@ THREE.ColladaLoader = function () { setupSkeleton( skeleton, bones, frame ); setupSkinningMatrices( bones, skinController.skin ); - for(var i = 0; i < bones.length; i ++) { + for (var i = 0; i < bones.length; i ++) { - for(var j = 0; j < animationdata.hierarchy.length; j ++) { + for (var j = 0; j < animationdata.hierarchy.length; j ++) { - if(animationdata.hierarchy[j].name === bones[i].sid) { + if (animationdata.hierarchy[j].name === bones[i].sid) { var key = {}; - key.time = (frame/30); + key.time = (frame / 30); key.matrix = bones[i].animatrix; - if(frame === 0) + if (frame === 0) bones[i].matrix = key.matrix; - var data = [new THREE.Vector3(),new THREE.Quaternion(),new THREE.Vector3()]; - key.matrix.decompose(data[0],data[1],data[2]); + var data = [ new THREE.Vector3(),new THREE.Quaternion(),new THREE.Vector3() ]; + key.matrix.decompose(data[0], data[1], data[2]); - key.pos = [data[0].x,data[0].y,data[0].z]; + key.pos = [ data[0].x,data[0].y,data[0].z ]; - key.scl = [data[2].x,data[2].y,data[2].z]; + key.scl = [ data[2].x,data[2].y,data[2].z ]; key.rot = data[1]; animationdata.hierarchy[j].keys.push(key); @@ -897,7 +897,7 @@ THREE.ColladaLoader = function () { var matrix = new THREE.Matrix4(); - for (i = 0; i < transforms.length; i++ ) { + for (i = 0; i < transforms.length; i ++ ) { var transform = transforms[ i ]; @@ -1345,7 +1345,7 @@ THREE.ColladaLoader = function () { var nodes = COLLADA.querySelectorAll('library_nodes node'); - for ( var i = 0; i < nodes.length; i++ ) { + for ( var i = 0; i < nodes.length; i ++ ) { var attObj = nodes[i].attributes.getNamedItem('id'); if ( attObj && attObj.value === id ) { @@ -1495,7 +1495,7 @@ THREE.ColladaLoader = function () { var keys = [], sids = []; - for ( var i = 0, il = node.channels.length; i < il; i++ ) { + for ( var i = 0, il = node.channels.length; i < il; i ++ ) { var channel = node.channels[i], fullSid = channel.fullSid, @@ -1508,7 +1508,7 @@ THREE.ColladaLoader = function () { member = []; - for ( var j = 0, jl = channel.arrIndices.length; j < jl; j++ ) { + for ( var j = 0, jl = channel.arrIndices.length; j < jl; j ++ ) { member[ j ] = getConvertedIndex( channel.arrIndices[ j ] ); @@ -1528,7 +1528,7 @@ THREE.ColladaLoader = function () { } - for ( var j = 0, jl = input.length; j < jl; j++ ) { + for ( var j = 0, jl = input.length; j < jl; j ++ ) { var time = input[j], data = sampler.getData( transform.type, j, member ), @@ -1555,11 +1555,11 @@ THREE.ColladaLoader = function () { } // post process - for ( var i = 0; i < sids.length; i++ ) { + for ( var i = 0; i < sids.length; i ++ ) { var sid = sids[ i ]; - for ( var j = 0; j < keys.length; j++ ) { + for ( var j = 0; j < keys.length; j ++ ) { var key = keys[ j ]; @@ -1584,7 +1584,7 @@ THREE.ColladaLoader = function () { var retVal = null; - for ( var i = 0, il = keys.length; i < il && retVal === null; i++ ) { + for ( var i = 0, il = keys.length; i < il && retVal === null; i ++ ) { var key = keys[i]; @@ -1608,7 +1608,7 @@ THREE.ColladaLoader = function () { var ndx = -1; - for ( var i = 0, il = keys.length; i < il && ndx === -1; i++ ) { + for ( var i = 0, il = keys.length; i < il && ndx === -1; i ++ ) { var key = keys[i]; @@ -1626,8 +1626,8 @@ THREE.ColladaLoader = function () { function interpolateKeys ( keys, key, ndx, fullSid ) { - var prevKey = getPrevKeyWith( keys, fullSid, ndx ? ndx-1 : 0 ), - nextKey = getNextKeyWith( keys, fullSid, ndx+1 ); + var prevKey = getPrevKeyWith( keys, fullSid, ndx ? ndx - 1 : 0 ), + nextKey = getNextKeyWith( keys, fullSid, ndx + 1 ); if ( prevKey && nextKey ) { @@ -1645,7 +1645,7 @@ THREE.ColladaLoader = function () { data = []; - for ( var i = 0; i < prevData.length; ++i ) { + for ( var i = 0; i < prevData.length; ++ i ) { data[ i ] = prevData[ i ] + ( nextData[ i ] - prevData[ i ] ) * scale; @@ -1667,7 +1667,7 @@ THREE.ColladaLoader = function () { function getNextKeyWith( keys, fullSid, ndx ) { - for ( ; ndx < keys.length; ndx++ ) { + for ( ; ndx < keys.length; ndx ++ ) { var key = keys[ ndx ]; @@ -1689,7 +1689,7 @@ THREE.ColladaLoader = function () { ndx = ndx >= 0 ? ndx : ndx + keys.length; - for ( ; ndx >= 0; ndx-- ) { + for ( ; ndx >= 0; ndx -- ) { var key = keys[ ndx ]; @@ -1748,7 +1748,7 @@ THREE.ColladaLoader = function () { this.name = element.getAttribute('name'); this.type = "none"; - for ( var i = 0; i < element.childNodes.length; i++ ) { + for ( var i = 0; i < element.childNodes.length; i ++ ) { var child = element.childNodes[ i ]; @@ -2011,7 +2011,7 @@ THREE.ColladaLoader = function () { var numBones = vcount[i]; var vertex_weights = []; - for ( var j = 0; j < numBones; j++ ) { + for ( var j = 0; j < numBones; j ++ ) { var influence = {}; @@ -2633,7 +2633,7 @@ THREE.ColladaLoader = function () { var instances = child.querySelectorAll('instance_material'); - for ( var j = 0; j < instances.length; j ++ ){ + for ( var j = 0; j < instances.length; j ++ ) { var instance = instances[j]; this.instance_material.push( (new InstanceMaterial()).parse(instance) ); @@ -2862,7 +2862,7 @@ THREE.ColladaLoader = function () { input = inputs[ j ]; var offset = input.offset + 1; - maxOffset = (maxOffset < offset)? offset : maxOffset; + maxOffset = (maxOffset < offset) ? offset : maxOffset; switch ( input.semantic ) { @@ -2874,7 +2874,7 @@ THREE.ColladaLoader = function () { } - for ( var pCount = 0; pCount < pList.length; ++pCount ) { + for ( var pCount = 0; pCount < pList.length; ++ pCount ) { var p = pList[ pCount ], i = 0; @@ -2956,7 +2956,7 @@ THREE.ColladaLoader = function () { source = sources[ input.source ]; numParams = source.accessor.params.length; - for ( var ndx = 0, len = vs.length; ndx < len; ndx++ ) { + for ( var ndx = 0, len = vs.length; ndx < len; ndx ++ ) { ns.push( getConvertedVec3( source.data, vs[ ndx ] * numParams ) ); @@ -2982,7 +2982,7 @@ THREE.ColladaLoader = function () { source = sources[ input.source ]; numParams = source.accessor.params.length; - for ( var ndx = 0, len = vs.length; ndx < len; ndx++ ) { + for ( var ndx = 0, len = vs.length; ndx < len; ndx ++ ) { idx32 = vs[ ndx ] * numParams; if ( ts[ input.set ] === undefined ) ts[ input.set ] = [ ]; @@ -3005,7 +3005,7 @@ THREE.ColladaLoader = function () { source = sources[ input.source ]; numParams = source.accessor.params.length; - for ( var ndx = 0, len = vs.length; ndx < len; ndx++ ) { + for ( var ndx = 0, len = vs.length; ndx < len; ndx ++ ) { idx32 = vs[ ndx ] * numParams; cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) ); @@ -3024,9 +3024,9 @@ THREE.ColladaLoader = function () { } else if ( vcount === 4 ) { - faces.push( new THREE.Face3( vs[0], vs[1], vs[3], [ns[0], ns[1], ns[3]], cs.length ? [cs[0], cs[1], cs[3]] : new THREE.Color() ) ); + faces.push( new THREE.Face3( vs[0], vs[1], vs[3], [ ns[0], ns[1], ns[3]], cs.length ? [ cs[0], cs[1], cs[3]] : new THREE.Color() ) ); - faces.push( new THREE.Face3( vs[1], vs[2], vs[3], [ns[1], ns[2], ns[3]], cs.length ? [cs[1], cs[2], cs[3]] : new THREE.Color() ) ); + faces.push( new THREE.Face3( vs[1], vs[2], vs[3], [ ns[1], ns[2], ns[3]], cs.length ? [ cs[1], cs[2], cs[3]] : new THREE.Color() ) ); } else if ( vcount > 4 && options.subdivideFaces ) { @@ -3039,7 +3039,7 @@ THREE.ColladaLoader = function () { // FIXME: normals don't seem to be quite right - faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ], clr ) ); + faces.push( new THREE.Face3( vs[0], vs[k], vs[k + 1], [ ns[0], ns[k ++], ns[k] ], clr ) ); } @@ -3053,14 +3053,14 @@ THREE.ColladaLoader = function () { face.daeMaterial = primitive.material; geom.faces.push( face ); - for ( k = 0; k < texture_sets.length; k++ ) { + for ( k = 0; k < texture_sets.length; k ++ ) { uv = ts[ texture_sets[k] ]; if ( vcount > 4 ) { // Grab the right UVs for the vertices in this face - uvArr = [ uv[0], uv[ndx+1], uv[ndx+2] ]; + uvArr = [ uv[0], uv[ndx + 1], uv[ndx + 2] ]; } else if ( vcount === 4 ) { @@ -3661,7 +3661,7 @@ THREE.ColladaLoader = function () { var keys = { 'diffuse':'map', - 'ambient':'lightMap' , + 'ambient':'lightMap', 'specular':'specularMap', 'emission':'emissionMap', 'bump':'bumpMap', @@ -3758,7 +3758,7 @@ THREE.ColladaLoader = function () { case 'reflectivity': props[ prop ] = this[ prop ]; - if( props[ prop ] > 0.0 ) props['envMap'] = options.defaultEnvMap; + if ( props[ prop ] > 0.0 ) props['envMap'] = options.defaultEnvMap; props['combine'] = THREE.MixOperation; //mix regular shading with reflective component break; @@ -4051,7 +4051,7 @@ THREE.ColladaLoader = function () { }; - Effect.prototype.parseTechnique= function ( element ) { + Effect.prototype.parseTechnique = function ( element ) { for ( var i = 0; i < element.childNodes.length; i ++ ) { @@ -4100,7 +4100,7 @@ THREE.ColladaLoader = function () { }; - Effect.prototype.parseExtraTechnique= function ( element ) { + Effect.prototype.parseExtraTechnique = function ( element ) { for ( var i = 0; i < element.childNodes.length; i ++ ) { @@ -4384,7 +4384,7 @@ THREE.ColladaLoader = function () { data = []; ndx *= this.strideOut; - for ( var i = 0; i < this.strideOut; ++i ) { + for ( var i = 0; i < this.strideOut; ++ i ) { data[ i ] = this.output[ ndx + i ]; @@ -4447,7 +4447,7 @@ THREE.ColladaLoader = function () { Key.prototype.apply = function ( opt_sid ) { - for ( var i = 0; i < this.targets.length; ++i ) { + for ( var i = 0; i < this.targets.length; ++ i ) { var target = this.targets[ i ]; @@ -4463,7 +4463,7 @@ THREE.ColladaLoader = function () { Key.prototype.getTarget = function ( fullSid ) { - for ( var i = 0; i < this.targets.length; ++i ) { + for ( var i = 0; i < this.targets.length; ++ i ) { if ( this.targets[ i ].sid === fullSid ) { @@ -4479,7 +4479,7 @@ THREE.ColladaLoader = function () { Key.prototype.hasTarget = function ( fullSid ) { - for ( var i = 0; i < this.targets.length; ++i ) { + for ( var i = 0; i < this.targets.length; ++ i ) { if ( this.targets[ i ].sid === fullSid ) { @@ -4515,7 +4515,7 @@ THREE.ColladaLoader = function () { data = []; - for ( var j = 0; j < prevData.length; ++j ) { + for ( var j = 0; j < prevData.length; ++ j ) { data[ j ] = prevData[ j ] + ( nextData[ j ] - prevData[ j ] ) * scale; @@ -4753,7 +4753,7 @@ THREE.ColladaLoader = function () { case 'quadratic_attenuation': var f = parseFloat( child.textContent ); - this.distance = f ? Math.sqrt( 1/f ) : 0; + this.distance = f ? Math.sqrt( 1 / f ) : 0; } } @@ -4819,7 +4819,7 @@ THREE.ColladaLoader = function () { this.joints = []; this.links = []; - for (var i = 0; i < element.childNodes.length; i++ ) { + for (var i = 0; i < element.childNodes.length; i ++ ) { var child = element.childNodes[ i ]; if ( child.nodeType != 1 ) continue; @@ -4844,7 +4844,7 @@ THREE.ColladaLoader = function () { KinematicsModel.prototype.parseCommon = function( element ) { - for (var i = 0; i < element.childNodes.length; i++ ) { + for (var i = 0; i < element.childNodes.length; i ++ ) { var child = element.childNodes[ i ]; if ( child.nodeType != 1 ) continue; @@ -4912,8 +4912,8 @@ THREE.ColladaLoader = function () { max: max }; - var jointTypes = ['prismatic', 'revolute']; - for (var i = 0; i < jointTypes.length; i++ ) { + var jointTypes = [ 'prismatic', 'revolute' ]; + for (var i = 0; i < jointTypes.length; i ++ ) { var type = jointTypes[ i ]; @@ -4955,7 +4955,7 @@ THREE.ColladaLoader = function () { this.transforms = []; this.attachments = []; - for (var i = 0; i < element.childNodes.length; i++ ) { + for (var i = 0; i < element.childNodes.length; i ++ ) { var child = element.childNodes[ i ]; if ( child.nodeType != 1 ) continue; @@ -4998,7 +4998,7 @@ THREE.ColladaLoader = function () { this.joint = element.getAttribute('joint').split('/').pop(); this.links = []; - for (var i = 0; i < element.childNodes.length; i++ ) { + for (var i = 0; i < element.childNodes.length; i ++ ) { var child = element.childNodes[ i ]; if ( child.nodeType != 1 ) continue; @@ -5175,7 +5175,7 @@ THREE.ColladaLoader = function () { var parts = f.toString().split( '.' ); parts[ 1 ] = parts.length > 1 ? parts[ 1 ].substr( 0, num ) : "0"; - while( parts[ 1 ].length < num ) { + while ( parts[ 1 ].length < num ) { parts[ 1 ] += '0'; @@ -5401,7 +5401,7 @@ THREE.ColladaLoader = function () { if ( index > -1 && index < 3 ) { - var members = ['X', 'Y', 'Z'], + var members = [ 'X', 'Y', 'Z' ], indices = { X: 0, Y: 1, Z: 2 }; index = getConvertedMember( members[ index ] ); diff --git a/examples/js/loaders/DDSLoader.js b/examples/js/loaders/DDSLoader.js index f6fb934e4b02e2..ebf003159f3ea4 100644 --- a/examples/js/loaders/DDSLoader.js +++ b/examples/js/loaders/DDSLoader.js @@ -70,21 +70,21 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) { } function loadARGBMip( buffer, dataOffset, width, height ) { - var dataLength = width*height*4; + var dataLength = width * height * 4; var srcBuffer = new Uint8Array( buffer, dataOffset, dataLength ); var byteArray = new Uint8Array( dataLength ); var dst = 0; var src = 0; - for ( var y = 0; y < height; y++ ) { - for ( var x = 0; x < width; x++ ) { - var b = srcBuffer[src]; src++; - var g = srcBuffer[src]; src++; - var r = srcBuffer[src]; src++; - var a = srcBuffer[src]; src++; - byteArray[dst] = r; dst++; //r - byteArray[dst] = g; dst++; //g - byteArray[dst] = b; dst++; //b - byteArray[dst] = a; dst++; //a + for ( var y = 0; y < height; y ++ ) { + for ( var x = 0; x < width; x ++ ) { + var b = srcBuffer[src]; src ++; + var g = srcBuffer[src]; src ++; + var r = srcBuffer[src]; src ++; + var a = srcBuffer[src]; src ++; + byteArray[dst] = r; dst ++; //r + byteArray[dst] = g; dst ++; //g + byteArray[dst] = b; dst ++; //b + byteArray[dst] = a; dst ++; //a } } return byteArray; @@ -166,7 +166,7 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) { default: - if( header[off_RGBBitCount] ==32 + if ( header[off_RGBBitCount] == 32 && header[off_RBitMask]&0xff0000 && header[off_GBitMask]&0xff00 && header[off_BBitMask]&0xff @@ -208,7 +208,7 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) { for ( var i = 0; i < dds.mipmapCount; i ++ ) { - if( isRGBAUncompressed ) { + if ( isRGBAUncompressed ) { var byteArray = loadARGBMip( buffer, dataOffset, width, height ); var dataLength = byteArray.length; } else { diff --git a/examples/js/loaders/MTLLoader.js b/examples/js/loaders/MTLLoader.js index 5bd4133f2471c1..784c93c0aff56e 100644 --- a/examples/js/loaders/MTLLoader.js +++ b/examples/js/loaders/MTLLoader.js @@ -121,8 +121,8 @@ THREE.MTLLoader.MaterialCreator = function( baseUrl, options ) { this.materialsArray = []; this.nameLookup = {}; - this.side = ( this.options && this.options.side )? this.options.side: THREE.FrontSide; - this.wrap = ( this.options && this.options.wrap )? this.options.wrap: THREE.RepeatWrapping; + this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide; + this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping; }; @@ -426,7 +426,7 @@ THREE.MTLLoader.ensurePowerOfTwo_ = function ( image ) { THREE.MTLLoader.nextHighestPowerOfTwo_ = function( x ) { - --x; + -- x; for ( var i = 1; i < 32; i <<= 1 ) { diff --git a/examples/js/loaders/PDBLoader.js b/examples/js/loaders/PDBLoader.js index 52c56334f948da..bea94eaecfaa03 100644 --- a/examples/js/loaders/PDBLoader.js +++ b/examples/js/loaders/PDBLoader.js @@ -53,7 +53,7 @@ THREE.PDBLoader.prototype = { var eatom = parseInt( lines[ i ].substr( start, length ) ); - if( eatom ) { + if ( eatom ) { var h = hash( satom, eatom ); @@ -75,8 +75,8 @@ THREE.PDBLoader.prototype = { } - var CPK = {"h":[255,255,255],"he":[217,255,255],"li":[204,128,255],"be":[194,255,0],"b":[255,181,181],"c":[144,144,144],"n":[48,80,248],"o":[255,13,13],"f":[144,224,80],"ne":[179,227,245],"na":[171,92,242],"mg":[138,255,0],"al":[191,166,166],"si":[240,200,160],"p":[255,128,0],"s":[255,255,48],"cl":[31,240,31],"ar":[128,209,227],"k":[143,64,212],"ca":[61,255,0],"sc":[230,230,230],"ti":[191,194,199],"v":[166,166,171],"cr":[138,153,199],"mn":[156,122,199],"fe":[224,102,51],"co":[240,144,160],"ni":[80,208,80],"cu":[200,128,51],"zn":[125,128,176],"ga":[194,143,143],"ge":[102,143,143],"as":[189,128,227],"se":[255,161,0],"br":[166,41,41],"kr":[92,184,209],"rb":[112,46,176],"sr":[0,255,0],"y":[148,255,255],"zr":[148,224,224],"nb":[115,194,201],"mo":[84,181,181],"tc":[59,158,158],"ru":[36,143,143],"rh":[10,125,140],"pd":[0,105,133],"ag":[192,192,192],"cd":[255,217,143],"in":[166,117,115],"sn":[102,128,128],"sb":[158,99,181],"te":[212,122,0],"i":[148,0,148],"xe":[66,158,176],"cs":[87,23,143],"ba":[0,201,0],"la":[112,212,255],"ce":[255,255,199],"pr":[217,255,199],"nd":[199,255,199],"pm":[163,255,199],"sm":[143,255,199],"eu":[97,255,199],"gd":[69,255,199],"tb":[48,255,199],"dy":[31,255,199],"ho":[0,255,156],"er":[0,230,117],"tm":[0,212,82],"yb":[0,191,56],"lu":[0,171,36],"hf":[77,194,255],"ta":[77,166,255],"w":[33,148,214],"re":[38,125,171],"os":[38,102,150],"ir":[23,84,135],"pt":[208,208,224],"au":[255,209,35],"hg":[184,184,208],"tl":[166,84,77],"pb":[87,89,97],"bi":[158,79,181],"po":[171,92,0],"at":[117,79,69],"rn":[66,130,150],"fr":[66,0,102],"ra":[0,125,0],"ac":[112,171,250],"th":[0,186,255],"pa":[0,161,255],"u":[0,143,255],"np":[0,128,255],"pu":[0,107,255],"am":[84,92,242],"cm":[120,92,227],"bk":[138,79,227],"cf":[161,54,212],"es":[179,31,212],"fm":[179,31,186],"md":[179,13,166],"no":[189,13,135],"lr":[199,0,102],"rf":[204,0,89],"db":[209,0,79],"sg":[217,0,69],"bh":[224,0,56],"hs":[230,0,46],"mt":[235,0,38], - "ds":[235,0,38],"rg":[235,0,38],"cn":[235,0,38],"uut":[235,0,38],"uuq":[235,0,38],"uup":[235,0,38],"uuh":[235,0,38],"uus":[235,0,38],"uuo":[235,0,38]}; + var CPK = { "h":[ 255,255,255 ],"he":[ 217,255,255 ],"li":[ 204,128,255 ],"be":[ 194,255,0 ],"b":[ 255,181,181 ],"c":[ 144,144,144 ],"n":[ 48,80,248 ],"o":[ 255,13,13 ],"f":[ 144,224,80 ],"ne":[ 179,227,245 ],"na":[ 171,92,242 ],"mg":[ 138,255,0 ],"al":[ 191,166,166 ],"si":[ 240,200,160 ],"p":[ 255,128,0 ],"s":[ 255,255,48 ],"cl":[ 31,240,31 ],"ar":[ 128,209,227 ],"k":[ 143,64,212 ],"ca":[ 61,255,0 ],"sc":[ 230,230,230 ],"ti":[ 191,194,199 ],"v":[ 166,166,171 ],"cr":[ 138,153,199 ],"mn":[ 156,122,199 ],"fe":[ 224,102,51 ],"co":[ 240,144,160 ],"ni":[ 80,208,80 ],"cu":[ 200,128,51 ],"zn":[ 125,128,176 ],"ga":[ 194,143,143 ],"ge":[ 102,143,143 ],"as":[ 189,128,227 ],"se":[ 255,161,0 ],"br":[ 166,41,41 ],"kr":[ 92,184,209 ],"rb":[ 112,46,176 ],"sr":[ 0,255,0 ],"y":[ 148,255,255 ],"zr":[ 148,224,224 ],"nb":[ 115,194,201 ],"mo":[ 84,181,181 ],"tc":[ 59,158,158 ],"ru":[ 36,143,143 ],"rh":[ 10,125,140 ],"pd":[ 0,105,133 ],"ag":[ 192,192,192 ],"cd":[ 255,217,143 ],"in":[ 166,117,115 ],"sn":[ 102,128,128 ],"sb":[ 158,99,181 ],"te":[ 212,122,0 ],"i":[ 148,0,148 ],"xe":[ 66,158,176 ],"cs":[ 87,23,143 ],"ba":[ 0,201,0 ],"la":[ 112,212,255 ],"ce":[ 255,255,199 ],"pr":[ 217,255,199 ],"nd":[ 199,255,199 ],"pm":[ 163,255,199 ],"sm":[ 143,255,199 ],"eu":[ 97,255,199 ],"gd":[ 69,255,199 ],"tb":[ 48,255,199 ],"dy":[ 31,255,199 ],"ho":[ 0,255,156 ],"er":[ 0,230,117 ],"tm":[ 0,212,82 ],"yb":[ 0,191,56 ],"lu":[ 0,171,36 ],"hf":[ 77,194,255 ],"ta":[ 77,166,255 ],"w":[ 33,148,214 ],"re":[ 38,125,171 ],"os":[ 38,102,150 ],"ir":[ 23,84,135 ],"pt":[ 208,208,224 ],"au":[ 255,209,35 ],"hg":[ 184,184,208 ],"tl":[ 166,84,77 ],"pb":[ 87,89,97 ],"bi":[ 158,79,181 ],"po":[ 171,92,0 ],"at":[ 117,79,69 ],"rn":[ 66,130,150 ],"fr":[ 66,0,102 ],"ra":[ 0,125,0 ],"ac":[ 112,171,250 ],"th":[ 0,186,255 ],"pa":[ 0,161,255 ],"u":[ 0,143,255 ],"np":[ 0,128,255 ],"pu":[ 0,107,255 ],"am":[ 84,92,242 ],"cm":[ 120,92,227 ],"bk":[ 138,79,227 ],"cf":[ 161,54,212 ],"es":[ 179,31,212 ],"fm":[ 179,31,186 ],"md":[ 179,13,166 ],"no":[ 189,13,135 ],"lr":[ 199,0,102 ],"rf":[ 204,0,89 ],"db":[ 209,0,79 ],"sg":[ 217,0,69 ],"bh":[ 224,0,56 ],"hs":[ 230,0,46 ],"mt":[ 235,0,38 ], + "ds":[ 235,0,38 ],"rg":[ 235,0,38 ],"cn":[ 235,0,38 ],"uut":[ 235,0,38 ],"uuq":[ 235,0,38 ],"uup":[ 235,0,38 ],"uuh":[ 235,0,38 ],"uus":[ 235,0,38 ],"uuo":[ 235,0,38 ] }; var atoms = []; @@ -89,30 +89,30 @@ THREE.PDBLoader.prototype = { var x, y, z, e; - for( var i = 0, il = lines.length; i < il; ++ i ) { + for ( var i = 0, il = lines.length; i < il; ++ i ) { - if( lines[i].substr(0,4)=="ATOM" || lines[i].substr(0,6)=="HETATM" ) { + if ( lines[i].substr(0, 4) == "ATOM" || lines[i].substr(0, 6) == "HETATM" ) { - x = parseFloat( lines[i].substr(30,7) ); - y = parseFloat( lines[i].substr(38,7) ); - z = parseFloat( lines[i].substr(46,7) ); + x = parseFloat( lines[i].substr(30, 7) ); + y = parseFloat( lines[i].substr(38, 7) ); + z = parseFloat( lines[i].substr(46, 7) ); - e = trim( lines[i].substr(76,2) ).toLowerCase(); + e = trim( lines[i].substr(76, 2) ).toLowerCase(); - if ( e=="" ) e = trim(lines[i].substr(12,2)).toLowerCase(); + if ( e == "" ) e = trim(lines[i].substr(12, 2)).toLowerCase(); atoms.push( [ x,y,z, CPK[e], capitalize(e) ] ); - if (histogram[e]==undefined) histogram[e] = 1; + if (histogram[e] == undefined) histogram[e] = 1; else histogram[e] += 1; - } else if(lines[i].substr(0,6)=="CONECT") { + } else if (lines[i].substr(0, 6) == "CONECT") { - var satom = parseInt( lines[i].substr(6,5) ); + var satom = parseInt( lines[i].substr(6, 5) ); - parseBond(11,5); - parseBond(16,5); - parseBond(21,5); - parseBond(26,5); + parseBond(11, 5); + parseBond(16, 5); + parseBond(21, 5); + parseBond(26, 5); } diff --git a/examples/js/loaders/PLYLoader.js b/examples/js/loaders/PLYLoader.js index 1f851489cccb83..da547209b1151f 100644 --- a/examples/js/loaders/PLYLoader.js +++ b/examples/js/loaders/PLYLoader.js @@ -80,7 +80,7 @@ THREE.PLYLoader.prototype = { var array_buffer = new Uint8Array(buf); var str = ''; - for(var i = 0; i < buf.byteLength; i++) { + for (var i = 0; i < buf.byteLength; i ++) { str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian } @@ -88,7 +88,7 @@ THREE.PLYLoader.prototype = { }, - isASCII: function( data ){ + isASCII: function( data ) { var header = this.parseHeader( this.bin2str( data ) ); @@ -167,7 +167,7 @@ THREE.PLYLoader.prototype = { lineType = lineValues.shift() line = lineValues.join(" ") - switch( lineType ) { + switch ( lineType ) { case "format": @@ -224,7 +224,7 @@ THREE.PLYLoader.prototype = { parseASCIINumber: function ( n, type ) { - switch( type ) { + switch ( type ) { case 'char': case 'uchar': case 'short': case 'ushort': case 'int': case 'uint': case 'int8': case 'uint8': case 'int16': case 'uint16': case 'int32': case 'uint32': @@ -301,7 +301,7 @@ THREE.PLYLoader.prototype = { if ( currentElementCount >= header.elements[currentElement].count ) { - currentElement++; + currentElement ++; currentElementCount = 0; } @@ -310,7 +310,7 @@ THREE.PLYLoader.prototype = { this.handleElement( geometry, header.elements[currentElement].name, element ); - currentElementCount++; + currentElementCount ++; } @@ -385,7 +385,7 @@ THREE.PLYLoader.prototype = { binaryRead: function ( dataview, at, type, little_endian ) { - switch( type ) { + switch ( type ) { // corespondences for non-specific length types here match rply: case 'int8': case 'char': return [ dataview.getInt8( at ), 1 ]; @@ -419,13 +419,13 @@ THREE.PLYLoader.prototype = { var list = []; - result = this.binaryRead( dataview, at+read, properties[i].countType, little_endian ); + result = this.binaryRead( dataview, at + read, properties[i].countType, little_endian ); var n = result[0]; read += result[1]; for ( j = 0; j < n; j ++ ) { - result = this.binaryRead( dataview, at+read, properties[i].itemType, little_endian ); + result = this.binaryRead( dataview, at + read, properties[i].itemType, little_endian ); list.push( result[0] ); read += result[1]; @@ -435,7 +435,7 @@ THREE.PLYLoader.prototype = { } else { - result = this.binaryRead( dataview, at+read, properties[i].type, little_endian ); + result = this.binaryRead( dataview, at + read, properties[i].type, little_endian ); element[ properties[i].name ] = result[0]; read += result[1]; diff --git a/examples/js/loaders/PVRLoader.js b/examples/js/loaders/PVRLoader.js index 12ff611aeaaeee..b840351fa6d579 100644 --- a/examples/js/loaders/PVRLoader.js +++ b/examples/js/loaders/PVRLoader.js @@ -28,11 +28,11 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) { }; // PVR v3 - if( header[0] === 0x03525650 ) { + if ( header[0] === 0x03525650 ) { return THREE.PVRLoader._parseV3( pvrDatas ); } // PVR v2 - else if( header[11] === 0x21525650) { + else if ( header[11] === 0x21525650) { return THREE.PVRLoader._parseV2( pvrDatas ); } else { @@ -55,7 +55,7 @@ THREE.PVRLoader._parseV3 = function ( pvrDatas ) { numFaces = header[10], numMipmaps = header[11]; - switch( pixelFormat ) { + switch ( pixelFormat ) { case 0 : // PVRTC 2bpp RGB bpp = 2; format = THREE.RGB_PVRTC_2BPPV1_Format; @@ -73,7 +73,7 @@ THREE.PVRLoader._parseV3 = function ( pvrDatas ) { format = THREE.RGBA_PVRTC_4BPPV1_Format; break; default : - throw new Error( "pvrtc - unsupported PVR format "+pixelFormat); + throw new Error( "pvrtc - unsupported PVR format " + pixelFormat); } pvrDatas.dataPtr = 52 + metaLen; @@ -123,12 +123,12 @@ THREE.PVRLoader._parseV2 = function ( pvrDatas ) { format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format; bpp = 4; } - else if( formatFlags === PVRTC_2) { + else if ( formatFlags === PVRTC_2) { format = _hasAlpha ? THREE.RGBA_PVRTC_2BPPV1_Format : THREE.RGB_PVRTC_2BPPV1_Format; bpp = 2; } else - throw new Error( "pvrtc - unknown format "+formatFlags); + throw new Error( "pvrtc - unknown format " + formatFlags); @@ -195,7 +195,7 @@ THREE.PVRLoader._extract = function ( pvrDatas ) { - if( bpp === 2 ){ + if ( bpp === 2 ) { blockWidth = 8; blockHeight = 4; } else { @@ -243,7 +243,7 @@ THREE.PVRLoader._extract = function ( pvrDatas ) { } - mipLevel++; + mipLevel ++; } diff --git a/examples/js/loaders/RGBELoader.js b/examples/js/loaders/RGBELoader.js index 3c490219a2748d..d638c89b6bf957 100644 --- a/examples/js/loaders/RGBELoader.js +++ b/examples/js/loaders/RGBELoader.js @@ -60,13 +60,13 @@ THREE.RGBELoader.prototype._parser = function( buffer ) { lineLimit = !lineLimit ? 1024 : lineLimit; var p = buffer.pos, i = -1, len = 0, s = '', chunkSize = 128, - chunk = String.fromCharCode.apply(null, new Uint16Array( buffer.subarray( p, p+chunkSize ) ) ) + chunk = String.fromCharCode.apply(null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) ) ; - while ( (0 > (i=chunk.indexOf( NEWLINE ))) && (len < lineLimit) && (p < buffer.byteLength) ) { + while ( (0 > (i = chunk.indexOf( NEWLINE ))) && (len < lineLimit) && (p < buffer.byteLength) ) { s += chunk; len += chunk.length; p += chunkSize; - chunk += String.fromCharCode.apply(null, new Uint16Array( buffer.subarray( p, p+chunkSize ) ) ); + chunk += String.fromCharCode.apply(null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) ); } @@ -78,7 +78,7 @@ THREE.RGBELoader.prototype._parser = function( buffer ) { else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2; if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate }*/ - if ( false !== consume ) buffer.pos += len+i+1; + if ( false !== consume ) buffer.pos += len + i + 1; return s + chunk.slice(0, i); } @@ -122,11 +122,11 @@ THREE.RGBELoader.prototype._parser = function( buffer ) { } ; - if ( buffer.pos >= buffer.byteLength || !( line=fgets( buffer ) ) ) { + if ( buffer.pos >= buffer.byteLength || !( line = fgets( buffer ) ) ) { return rgbe_error( rgbe_read_error, "no header found" ); } /* if you want to require the magic token then uncomment the next line */ - if ( !(match=line.match(magic_token_re)) ) { + if ( !(match = line.match(magic_token_re)) ) { return rgbe_error( rgbe_format_error, "bad initial token" ); } header.valid |= RGBE_VALID_PROGRAMTYPE; @@ -144,17 +144,17 @@ THREE.RGBELoader.prototype._parser = function( buffer ) { continue; // comment line } - if ( match=line.match(gamma_re) ) { + if ( match = line.match(gamma_re) ) { header.gamma = parseFloat(match[1], 10); } - if ( match=line.match(exposure_re) ) { + if ( match = line.match(exposure_re) ) { header.exposure = parseFloat(match[1], 10); } - if ( match=line.match(format_re) ) { + if ( match = line.match(format_re) ) { header.valid |= RGBE_VALID_FORMAT; header.format = match[1];//'32-bit_rle_rgbe'; } - if ( match=line.match(dimensions_re) ) { + if ( match = line.match(dimensions_re) ) { header.valid |= RGBE_VALID_DIMENSIONS; header.height = parseInt(match[1], 10); header.width = parseInt(match[2], 10); @@ -193,29 +193,29 @@ THREE.RGBELoader.prototype._parser = function( buffer ) { return rgbe_error(rgbe_format_error, "wrong scanline width"); } - data_rgba = new Uint8Array( 4*w*h ); + data_rgba = new Uint8Array( 4 * w * h ); if ( !data_rgba || !data_rgba.length ) { return rgbe_error(rgbe_memory_error, "unable to allocate buffer space"); } - offset = 0; pos = 0; ptr_end = 4*scanline_width; + offset = 0; pos = 0; ptr_end = 4 * scanline_width; rgbeStart = new Uint8Array( 4 ); scanline_buffer = new Uint8Array( ptr_end ); // read in each successive scanline - while( (num_scanlines > 0) && (pos < buffer.byteLength) ) { + while ( (num_scanlines > 0) && (pos < buffer.byteLength) ) { - if ( pos+4 > buffer.byteLength ) { + if ( pos + 4 > buffer.byteLength ) { return rgbe_error( rgbe_read_error ); } - rgbeStart[0] = buffer[pos++]; - rgbeStart[1] = buffer[pos++]; - rgbeStart[2] = buffer[pos++]; - rgbeStart[3] = buffer[pos++]; + rgbeStart[0] = buffer[pos ++]; + rgbeStart[1] = buffer[pos ++]; + rgbeStart[2] = buffer[pos ++]; + rgbeStart[3] = buffer[pos ++]; if ( (2 != rgbeStart[0]) || (2 != rgbeStart[1]) || (((rgbeStart[2]<<8) | rgbeStart[3]) != scanline_width) ) { @@ -228,11 +228,11 @@ THREE.RGBELoader.prototype._parser = function( buffer ) { ptr = 0; while ( (ptr < ptr_end) && (pos < buffer.byteLength) ) { - count = buffer[ pos++ ]; + count = buffer[ pos ++ ]; isEncodedRun = count > 128; if ( isEncodedRun ) count -= 128; - if ( (0 === count) || (ptr+count > ptr_end) ) { + if ( (0 === count) || (ptr + count > ptr_end) ) { return rgbe_error(rgbe_format_error, "bad scanline data"); @@ -240,15 +240,15 @@ THREE.RGBELoader.prototype._parser = function( buffer ) { if ( isEncodedRun ) { // a (encoded) run of the same value - byteValue = buffer[ pos++ ]; - for (i=0; i> TGA_ORIGIN_SHIFT ) { + switch ( (header.flags & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT ) { default: case TGA_ORIGIN_UL: x_start = 0; @@ -374,7 +374,7 @@ THREE.TGALoader.prototype._parser = function ( buffer ) { if ( use_grey ) { - switch( header.pixel_size ) { + switch ( header.pixel_size ) { case 8: tgaGetImageDataGrey8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image ); break; @@ -388,7 +388,7 @@ THREE.TGALoader.prototype._parser = function ( buffer ) { } else { - switch( header.pixel_size ) { + switch ( header.pixel_size ) { case 8: tgaGetImageData8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image, palette ); break; diff --git a/examples/js/loaders/UTF8Loader.js b/examples/js/loaders/UTF8Loader.js index 0323039d62c260..483c1e6a460965 100644 --- a/examples/js/loaders/UTF8Loader.js +++ b/examples/js/loaders/UTF8Loader.js @@ -50,15 +50,15 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray j = 0; offset = 0; - for( i = offset; i < end; i += stride ) { + for ( i = offset; i < end; i += stride ) { x = attribArray[ i ]; y = attribArray[ i + 1 ]; z = attribArray[ i + 2 ]; - positions[ j++ ] = x; - positions[ j++ ] = y; - positions[ j++ ] = z; + positions[ j ++ ] = x; + positions[ j ++ ] = y; + positions[ j ++ ] = z; } @@ -67,13 +67,13 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray j = 0; offset = 3; - for( i = offset; i < end; i += stride ) { + for ( i = offset; i < end; i += stride ) { u = attribArray[ i ]; v = attribArray[ i + 1 ]; - uvs[ j++ ] = u; - uvs[ j++ ] = v; + uvs[ j ++ ] = u; + uvs[ j ++ ] = v; } @@ -82,15 +82,15 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray j = 0; offset = 5; - for( i = offset; i < end; i += stride ) { + for ( i = offset; i < end; i += stride ) { x = attribArray[ i ]; y = attribArray[ i + 1 ]; z = attribArray[ i + 2 ]; - normals[ j++ ] = x; - normals[ j++ ] = y; - normals[ j++ ] = z; + normals[ j ++ ] = x; + normals[ j ++ ] = y; + normals[ j ++ ] = z; } @@ -133,8 +133,8 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray var DEFAULT_DECODE_PARAMS = { - decodeOffsets: [-4095, -4095, -4095, 0, 0, -511, -511, -511], - decodeScales: [1/8191, 1/8191, 1/8191, 1/1023, 1/1023, 1/1023, 1/1023, 1/1023] + decodeOffsets: [ -4095, -4095, -4095, 0, 0, -511, -511, -511 ], + decodeScales: [ 1 / 8191, 1 / 8191, 1 / 8191, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023 ] // TODO: normal decoding? (see walt.js) // needs to know: input, output (from vertex format!) @@ -212,13 +212,13 @@ THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBo var radiusY = (str.charCodeAt(i + 4) + 1) >> 1; var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1; - bboxen[ outputStart++ ] = decodeScales[0] * (minX + radiusX); - bboxen[ outputStart++ ] = decodeScales[1] * (minY + radiusY); - bboxen[ outputStart++ ] = decodeScales[2] * (minZ + radiusZ); + bboxen[ outputStart ++ ] = decodeScales[0] * (minX + radiusX); + bboxen[ outputStart ++ ] = decodeScales[1] * (minY + radiusY); + bboxen[ outputStart ++ ] = decodeScales[2] * (minZ + radiusZ); - bboxen[ outputStart++ ] = decodeScales[0] * radiusX; - bboxen[ outputStart++ ] = decodeScales[1] * radiusY; - bboxen[ outputStart++ ] = decodeScales[2] * radiusZ; + bboxen[ outputStart ++ ] = decodeScales[0] * radiusX; + bboxen[ outputStart ++ ] = decodeScales[1] * radiusY; + bboxen[ outputStart ++ ] = decodeScales[2] * radiusZ; } @@ -300,7 +300,7 @@ THREE.UTF8Loader.prototype.decodeAttrib2 = function ( str, stride, decodeOffsets for ( var j = 0; j < 5; j ++ ) { - var code = str.charCodeAt( deltaStart + numVerts*j + index ); + var code = str.charCodeAt( deltaStart + numVerts * j + index ); var delta = ( code >> 1) ^ (-(code & 1)); lastAttrib[ j ] += delta; @@ -312,17 +312,17 @@ THREE.UTF8Loader.prototype.decodeAttrib2 = function ( str, stride, decodeOffsets THREE.UTF8Loader.prototype.accumulateNormal = function ( i0, i1, i2, attribsOutFixed, crosses ) { - var p0x = attribsOutFixed[ 8*i0 ]; - var p0y = attribsOutFixed[ 8*i0 + 1 ]; - var p0z = attribsOutFixed[ 8*i0 + 2 ]; + var p0x = attribsOutFixed[ 8 * i0 ]; + var p0y = attribsOutFixed[ 8 * i0 + 1 ]; + var p0z = attribsOutFixed[ 8 * i0 + 2 ]; - var p1x = attribsOutFixed[ 8*i1 ]; - var p1y = attribsOutFixed[ 8*i1 + 1 ]; - var p1z = attribsOutFixed[ 8*i1 + 2 ]; + var p1x = attribsOutFixed[ 8 * i1 ]; + var p1y = attribsOutFixed[ 8 * i1 + 1 ]; + var p1z = attribsOutFixed[ 8 * i1 + 2 ]; - var p2x = attribsOutFixed[ 8*i2 ]; - var p2y = attribsOutFixed[ 8*i2 + 1 ]; - var p2z = attribsOutFixed[ 8*i2 + 2 ]; + var p2x = attribsOutFixed[ 8 * i2 ]; + var p2y = attribsOutFixed[ 8 * i2 + 1 ]; + var p2z = attribsOutFixed[ 8 * i2 + 2 ]; p1x -= p0x; p1y -= p0y; @@ -332,21 +332,21 @@ THREE.UTF8Loader.prototype.accumulateNormal = function ( i0, i1, i2, attribsOutF p2y -= p0y; p2z -= p0z; - p0x = p1y*p2z - p1z*p2y; - p0y = p1z*p2x - p1x*p2z; - p0z = p1x*p2y - p1y*p2x; + p0x = p1y * p2z - p1z * p2y; + p0y = p1z * p2x - p1x * p2z; + p0z = p1x * p2y - p1y * p2x; - crosses[ 3*i0 ] += p0x; - crosses[ 3*i0 + 1 ] += p0y; - crosses[ 3*i0 + 2 ] += p0z; + crosses[ 3 * i0 ] += p0x; + crosses[ 3 * i0 + 1 ] += p0y; + crosses[ 3 * i0 + 2 ] += p0z; - crosses[ 3*i1 ] += p0x; - crosses[ 3*i1 + 1 ] += p0y; - crosses[ 3*i1 + 2 ] += p0z; + crosses[ 3 * i1 ] += p0x; + crosses[ 3 * i1 + 1 ] += p0y; + crosses[ 3 * i1 + 2 ] += p0z; - crosses[ 3*i2 ] += p0x; - crosses[ 3*i2 + 1 ] += p0y; - crosses[ 3*i2 + 2 ] += p0z; + crosses[ 3 * i2 ] += p0x; + crosses[ 3 * i2 + 1 ] += p0y; + crosses[ 3 * i2 + 2 ] += p0z; }; @@ -435,9 +435,9 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest ); var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) + - attribsOutFixed[stride*i0 + j] + - attribsOutFixed[stride*i1 + j] - - attribsOutFixed[stride*i2 + j]; + attribsOutFixed[stride * i0 + j] + + attribsOutFixed[stride * i1 + j] - + attribsOutFixed[stride * i2 + j]; lastAttrib[j] = prediction; @@ -524,19 +524,19 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa for ( var i = 0; i < numVerts; i ++ ) { - var nx = crosses[ 3*i ]; - var ny = crosses[ 3*i + 1 ]; - var nz = crosses[ 3*i + 2 ]; + var nx = crosses[ 3 * i ]; + var ny = crosses[ 3 * i + 1 ]; + var nz = crosses[ 3 * i + 2 ]; - var norm = 511.0 / Math.sqrt( nx*nx + ny*ny + nz*nz ); + var norm = 511.0 / Math.sqrt( nx * nx + ny * ny + nz * nz ); - var cx = str.charCodeAt( deltaStart + 5*numVerts + i ); - var cy = str.charCodeAt( deltaStart + 6*numVerts + i ); - var cz = str.charCodeAt( deltaStart + 7*numVerts + i ); + var cx = str.charCodeAt( deltaStart + 5 * numVerts + i ); + var cy = str.charCodeAt( deltaStart + 6 * numVerts + i ); + var cz = str.charCodeAt( deltaStart + 7 * numVerts + i ); - attribsOut[ stride*i + 5 ] = norm*nx + ((cx >> 1) ^ (-(cx & 1))); - attribsOut[ stride*i + 6 ] = norm*ny + ((cy >> 1) ^ (-(cy & 1))); - attribsOut[ stride*i + 7 ] = norm*nz + ((cz >> 1) ^ (-(cz & 1))); + attribsOut[ stride * i + 5 ] = norm * nx + ((cx >> 1) ^ (-(cx & 1))); + attribsOut[ stride * i + 6 ] = norm * ny + ((cy >> 1) ^ (-(cy & 1))); + attribsOut[ stride * i + 7 ] = norm * nz + ((cz >> 1) ^ (-(cz & 1))); } callback( name, idx, attribsOut, indicesOut, undefined, meshParams ); @@ -573,7 +573,7 @@ THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, deco loader.decompressMesh2( req.responseText, meshParams, decodeParams, name, idx, callback ); } - ++idx; + ++ idx; } diff --git a/examples/js/loaders/VRMLLoader.js b/examples/js/loaders/VRMLLoader.js index 45adf00e1f0845..bf67886d4c56da 100644 --- a/examples/js/loaders/VRMLLoader.js +++ b/examples/js/loaders/VRMLLoader.js @@ -123,7 +123,7 @@ THREE.VRMLLoader.prototype = { var coord = [ ], aColor, bColor, t = 1, A = {}, B = {}, applyColor = false, colorIndex; - for ( var k = 0; k < angles.length; k++ ) { + for ( var k = 0; k < angles.length; k ++ ) { var vec = { }; @@ -137,19 +137,19 @@ THREE.VRMLLoader.prototype = { } // painting the colors on the faces - for ( var i = 0; i < geometry.faces.length ; i++ ) { + for ( var i = 0; i < geometry.faces.length ; i ++ ) { f = geometry.faces[ i ]; n = ( f instanceof THREE.Face3 ) ? 3 : 4; - for ( var j = 0; j < n; j++ ) { + for ( var j = 0; j < n; j ++ ) { vertexIndex = f[ faceIndices[ j ] ]; p = geometry.vertices[ vertexIndex ]; - for ( var index = 0; index < colors.length; index++ ) { + for ( var index = 0; index < colors.length; index ++ ) { // linear interpolation between aColor and bColor, calculate proportion // A is previous point (angle) @@ -160,8 +160,8 @@ THREE.VRMLLoader.prototype = { } else { - A.x = coord[ index-1 ].x; - A.y = coord[ index-1 ].y; + A.x = coord[ index - 1 ].x; + A.y = coord[ index - 1 ].y; } @@ -188,7 +188,7 @@ THREE.VRMLLoader.prototype = { } } else if ( undefined === f.vertexColors[ j ] ) { - colorIndex = directionIsDown ? colors.length -1 : 0; + colorIndex = directionIsDown ? colors.length - 1 : 0; f.vertexColors[ j ] = colors[ colorIndex ]; } @@ -250,7 +250,7 @@ THREE.VRMLLoader.prototype = { if (parts.length > 0) { index = []; - for (var ind = 0;ind < parts.length; ind++) { + for (var ind = 0; ind < parts.length; ind ++) { // the part should either be positive integer or -1 if (!/(-?\d+)/.test( parts[ind]) ) { @@ -301,7 +301,7 @@ THREE.VRMLLoader.prototype = { // the parts hold the angles as strings if ( parts.length > 0 ) { - for ( var ind = 0;ind < parts.length; ind++ ) { + for ( var ind = 0; ind < parts.length; ind ++ ) { // the part should be a float if ( ! float_pattern.test( parts[ind] ) ) { @@ -321,7 +321,7 @@ THREE.VRMLLoader.prototype = { } else if (this.isRecordingColors) { - while( null !== ( parts = float3_pattern.exec(line) ) ) { + while ( null !== ( parts = float3_pattern.exec(line) ) ) { color = { r: parseFloat(parts[1]), @@ -339,7 +339,7 @@ THREE.VRMLLoader.prototype = { node[this.recordingFieldname] = this.colors; } - } else if ( parts[parts.length -1] !== 'NULL' && fieldName !== 'children') { + } else if ( parts[parts.length - 1] !== 'NULL' && fieldName !== 'children') { switch (fieldName) { @@ -466,7 +466,7 @@ THREE.VRMLLoader.prototype = { if ( matches = /([^\s]*){1}\s?{/.exec( line ) ) { // first subpattern should match the Node name - var block = { 'nodeType' : matches[1], 'string': line, 'parent': current, 'children': [],'comment' : comment}; + var block = { 'nodeType' : matches[1], 'string': line, 'parent': current, 'children': [],'comment' : comment }; current.children.push( block ); current = block; @@ -528,7 +528,7 @@ THREE.VRMLLoader.prototype = { parent.material.side = THREE.DoubleSide; } - } else if (defineKey){ + } else if (defineKey) { var object = defines[ defineKey ].clone(); parent.add( object ); @@ -660,7 +660,7 @@ THREE.VRMLLoader.prototype = { var indexes; - for ( var i = 0, j = data.children.length; i < j; i++ ) { + for ( var i = 0, j = data.children.length; i < j; i ++ ) { var child = data.children[ i ]; @@ -668,7 +668,7 @@ THREE.VRMLLoader.prototype = { if ( 'Coordinate' === child.nodeType ) { - for ( var k = 0, l = child.points.length; k < l; k++ ) { + for ( var k = 0, l = child.points.length; k < l; k ++ ) { var point = child.points[ k ]; @@ -684,7 +684,7 @@ THREE.VRMLLoader.prototype = { var skip = 0; // read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html - for ( var i = 0, j = data.coordIndex.length; i < j; i++ ) { + for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) { indexes = data.coordIndex[i]; @@ -694,7 +694,7 @@ THREE.VRMLLoader.prototype = { // todo: this is the time to check if the faces are ordered ccw or not (cw) // Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles - while ( indexes.length >= 3 && skip < ( indexes.length -2 ) ) { + while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) { var face = new THREE.Face3( indexes[0], @@ -704,7 +704,7 @@ THREE.VRMLLoader.prototype = { // todo: pass in the color, if a color index is present ); - skip++; + skip ++; geometry.faces.push( face ); diff --git a/examples/js/loaders/ctm/CTMLoader.js b/examples/js/loaders/ctm/CTMLoader.js index 43d9ce191bfdab..be3ae792645733 100755 --- a/examples/js/loaders/ctm/CTMLoader.js +++ b/examples/js/loaders/ctm/CTMLoader.js @@ -126,7 +126,7 @@ THREE.CTMLoader.prototype.load = function( url, callback, parameters ) { scope.createModel( ctmFile, callback ); var e = Date.now(); - console.log( "model load time [worker]: " + (e-e1) + " ms, total: " + (e-s)); + console.log( "model load time [worker]: " + (e - e1) + " ms, total: " + (e - s)); } diff --git a/examples/js/loaders/ctm/ctm.js b/examples/js/loaders/ctm/ctm.js index f6badb7484e5f2..df5c1f6f7d7a6d 100755 --- a/examples/js/loaders/ctm/ctm.js +++ b/examples/js/loaders/ctm/ctm.js @@ -45,11 +45,11 @@ CTM.Flags = { NORMALS: 0x00000001 }; -CTM.File = function(stream){ +CTM.File = function(stream) { this.load(stream); }; -CTM.File.prototype.load = function(stream){ +CTM.File.prototype.load = function(stream) { this.header = new CTM.FileHeader(stream); this.body = new CTM.FileBody(this.header); @@ -57,10 +57,10 @@ CTM.File.prototype.load = function(stream){ this.getReader().read(stream, this.body); }; -CTM.File.prototype.getReader = function(){ +CTM.File.prototype.getReader = function() { var reader; - switch(this.header.compressionMethod){ + switch (this.header.compressionMethod){ case CTM.CompressionMethod.RAW: reader = new CTM.ReaderRAW(); break; @@ -75,7 +75,7 @@ CTM.File.prototype.getReader = function(){ return reader; }; -CTM.FileHeader = function(stream){ +CTM.FileHeader = function(stream) { stream.readInt32(); //magic "OCTM" this.fileFormat = stream.readInt32(); this.compressionMethod = stream.readInt32(); @@ -87,14 +87,14 @@ CTM.FileHeader = function(stream){ this.comment = stream.readString(); }; -CTM.FileHeader.prototype.hasNormals = function(){ +CTM.FileHeader.prototype.hasNormals = function() { return this.flags & CTM.Flags.NORMALS; }; -CTM.FileBody = function(header){ +CTM.FileBody = function(header) { var i = header.triangleCount * 3, v = header.vertexCount * 3, - n = header.hasNormals()? header.vertexCount * 3: 0, + n = header.hasNormals() ? header.vertexCount * 3 : 0, u = header.vertexCount * 2, a = header.vertexCount * 4, j = 0; @@ -106,28 +106,28 @@ CTM.FileBody = function(header){ this.vertices = new Float32Array(data, i * 4, v); - if ( header.hasNormals() ){ + if ( header.hasNormals() ) { this.normals = new Float32Array(data, (i + v) * 4, n); } - if (header.uvMapCount){ + if (header.uvMapCount) { this.uvMaps = []; - for (j = 0; j < header.uvMapCount; ++ j){ - this.uvMaps[j] = {uv: new Float32Array(data, + for (j = 0; j < header.uvMapCount; ++ j) { + this.uvMaps[j] = { uv: new Float32Array(data, (i + v + n + (j * u) ) * 4, u) }; } } - if (header.attrMapCount){ + if (header.attrMapCount) { this.attrMaps = []; - for (j = 0; j < header.attrMapCount; ++ j){ - this.attrMaps[j] = {attr: new Float32Array(data, + for (j = 0; j < header.attrMapCount; ++ j) { + this.attrMaps[j] = { attr: new Float32Array(data, (i + v + n + (u * header.uvMapCount) + (j * a) ) * 4, a) }; } } }; -CTM.FileMG2Header = function(stream){ +CTM.FileMG2Header = function(stream) { stream.readInt32(); //magic "MG2H" this.vertexPrecision = stream.readFloat32(); this.normalPrecision = stream.readFloat32(); @@ -146,42 +146,42 @@ CTM.FileMG2Header = function(stream){ this.sizez = (this.higherBoundz - this.lowerBoundz) / this.divz; }; -CTM.ReaderRAW = function(){ +CTM.ReaderRAW = function() { }; -CTM.ReaderRAW.prototype.read = function(stream, body){ +CTM.ReaderRAW.prototype.read = function(stream, body) { this.readIndices(stream, body.indices); this.readVertices(stream, body.vertices); - if (body.normals){ + if (body.normals) { this.readNormals(stream, body.normals); } - if (body.uvMaps){ + if (body.uvMaps) { this.readUVMaps(stream, body.uvMaps); } - if (body.attrMaps){ + if (body.attrMaps) { this.readAttrMaps(stream, body.attrMaps); } }; -CTM.ReaderRAW.prototype.readIndices = function(stream, indices){ +CTM.ReaderRAW.prototype.readIndices = function(stream, indices) { stream.readInt32(); //magic "INDX" stream.readArrayInt32(indices); }; -CTM.ReaderRAW.prototype.readVertices = function(stream, vertices){ +CTM.ReaderRAW.prototype.readVertices = function(stream, vertices) { stream.readInt32(); //magic "VERT" stream.readArrayFloat32(vertices); }; -CTM.ReaderRAW.prototype.readNormals = function(stream, normals){ +CTM.ReaderRAW.prototype.readNormals = function(stream, normals) { stream.readInt32(); //magic "NORM" stream.readArrayFloat32(normals); }; -CTM.ReaderRAW.prototype.readUVMaps = function(stream, uvMaps){ +CTM.ReaderRAW.prototype.readUVMaps = function(stream, uvMaps) { var i = 0; - for (; i < uvMaps.length; ++ i){ + for (; i < uvMaps.length; ++ i) { stream.readInt32(); //magic "TEXC" uvMaps[i].name = stream.readString(); @@ -190,9 +190,9 @@ CTM.ReaderRAW.prototype.readUVMaps = function(stream, uvMaps){ } }; -CTM.ReaderRAW.prototype.readAttrMaps = function(stream, attrMaps){ +CTM.ReaderRAW.prototype.readAttrMaps = function(stream, attrMaps) { var i = 0; - for (; i < attrMaps.length; ++ i){ + for (; i < attrMaps.length; ++ i) { stream.readInt32(); //magic "ATTR" attrMaps[i].name = stream.readString(); @@ -200,25 +200,25 @@ CTM.ReaderRAW.prototype.readAttrMaps = function(stream, attrMaps){ } }; -CTM.ReaderMG1 = function(){ +CTM.ReaderMG1 = function() { }; -CTM.ReaderMG1.prototype.read = function(stream, body){ +CTM.ReaderMG1.prototype.read = function(stream, body) { this.readIndices(stream, body.indices); this.readVertices(stream, body.vertices); - if (body.normals){ + if (body.normals) { this.readNormals(stream, body.normals); } - if (body.uvMaps){ + if (body.uvMaps) { this.readUVMaps(stream, body.uvMaps); } - if (body.attrMaps){ + if (body.attrMaps) { this.readAttrMaps(stream, body.attrMaps); } }; -CTM.ReaderMG1.prototype.readIndices = function(stream, indices){ +CTM.ReaderMG1.prototype.readIndices = function(stream, indices) { stream.readInt32(); //magic "INDX" stream.readInt32(); //packed size @@ -228,7 +228,7 @@ CTM.ReaderMG1.prototype.readIndices = function(stream, indices){ CTM.restoreIndices(indices, indices.length); }; -CTM.ReaderMG1.prototype.readVertices = function(stream, vertices){ +CTM.ReaderMG1.prototype.readVertices = function(stream, vertices) { stream.readInt32(); //magic "VERT" stream.readInt32(); //packed size @@ -236,7 +236,7 @@ CTM.ReaderMG1.prototype.readVertices = function(stream, vertices){ LZMA.decompress(stream, stream, interleaved, interleaved.data.length); }; -CTM.ReaderMG1.prototype.readNormals = function(stream, normals){ +CTM.ReaderMG1.prototype.readNormals = function(stream, normals) { stream.readInt32(); //magic "NORM" stream.readInt32(); //packed size @@ -244,9 +244,9 @@ CTM.ReaderMG1.prototype.readNormals = function(stream, normals){ LZMA.decompress(stream, stream, interleaved, interleaved.data.length); }; -CTM.ReaderMG1.prototype.readUVMaps = function(stream, uvMaps){ +CTM.ReaderMG1.prototype.readUVMaps = function(stream, uvMaps) { var i = 0; - for (; i < uvMaps.length; ++ i){ + for (; i < uvMaps.length; ++ i) { stream.readInt32(); //magic "TEXC" uvMaps[i].name = stream.readString(); @@ -259,9 +259,9 @@ CTM.ReaderMG1.prototype.readUVMaps = function(stream, uvMaps){ } }; -CTM.ReaderMG1.prototype.readAttrMaps = function(stream, attrMaps){ +CTM.ReaderMG1.prototype.readAttrMaps = function(stream, attrMaps) { var i = 0; - for (; i < attrMaps.length; ++ i){ + for (; i < attrMaps.length; ++ i) { stream.readInt32(); //magic "ATTR" attrMaps[i].name = stream.readString(); @@ -273,27 +273,27 @@ CTM.ReaderMG1.prototype.readAttrMaps = function(stream, attrMaps){ } }; -CTM.ReaderMG2 = function(){ +CTM.ReaderMG2 = function() { }; -CTM.ReaderMG2.prototype.read = function(stream, body){ +CTM.ReaderMG2.prototype.read = function(stream, body) { this.MG2Header = new CTM.FileMG2Header(stream); this.readVertices(stream, body.vertices); this.readIndices(stream, body.indices); - if (body.normals){ + if (body.normals) { this.readNormals(stream, body); } - if (body.uvMaps){ + if (body.uvMaps) { this.readUVMaps(stream, body.uvMaps); } - if (body.attrMaps){ + if (body.attrMaps) { this.readAttrMaps(stream, body.attrMaps); } }; -CTM.ReaderMG2.prototype.readVertices = function(stream, vertices){ +CTM.ReaderMG2.prototype.readVertices = function(stream, vertices) { stream.readInt32(); //magic "VERT" stream.readInt32(); //packed size @@ -305,7 +305,7 @@ CTM.ReaderMG2.prototype.readVertices = function(stream, vertices){ CTM.restoreVertices(vertices, this.MG2Header, gridIndices, this.MG2Header.vertexPrecision); }; -CTM.ReaderMG2.prototype.readGridIndices = function(stream, vertices){ +CTM.ReaderMG2.prototype.readGridIndices = function(stream, vertices) { stream.readInt32(); //magic "GIDX" stream.readInt32(); //packed size @@ -319,7 +319,7 @@ CTM.ReaderMG2.prototype.readGridIndices = function(stream, vertices){ return gridIndices; }; -CTM.ReaderMG2.prototype.readIndices = function(stream, indices){ +CTM.ReaderMG2.prototype.readIndices = function(stream, indices) { stream.readInt32(); //magic "INDX" stream.readInt32(); //packed size @@ -329,7 +329,7 @@ CTM.ReaderMG2.prototype.readIndices = function(stream, indices){ CTM.restoreIndices(indices, indices.length); }; -CTM.ReaderMG2.prototype.readNormals = function(stream, body){ +CTM.ReaderMG2.prototype.readNormals = function(stream, body) { stream.readInt32(); //magic "NORM" stream.readInt32(); //packed size @@ -341,9 +341,9 @@ CTM.ReaderMG2.prototype.readNormals = function(stream, body){ CTM.restoreNormals(body.normals, smooth, this.MG2Header.normalPrecision); }; -CTM.ReaderMG2.prototype.readUVMaps = function(stream, uvMaps){ +CTM.ReaderMG2.prototype.readUVMaps = function(stream, uvMaps) { var i = 0; - for (; i < uvMaps.length; ++ i){ + for (; i < uvMaps.length; ++ i) { stream.readInt32(); //magic "TEXC" uvMaps[i].name = stream.readString(); @@ -360,9 +360,9 @@ CTM.ReaderMG2.prototype.readUVMaps = function(stream, uvMaps){ } }; -CTM.ReaderMG2.prototype.readAttrMaps = function(stream, attrMaps){ +CTM.ReaderMG2.prototype.readAttrMaps = function(stream, attrMaps) { var i = 0; - for (; i < attrMaps.length; ++ i){ + for (; i < attrMaps.length; ++ i) { stream.readInt32(); //magic "ATTR" attrMaps[i].name = stream.readString(); @@ -378,18 +378,18 @@ CTM.ReaderMG2.prototype.readAttrMaps = function(stream, attrMaps){ } }; -CTM.restoreIndices = function(indices, len){ +CTM.restoreIndices = function(indices, len) { var i = 3; - if (len > 0){ + if (len > 0) { indices[2] += indices[0]; indices[1] += indices[0]; } - for (; i < len; i += 3){ + for (; i < len; i += 3) { indices[i] += indices[i - 3]; - if (indices[i] === indices[i - 3]){ + if (indices[i] === indices[i - 3]) { indices[i + 1] += indices[i - 2]; - }else{ + }else { indices[i + 1] += indices[i]; } @@ -397,21 +397,21 @@ CTM.restoreIndices = function(indices, len){ } }; -CTM.restoreGridIndices = function(gridIndices, len){ +CTM.restoreGridIndices = function(gridIndices, len) { var i = 1; - for (; i < len; ++ i){ + for (; i < len; ++ i) { gridIndices[i] += gridIndices[i - 1]; } }; -CTM.restoreVertices = function(vertices, grid, gridIndices, precision){ +CTM.restoreVertices = function(vertices, grid, gridIndices, precision) { var gridIdx, delta, x, y, z, intVertices = new Uint32Array(vertices.buffer, vertices.byteOffset, vertices.length), ydiv = grid.divx, zdiv = ydiv * grid.divy, prevGridIdx = 0x7fffffff, prevDelta = 0, i = 0, j = 0, len = gridIndices.length; - for (; i < len; j += 3){ + for (; i < len; j += 3) { x = gridIdx = gridIndices[i ++]; z = ~~(x / zdiv); @@ -420,7 +420,7 @@ CTM.restoreVertices = function(vertices, grid, gridIndices, precision){ x -= ~~(y * ydiv); delta = intVertices[j]; - if (gridIdx === prevGridIdx){ + if (gridIdx === prevGridIdx) { delta += prevDelta; } @@ -436,26 +436,26 @@ CTM.restoreVertices = function(vertices, grid, gridIndices, precision){ } }; -CTM.restoreNormals = function(normals, smooth, precision){ +CTM.restoreNormals = function(normals, smooth, precision) { var ro, phi, theta, sinPhi, nx, ny, nz, by, bz, len, intNormals = new Uint32Array(normals.buffer, normals.byteOffset, normals.length), i = 0, k = normals.length, PI_DIV_2 = 3.141592653589793238462643 * 0.5; - for (; i < k; i += 3){ + for (; i < k; i += 3) { ro = intNormals[i] * precision; phi = intNormals[i + 1]; - if (phi === 0){ + if (phi === 0) { normals[i] = smooth[i] * ro; normals[i + 1] = smooth[i + 1] * ro; normals[i + 2] = smooth[i + 2] * ro; - }else{ + }else { - if (phi <= 4){ + if (phi <= 4) { theta = (intNormals[i + 2] - 2) * PI_DIV_2; - }else{ + }else { theta = ( (intNormals[i + 2] * 4 / phi) - 2) * PI_DIV_2; } @@ -470,7 +470,7 @@ CTM.restoreNormals = function(normals, smooth, precision){ by = smooth[i] - smooth[i + 2]; len = Math.sqrt(2 * bz * bz + by * by); - if (len > 1e-20){ + if (len > 1e-20) { by /= len; bz /= len; } @@ -485,31 +485,31 @@ CTM.restoreNormals = function(normals, smooth, precision){ } }; -CTM.restoreMap = function(map, count, precision){ +CTM.restoreMap = function(map, count, precision) { var delta, value, intMap = new Uint32Array(map.buffer, map.byteOffset, map.length), i = 0, j, len = map.length; - for (; i < count; ++ i){ + for (; i < count; ++ i) { delta = 0; - for (j = i; j < len; j += count){ + for (j = i; j < len; j += count) { value = intMap[j]; - delta += value & 1? -( (value + 1) >> 1): value >> 1; + delta += value & 1 ? -( (value + 1) >> 1) : value >> 1; map[j] = delta * precision; } } }; -CTM.calcSmoothNormals = function(indices, vertices){ +CTM.calcSmoothNormals = function(indices, vertices) { var smooth = new Float32Array(vertices.length), indx, indy, indz, nx, ny, nz, v1x, v1y, v1z, v2x, v2y, v2z, len, i, k; - for (i = 0, k = indices.length; i < k;){ + for (i = 0, k = indices.length; i < k;) { indx = indices[i ++] * 3; indy = indices[i ++] * 3; indz = indices[i ++] * 3; @@ -526,7 +526,7 @@ CTM.calcSmoothNormals = function(indices, vertices){ nz = v1x * v2y - v1y * v2x; len = Math.sqrt(nx * nx + ny * ny + nz * nz); - if (len > 1e-10){ + if (len > 1e-10) { nx /= len; ny /= len; nz /= len; @@ -543,12 +543,12 @@ CTM.calcSmoothNormals = function(indices, vertices){ smooth[indz + 2] += nz; } - for (i = 0, k = smooth.length; i < k; i += 3){ + for (i = 0, k = smooth.length; i < k; i += 3) { len = Math.sqrt(smooth[i] * smooth[i] + smooth[i + 1] * smooth[i + 1] + smooth[i + 2] * smooth[i + 2]); - if(len > 1e-10){ + if (len > 1e-10) { smooth[i] /= len; smooth[i + 1] /= len; smooth[i + 2] /= len; @@ -558,7 +558,7 @@ CTM.calcSmoothNormals = function(indices, vertices){ return smooth; }; -CTM.isLittleEndian = (function(){ +CTM.isLittleEndian = (function() { var buffer = new ArrayBuffer(2), bytes = new Uint8Array(buffer), ints = new Uint16Array(buffer); @@ -568,28 +568,28 @@ CTM.isLittleEndian = (function(){ return ints[0] === 1; }()); -CTM.InterleavedStream = function(data, count){ +CTM.InterleavedStream = function(data, count) { this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); - this.offset = CTM.isLittleEndian? 3: 0; + this.offset = CTM.isLittleEndian ? 3 : 0; this.count = count * 4; this.len = this.data.length; }; -CTM.InterleavedStream.prototype.writeByte = function(value){ +CTM.InterleavedStream.prototype.writeByte = function(value) { this.data[this.offset] = value; this.offset += this.count; - if (this.offset >= this.len){ + if (this.offset >= this.len) { this.offset -= this.len - 4; - if (this.offset >= this.count){ + if (this.offset >= this.count) { - this.offset -= this.count + (CTM.isLittleEndian? 1: -1); + this.offset -= this.count + (CTM.isLittleEndian ? 1 : -1); } } }; -CTM.Stream = function(data){ +CTM.Stream = function(data) { this.data = data; this.offset = 0; }; @@ -598,18 +598,18 @@ CTM.Stream.prototype.TWO_POW_MINUS23 = Math.pow(2, -23); CTM.Stream.prototype.TWO_POW_MINUS126 = Math.pow(2, -126); -CTM.Stream.prototype.readByte = function(){ +CTM.Stream.prototype.readByte = function() { return this.data[this.offset ++] & 0xff; }; -CTM.Stream.prototype.readInt32 = function(){ +CTM.Stream.prototype.readInt32 = function() { var i = this.readByte(); i |= this.readByte() << 8; i |= this.readByte() << 16; return i | (this.readByte() << 24); }; -CTM.Stream.prototype.readFloat32 = function(){ +CTM.Stream.prototype.readFloat32 = function() { var m = this.readByte(); m += this.readByte() << 8; @@ -618,42 +618,42 @@ CTM.Stream.prototype.readFloat32 = function(){ m += (b1 & 0x7f) << 16; var e = ( (b2 & 0x7f) << 1) | ( (b1 & 0x80) >>> 7); - var s = b2 & 0x80? -1: 1; + var s = b2 & 0x80 ? -1 : 1; - if (e === 255){ - return m !== 0? NaN: s * Infinity; + if (e === 255) { + return m !== 0 ? NaN : s * Infinity; } - if (e > 0){ + if (e > 0) { return s * (1 + (m * this.TWO_POW_MINUS23) ) * Math.pow(2, e - 127); } - if (m !== 0){ + if (m !== 0) { return s * m * this.TWO_POW_MINUS126; } return s * 0; }; -CTM.Stream.prototype.readString = function(){ +CTM.Stream.prototype.readString = function() { var len = this.readInt32(); this.offset += len; - return String.fromCharCode.apply(null,this.data.subarray(this.offset - len, this.offset)); + return String.fromCharCode.apply(null, this.data.subarray(this.offset - len, this.offset)); }; -CTM.Stream.prototype.readArrayInt32 = function(array){ +CTM.Stream.prototype.readArrayInt32 = function(array) { var i = 0, len = array.length; - while(i < len){ + while (i < len) { array[i ++] = this.readInt32(); } return array; }; -CTM.Stream.prototype.readArrayFloat32 = function(array){ +CTM.Stream.prototype.readArrayFloat32 = function(array) { var i = 0, len = array.length; - while(i < len){ + while (i < len) { array[i ++] = this.readFloat32(); } diff --git a/examples/js/loaders/ctm/lzma.js b/examples/js/loaders/ctm/lzma.js index ec29f6dbc4f79c..e2e83dee80ee64 100644 --- a/examples/js/loaders/ctm/lzma.js +++ b/examples/js/loaders/ctm/lzma.js @@ -8,12 +8,12 @@ if ( typeof module === 'object' ) { } -LZMA.OutWindow = function(){ +LZMA.OutWindow = function() { this._windowSize = 0; }; -LZMA.OutWindow.prototype.create = function(windowSize){ - if ( (!this._buffer) || (this._windowSize !== windowSize) ){ +LZMA.OutWindow.prototype.create = function(windowSize) { + if ( (!this._buffer) || (this._windowSize !== windowSize) ) { this._buffer = []; } this._windowSize = windowSize; @@ -21,99 +21,99 @@ LZMA.OutWindow.prototype.create = function(windowSize){ this._streamPos = 0; }; -LZMA.OutWindow.prototype.flush = function(){ +LZMA.OutWindow.prototype.flush = function() { var size = this._pos - this._streamPos; - if (size !== 0){ - while(size --){ + if (size !== 0) { + while (size --) { this._stream.writeByte(this._buffer[this._streamPos ++]); } - if (this._pos >= this._windowSize){ + if (this._pos >= this._windowSize) { this._pos = 0; } this._streamPos = this._pos; } }; -LZMA.OutWindow.prototype.releaseStream = function(){ +LZMA.OutWindow.prototype.releaseStream = function() { this.flush(); this._stream = null; }; -LZMA.OutWindow.prototype.setStream = function(stream){ +LZMA.OutWindow.prototype.setStream = function(stream) { this.releaseStream(); this._stream = stream; }; -LZMA.OutWindow.prototype.init = function(solid){ - if (!solid){ +LZMA.OutWindow.prototype.init = function(solid) { + if (!solid) { this._streamPos = 0; this._pos = 0; } }; -LZMA.OutWindow.prototype.copyBlock = function(distance, len){ +LZMA.OutWindow.prototype.copyBlock = function(distance, len) { var pos = this._pos - distance - 1; - if (pos < 0){ + if (pos < 0) { pos += this._windowSize; } - while(len --){ - if (pos >= this._windowSize){ + while (len --) { + if (pos >= this._windowSize) { pos = 0; } this._buffer[this._pos ++] = this._buffer[pos ++]; - if (this._pos >= this._windowSize){ + if (this._pos >= this._windowSize) { this.flush(); } } }; -LZMA.OutWindow.prototype.putByte = function(b){ +LZMA.OutWindow.prototype.putByte = function(b) { this._buffer[this._pos ++] = b; - if (this._pos >= this._windowSize){ + if (this._pos >= this._windowSize) { this.flush(); } }; -LZMA.OutWindow.prototype.getByte = function(distance){ +LZMA.OutWindow.prototype.getByte = function(distance) { var pos = this._pos - distance - 1; - if (pos < 0){ + if (pos < 0) { pos += this._windowSize; } return this._buffer[pos]; }; -LZMA.RangeDecoder = function(){ +LZMA.RangeDecoder = function() { }; -LZMA.RangeDecoder.prototype.setStream = function(stream){ +LZMA.RangeDecoder.prototype.setStream = function(stream) { this._stream = stream; }; -LZMA.RangeDecoder.prototype.releaseStream = function(){ +LZMA.RangeDecoder.prototype.releaseStream = function() { this._stream = null; }; -LZMA.RangeDecoder.prototype.init = function(){ +LZMA.RangeDecoder.prototype.init = function() { var i = 5; this._code = 0; this._range = -1; - while(i --){ + while (i --) { this._code = (this._code << 8) | this._stream.readByte(); } }; -LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits){ +LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits) { var result = 0, i = numTotalBits, t; - while(i --){ + while (i --) { this._range >>>= 1; t = (this._code - this._range) >>> 31; this._code -= this._range & (t - 1); result = (result << 1) | (1 - t); - if ( (this._range & 0xff000000) === 0){ + if ( (this._range & 0xff000000) === 0) { this._code = (this._code << 8) | this._stream.readByte(); this._range <<= 8; } @@ -122,14 +122,14 @@ LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits){ return result; }; -LZMA.RangeDecoder.prototype.decodeBit = function(probs, index){ +LZMA.RangeDecoder.prototype.decodeBit = function(probs, index) { var prob = probs[index], newBound = (this._range >>> 11) * prob; - if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ){ + if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ) { this._range = newBound; probs[index] += (2048 - prob) >>> 5; - if ( (this._range & 0xff000000) === 0){ + if ( (this._range & 0xff000000) === 0) { this._code = (this._code << 8) | this._stream.readByte(); this._range <<= 8; } @@ -139,41 +139,41 @@ LZMA.RangeDecoder.prototype.decodeBit = function(probs, index){ this._range -= newBound; this._code -= newBound; probs[index] -= prob >>> 5; - if ( (this._range & 0xff000000) === 0){ + if ( (this._range & 0xff000000) === 0) { this._code = (this._code << 8) | this._stream.readByte(); this._range <<= 8; } return 1; }; -LZMA.initBitModels = function(probs, len){ - while(len --){ +LZMA.initBitModels = function(probs, len) { + while (len --) { probs[len] = 1024; } }; -LZMA.BitTreeDecoder = function(numBitLevels){ +LZMA.BitTreeDecoder = function(numBitLevels) { this._models = []; this._numBitLevels = numBitLevels; }; -LZMA.BitTreeDecoder.prototype.init = function(){ +LZMA.BitTreeDecoder.prototype.init = function() { LZMA.initBitModels(this._models, 1 << this._numBitLevels); }; -LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder){ +LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder) { var m = 1, i = this._numBitLevels; - while(i --){ + while (i --) { m = (m << 1) | rangeDecoder.decodeBit(this._models, m); } return m - (1 << this._numBitLevels); }; -LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder){ +LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder) { var m = 1, symbol = 0, i = 0, bit; - for (; i < this._numBitLevels; ++ i){ + for (; i < this._numBitLevels; ++ i) { bit = rangeDecoder.decodeBit(this._models, m); m = (m << 1) | bit; symbol |= bit << i; @@ -181,10 +181,10 @@ LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder){ return symbol; }; -LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels){ +LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels) { var m = 1, symbol = 0, i = 0, bit; - for (; i < numBitLevels; ++ i){ + for (; i < numBitLevels; ++ i) { bit = rangeDecoder.decodeBit(models, startIndex + m); m = (m << 1) | bit; symbol |= bit << i; @@ -192,7 +192,7 @@ LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels){ return symbol; }; -LZMA.LenDecoder = function(){ +LZMA.LenDecoder = function() { this._choice = []; this._lowCoder = []; this._midCoder = []; @@ -200,79 +200,79 @@ LZMA.LenDecoder = function(){ this._numPosStates = 0; }; -LZMA.LenDecoder.prototype.create = function(numPosStates){ - for (; this._numPosStates < numPosStates; ++ this._numPosStates){ +LZMA.LenDecoder.prototype.create = function(numPosStates) { + for (; this._numPosStates < numPosStates; ++ this._numPosStates) { this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3); this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3); } }; -LZMA.LenDecoder.prototype.init = function(){ +LZMA.LenDecoder.prototype.init = function() { var i = this._numPosStates; LZMA.initBitModels(this._choice, 2); - while(i --){ + while (i --) { this._lowCoder[i].init(); this._midCoder[i].init(); } this._highCoder.init(); }; -LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState){ - if (rangeDecoder.decodeBit(this._choice, 0) === 0){ +LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState) { + if (rangeDecoder.decodeBit(this._choice, 0) === 0) { return this._lowCoder[posState].decode(rangeDecoder); } - if (rangeDecoder.decodeBit(this._choice, 1) === 0){ + if (rangeDecoder.decodeBit(this._choice, 1) === 0) { return 8 + this._midCoder[posState].decode(rangeDecoder); } return 16 + this._highCoder.decode(rangeDecoder); }; -LZMA.Decoder2 = function(){ +LZMA.Decoder2 = function() { this._decoders = []; }; -LZMA.Decoder2.prototype.init = function(){ +LZMA.Decoder2.prototype.init = function() { LZMA.initBitModels(this._decoders, 0x300); }; -LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder){ +LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder) { var symbol = 1; - do{ + do { symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol); - }while(symbol < 0x100); + }while (symbol < 0x100); return symbol & 0xff; }; -LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte){ +LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte) { var symbol = 1, matchBit, bit; - do{ + do { matchBit = (matchByte >> 7) & 1; matchByte <<= 1; bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol); symbol = (symbol << 1) | bit; - if (matchBit !== bit){ - while(symbol < 0x100){ + if (matchBit !== bit) { + while (symbol < 0x100) { symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol); } break; } - }while(symbol < 0x100); + }while (symbol < 0x100); return symbol & 0xff; }; -LZMA.LiteralDecoder = function(){ +LZMA.LiteralDecoder = function() { }; -LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits){ +LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits) { var i; if (this._coders && (this._numPrevBits === numPrevBits) - && (this._numPosBits === numPosBits) ){ + && (this._numPosBits === numPosBits) ) { return; } this._numPosBits = numPosBits; @@ -282,24 +282,24 @@ LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits){ this._coders = []; i = 1 << (this._numPrevBits + this._numPosBits); - while(i --){ + while (i --) { this._coders[i] = new LZMA.Decoder2(); } }; -LZMA.LiteralDecoder.prototype.init = function(){ +LZMA.LiteralDecoder.prototype.init = function() { var i = 1 << (this._numPrevBits + this._numPosBits); - while(i --){ + while (i --) { this._coders[i].init(); } }; -LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte){ +LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte) { return this._coders[( (pos & this._posMask) << this._numPrevBits) + ( (prevByte & 0xff) >>> (8 - this._numPrevBits) )]; }; -LZMA.Decoder = function(){ +LZMA.Decoder = function() { this._outWindow = new LZMA.OutWindow(); this._rangeDecoder = new LZMA.RangeDecoder(); this._isMatchDecoders = []; @@ -323,11 +323,11 @@ LZMA.Decoder = function(){ this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6); }; -LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize){ - if (dictionarySize < 0){ +LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize) { + if (dictionarySize < 0) { return false; } - if (this._dictionarySize !== dictionarySize){ + if (this._dictionarySize !== dictionarySize) { this._dictionarySize = dictionarySize; this._dictionarySizeCheck = Math.max(this._dictionarySize, 1); this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) ); @@ -335,10 +335,10 @@ LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize){ return true; }; -LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb){ +LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb) { var numPosStates = 1 << pb; - if (lc > 8 || lp > 4 || pb > 4){ + if (lc > 8 || lp > 4 || pb > 4) { return false; } @@ -351,7 +351,7 @@ LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb){ return true; }; -LZMA.Decoder.prototype.init = function(){ +LZMA.Decoder.prototype.init = function() { var i = 4; this._outWindow.init(false); @@ -366,7 +366,7 @@ LZMA.Decoder.prototype.init = function(){ this._literalDecoder.init(); - while(i --){ + while (i --) { this._posSlotDecoder[i].init(); } @@ -376,7 +376,7 @@ LZMA.Decoder.prototype.init = function(){ this._rangeDecoder.init(); }; -LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize){ +LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize) { var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0, posState, decoder2, len, distance, posSlot, numDirectBits; @@ -385,37 +385,37 @@ LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize){ this.init(); - while(outSize < 0 || nowPos64 < outSize){ + while (outSize < 0 || nowPos64 < outSize) { posState = nowPos64 & this._posStateMask; - if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0){ + if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0) { decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte); - if (state >= 7){ + if (state >= 7) { prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) ); - }else{ + }else { prevByte = decoder2.decodeNormal(this._rangeDecoder); } this._outWindow.putByte(prevByte); - state = state < 4? 0: state - (state < 10? 3: 6); + state = state < 4 ? 0 : state - (state < 10 ? 3 : 6); - }else{ + }else { - if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1){ + if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1) { len = 0; - if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0){ - if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0){ - state = state < 7? 9: 11; + if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0) { + if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0) { + state = state < 7 ? 9 : 11; len = 1; } - }else{ - if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0){ + }else { + if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0) { distance = rep1; - }else{ - if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0){ + }else { + if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0) { distance = rep2; - }else{ + }else { distance = rep3; rep3 = rep2; } @@ -424,43 +424,43 @@ LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize){ rep1 = rep0; rep0 = distance; } - if (len === 0){ + if (len === 0) { len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState); - state = state < 7? 8: 11; + state = state < 7 ? 8 : 11; } - }else{ + }else { rep3 = rep2; rep2 = rep1; rep1 = rep0; len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState); - state = state < 7? 7: 10; + state = state < 7 ? 7 : 10; - posSlot = this._posSlotDecoder[len <= 5? len - 2: 3].decode(this._rangeDecoder); - if (posSlot >= 4){ + posSlot = this._posSlotDecoder[len <= 5 ? len - 2 : 3].decode(this._rangeDecoder); + if (posSlot >= 4) { numDirectBits = (posSlot >> 1) - 1; rep0 = (2 | (posSlot & 1) ) << numDirectBits; - if (posSlot < 14){ + if (posSlot < 14) { rep0 += LZMA.reverseDecode2(this._posDecoders, rep0 - posSlot - 1, this._rangeDecoder, numDirectBits); - }else{ + }else { rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4; rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder); - if (rep0 < 0){ - if (rep0 === -1){ + if (rep0 < 0) { + if (rep0 === -1) { break; } return false; } } - }else{ + }else { rep0 = posSlot; } } - if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck){ + if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck) { return false; } @@ -477,10 +477,10 @@ LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize){ return true; }; -LZMA.Decoder.prototype.setDecoderProperties = function(properties){ +LZMA.Decoder.prototype.setDecoderProperties = function(properties) { var value, lc, lp, pb, dictionarySize; - if (properties.size < 5){ + if (properties.size < 5) { return false; } @@ -490,7 +490,7 @@ LZMA.Decoder.prototype.setDecoderProperties = function(properties){ lp = value % 5; pb = ~~(value / 5); - if ( !this.setLcLpPb(lc, lp, pb) ){ + if ( !this.setLcLpPb(lc, lp, pb) ) { return false; } @@ -502,14 +502,14 @@ LZMA.Decoder.prototype.setDecoderProperties = function(properties){ return this.setDictionarySize(dictionarySize); }; -LZMA.decompress = function(properties, inStream, outStream, outSize){ +LZMA.decompress = function(properties, inStream, outStream, outSize) { var decoder = new LZMA.Decoder(); - if ( !decoder.setDecoderProperties(properties) ){ + if ( !decoder.setDecoderProperties(properties) ) { throw "Incorrect stream properties"; } - if ( !decoder.decode(inStream, outStream, outSize) ){ + if ( !decoder.decode(inStream, outStream, outSize) ) { throw "Error in data stream"; } diff --git a/examples/js/loaders/deprecated/SceneLoader.js b/examples/js/loaders/deprecated/SceneLoader.js index 322e25488fcbe3..aa163f5ae9d65b 100644 --- a/examples/js/loaders/deprecated/SceneLoader.js +++ b/examples/js/loaders/deprecated/SceneLoader.js @@ -891,7 +891,7 @@ THREE.SceneLoader.prototype = { counter_textures += textureJSON.url.length; - for( var n = 0; n < textureJSON.url.length; n ++ ) { + for ( var n = 0; n < textureJSON.url.length; n ++ ) { scope.onLoadStart(); diff --git a/examples/js/loaders/gltf/glTF-parser.js b/examples/js/loaders/gltf/glTF-parser.js index b23b3729947bee..ed53d2a380fc7a 100755 --- a/examples/js/loaders/gltf/glTF-parser.js +++ b/examples/js/loaders/gltf/glTF-parser.js @@ -66,7 +66,7 @@ var global = window; }(this, function (root) { "use strict"; - var categoriesDepsOrder = ["buffers", "bufferViews", "images", "videos", "samplers", "textures", "shaders", "programs", "techniques", "materials", "accessors", "meshes", "cameras", "lights", "skins", "nodes", "scenes", "animations"]; + var categoriesDepsOrder = [ "buffers", "bufferViews", "images", "videos", "samplers", "textures", "shaders", "programs", "techniques", "materials", "accessors", "meshes", "cameras", "lights", "skins", "nodes", "scenes", "animations" ]; var glTFParser = Object.create(Object.prototype, { @@ -86,7 +86,7 @@ var global = window; //detect absolute path following the same protocol than window.location _isAbsolutePath: { value: function(path) { - var isAbsolutePathRegExp = new RegExp("^"+window.location.protocol, "i"); + var isAbsolutePathRegExp = new RegExp("^" + window.location.protocol, "i"); return path.match(isAbsolutePathRegExp) ? true : false; } @@ -130,7 +130,7 @@ var global = window; set: function(value) { if (this._json !== value) { this._json = value; - this._resolvePathsForCategories(["buffers", "shaders", "images", "videos"]); + this._resolvePathsForCategories([ "buffers", "shaders", "images", "videos" ]); } } }, @@ -147,7 +147,7 @@ var global = window; var category = entryType; entries = this.rootDescription[category]; if (!entries) { - console.log("ERROR:CANNOT find expected category named:"+category); + console.log("ERROR:CANNOT find expected category named:" + category); return null; } @@ -177,7 +177,7 @@ var global = window; return false; } - categoryState.index++; + categoryState.index ++; categoryState.keys = null; if (categoryState.index >= keys.length) { return this._stepToNextCategory(); @@ -237,7 +237,7 @@ var global = window; var description = this.getEntryDescription(entryID, type); if (!description) { if (this.handleError) { - this.handleError("INCONSISTENCY ERROR: no description found for entry "+entryID); + this.handleError("INCONSISTENCY ERROR: no description found for entry " + entryID); success = false; break; } @@ -266,7 +266,7 @@ var global = window; value: function(callback) { var self = this; //FIXME: handle error - if (!this._json) { + if (!this._json) { var jsonPath = this._path; var i = jsonPath.lastIndexOf("/"); this.baseURL = (i !== 0) ? jsonPath.substring(0, i + 1) : ''; @@ -306,7 +306,7 @@ var global = window; _getEntryType: { value: function(entryID) { var rootKeys = categoriesDepsOrder; - for (var i = 0 ; i < rootKeys.length ; i++) { + for (var i = 0 ; i < rootKeys.length ; i ++) { var rootValues = this.rootDescription[rootKeys[i]]; if (rootValues) { return rootKeys[i]; @@ -318,7 +318,7 @@ var global = window; getNextCategoryIndex: { value: function(currentIndex) { - for (var i = currentIndex ; i < categoriesDepsOrder.length ; i++) { + for (var i = currentIndex ; i < categoriesDepsOrder.length ; i ++) { if (this.hasCategory(categoriesDepsOrder[i])) { return i; } @@ -333,7 +333,7 @@ var global = window; value: function(userInfo, options) { var self = this; this._buildLoader(function loaderReady(reader) { - var startCategory = self.getNextCategoryIndex.call(self,0); + var startCategory = self.getNextCategoryIndex.call(self, 0); if (startCategory !== -1) { self._state = { "userInfo" : userInfo, "options" : options, @@ -379,7 +379,7 @@ var global = window; }); - if(root) { + if (root) { root.glTFParser = glTFParser; } diff --git a/examples/js/loaders/gltf/glTFAnimation.js b/examples/js/loaders/gltf/glTFAnimation.js index 735e5f1e2a4372..7694c50662c7d0 100644 --- a/examples/js/loaders/gltf/glTFAnimation.js +++ b/examples/js/loaders/gltf/glTFAnimation.js @@ -24,7 +24,7 @@ THREE.glTFAnimator = ( function () { update : function() { - for (i = 0; i < animators.length; i++) + for (i = 0; i < animators.length; i ++) { animators[i].update(); } @@ -50,7 +50,7 @@ THREE.glTFAnimation = function(interps) THREE.glTFAnimation.prototype.createInterpolators = function(interps) { var i, len = interps.length; - for (i = 0; i < len; i++) + for (i = 0; i < len; i ++) { var interp = new THREE.glTFInterpolator(interps[i]); this.interps.push(interp); @@ -90,7 +90,7 @@ THREE.glTFAnimation.prototype.update = function() { this.running = false; var i, len = this.interps.length; - for (i = 0; i < len; i++) + for (i = 0; i < len; i ++) { this.interps[i].interp(this.duration); } @@ -100,7 +100,7 @@ THREE.glTFAnimation.prototype.update = function() else { var i, len = this.interps.length; - for (i = 0; i < len; i++) + for (i = 0; i < len; i ++) { this.interps[i].interp(t); } @@ -202,7 +202,7 @@ THREE.glTFInterpolator.prototype.interp = function(t) } else { - for (i = 0; i < this.count - 1; i++) + for (i = 0; i < this.count - 1; i ++) { var key1 = this.keys[i]; var key2 = this.keys[i + 1]; diff --git a/examples/js/loaders/gltf/glTFLoader.js b/examples/js/loaders/gltf/glTFLoader.js index 99b442767f4450..10d397f9dd0eb4 100644 --- a/examples/js/loaders/gltf/glTFLoader.js +++ b/examples/js/loaders/gltf/glTFLoader.js @@ -25,7 +25,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { // Utilities function RgbArraytoHex(colorArray) { - if(!colorArray) return 0xFFFFFFFF; + if (!colorArray) return 0xFFFFFFFF; var r = Math.floor(colorArray[0] * 255), g = Math.floor(colorArray[1] * 255), b = Math.floor(colorArray[2] * 255), @@ -43,7 +43,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var euler = new THREE.Vector3; var i; - for (i = 0; i < count; i++) { + for (i = 0; i < count; i ++) { axis.set(rotations[i * 4], rotations[i * 4 + 1], rotations[i * 4 + 2]).normalize(); var angle = rotations[i * 4 + 3]; @@ -76,7 +76,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { function LoadTexture(src) { - if(!src) { return null; } + if (!src) { return null; } return THREE.ImageUtils.loadTexture(src); } @@ -110,13 +110,13 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { } ClassicGeometry.prototype.checkFinished = function() { - if(this.indexArray && this.loadedAttributes === this.totalAttributes) { + if (this.indexArray && this.loadedAttributes === this.totalAttributes) { this.buildBufferGeometry(); this.finished = true; - if(this.onload) { + if (this.onload) { this.onload(); } } @@ -127,7 +127,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { IndicesDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(IndicesDelegate):"+errorCode+":"+info); + console.log("ERROR(IndicesDelegate):" + errorCode + ":" + info); }; IndicesDelegate.prototype.convert = function(resource, ctx) { @@ -153,7 +153,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { VertexAttributeDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(VertexAttributeDelegate):"+errorCode+":"+info); + console.log("ERROR(VertexAttributeDelegate):" + errorCode + ":" + info); }; VertexAttributeDelegate.prototype.convert = function(resource, ctx) { @@ -170,37 +170,37 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var i, l; //FIXME: Float32 is assumed here, but should be checked. - if(semantic == "POSITION") { + if (semantic == "POSITION") { // TODO: Should be easy to take strides into account here floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); - for(i = 0, l = floatArray.length; i < l; i += 3) { - geom.geometry.vertices.push( new THREE.Vector3( floatArray[i], floatArray[i+1], floatArray[i+2] ) ); + for (i = 0, l = floatArray.length; i < l; i += 3) { + geom.geometry.vertices.push( new THREE.Vector3( floatArray[i], floatArray[i + 1], floatArray[i + 2] ) ); } - } else if(semantic == "NORMAL") { + } else if (semantic == "NORMAL") { geom.geometry.normals = []; floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); - for(i = 0, l = floatArray.length; i < l; i += 3) { - geom.geometry.normals.push( new THREE.Vector3( floatArray[i], floatArray[i+1], floatArray[i+2] ) ); + for (i = 0, l = floatArray.length; i < l; i += 3) { + geom.geometry.normals.push( new THREE.Vector3( floatArray[i], floatArray[i + 1], floatArray[i + 2] ) ); } } else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) { geom.uvs = []; floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); - for(i = 0, l = floatArray.length; i < l; i += 2) { - geom.uvs.push( new THREE.Vector2( floatArray[i], 1.0 - floatArray[i+1] ) ); + for (i = 0, l = floatArray.length; i < l; i += 2) { + geom.uvs.push( new THREE.Vector2( floatArray[i], 1.0 - floatArray[i + 1] ) ); } } else if (semantic == "WEIGHT") { nComponents = componentsPerElementForGLType(attribute.type); floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); - for(i = 0, l = floatArray.length; i < l; i += 4) { - geom.geometry.skinWeights.push( new THREE.Vector4( floatArray[i], floatArray[i+1], floatArray[i+2], floatArray[i+3] ) ); + for (i = 0, l = floatArray.length; i < l; i += 4) { + geom.geometry.skinWeights.push( new THREE.Vector4( floatArray[i], floatArray[i + 1], floatArray[i + 2], floatArray[i + 3] ) ); } } else if (semantic == "JOINT") { nComponents = componentsPerElementForGLType(attribute.type); floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); - for(i = 0, l = floatArray.length; i < l; i += 4) { - geom.geometry.skinIndices.push( new THREE.Vector4( floatArray[i], floatArray[i+1], floatArray[i+2], floatArray[i+3] ) ); + for (i = 0, l = floatArray.length; i < l; i += 4) { + geom.geometry.skinIndices.push( new THREE.Vector4( floatArray[i], floatArray[i + 1], floatArray[i + 2], floatArray[i + 3] ) ); } } } @@ -214,11 +214,11 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var nComponents; //FIXME: Float32 is assumed here, but should be checked. - if(semantic == "POSITION") { + if (semantic == "POSITION") { // TODO: Should be easy to take strides into account here floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); geom.geometry.addAttribute( 'position', new THREE.BufferAttribute( floatArray, 3 ) ); - } else if(semantic == "NORMAL") { + } else if (semantic == "NORMAL") { floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); geom.geometry.addAttribute( 'normal', new THREE.BufferAttribute( floatArray, 3 ) ); } else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) { @@ -226,8 +226,8 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { nComponents = componentsPerElementForGLType(attribute.type); floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); // N.B.: flip Y value... should we just set texture.flipY everywhere? - for (i = 0; i < floatArray.length / 2; i++) { - floatArray[i*2+1] = 1.0 - floatArray[i*2+1]; + for (i = 0; i < floatArray.length / 2; i ++) { + floatArray[i * 2 + 1] = 1.0 - floatArray[i * 2 + 1]; } geom.geometry.addAttribute( 'uv', new THREE.BufferAttribute( floatArray, nComponents ) ); } @@ -248,7 +248,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { this.bufferResourceAvailable(glResource, ctx); var geom = ctx.geometry; - geom.loadedAttributes++; + geom.loadedAttributes ++; geom.checkFinished(); return true; }; @@ -272,7 +272,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var self = this; geometry.onload = function() { - self.loadedGeometry++; + self.loadedGeometry ++; self.checkComplete(); }; @@ -290,7 +290,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { Mesh.prototype.checkComplete = function() { var self = this; - if(this.onCompleteCallbacks.length && this.primitives.length == this.loadedGeometry) { + if (this.onCompleteCallbacks.length && this.primitives.length == this.loadedGeometry) { this.onCompleteCallbacks.forEach(function(callback) { callback(self); }); @@ -325,7 +325,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { AnimationParameterDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(AnimationParameterDelegate):"+errorCode+":"+info); + console.log("ERROR(AnimationParameterDelegate):" + errorCode + ":" + info); }; AnimationParameterDelegate.prototype.convert = function(resource, ctx) { @@ -377,12 +377,12 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { Animation.prototype.handleParameterLoaded = function(parameter) { this.parameters[parameter.name] = parameter; - this.loadedParameters++; + this.loadedParameters ++; this.checkFinished(); }; Animation.prototype.checkFinished = function() { - if(this.loadedParameters === this.totalParameters) { + if (this.loadedParameters === this.totalParameters) { // Build animation this.finishedLoading = true; @@ -397,7 +397,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { InverseBindMatricesDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(InverseBindMatricesDelegate):"+errorCode+":"+info); + console.log("ERROR(InverseBindMatricesDelegate):" + errorCode + ":" + info); }; InverseBindMatricesDelegate.prototype.convert = function(resource, ctx) { @@ -433,7 +433,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { ShaderDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(ShaderDelegate):"+errorCode+":"+info); + console.log("ERROR(ShaderDelegate):" + errorCode + ":" + info); }; ShaderDelegate.prototype.convert = function(resource, ctx) { @@ -441,7 +441,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { } ShaderDelegate.prototype.resourceAvailable = function(data, ctx) { - theLoader.shadersLoaded++; + theLoader.shadersLoaded ++; theLoader.shaders[ctx.id] = data; return true; }; @@ -472,7 +472,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { } if (this._entries[entryID]) { - console.warn("entry["+entryID+"] is being overwritten"); + console.warn("entry[" + entryID + "] is being overwritten"); } this._entries[entryID] = new ResourceEntry(entryID, object, description ); @@ -562,7 +562,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var shaderContext = new ShaderContext(entryID, description.path); - theLoader.shadersRequested++; + theLoader.shadersRequested ++; THREE.GLTFLoaderUtils.getFile(shaderRequest, shaderDelegate, shaderContext); return true; @@ -825,11 +825,11 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var primitivesDescription = description.primitives; if (!primitivesDescription) { //FIXME: not implemented in delegate - console.log("MISSING_PRIMITIVES for mesh:"+ entryID); + console.log("MISSING_PRIMITIVES for mesh:" + entryID); return false; } - for (var i = 0 ; i < primitivesDescription.length ; i++) { + for (var i = 0 ; i < primitivesDescription.length ; i ++) { var primitiveDescription = primitivesDescription[i]; if (primitiveDescription.primitive === WebGLRenderingContext.TRIANGLES) { @@ -858,7 +858,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { // Load Vertex Attributes var allAttributes = Object.keys(primitiveDescription.attributes); allAttributes.forEach( function(semantic) { - geometry.totalAttributes++; + geometry.totalAttributes ++; var attribute; var attributeID = primitiveDescription.attributes[semantic]; @@ -1013,7 +1013,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { this.resources.setEntry(entryID, threeNode, description); var m = description.matrix; - if(m) { + if (m) { threeNode.applyMatrix(new THREE.Matrix4().fromArray( m )); threeNode.matrixAutoUpdate = false; threeNode.matrixWorldNeedsUpdate = true; @@ -1047,10 +1047,10 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var meshEntry; if (description.mesh) { meshEntry = this.resources.getEntry(description.mesh); - theLoader.meshesRequested++; + theLoader.meshesRequested ++; meshEntry.object.onComplete(function(mesh) { self.addPendingMesh(mesh, threeNode); - theLoader.meshesLoaded++; + theLoader.meshesLoaded ++; theLoader.checkComplete(); }); } @@ -1058,10 +1058,10 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { if (description.meshes) { description.meshes.forEach( function(meshID) { meshEntry = this.resources.getEntry(meshID); - theLoader.meshesRequested++; + theLoader.meshesRequested ++; meshEntry.object.onComplete(function(mesh) { self.addPendingMesh(mesh, threeNode); - theLoader.meshesLoaded++; + theLoader.meshesLoaded ++; theLoader.checkComplete(); }); }, this); @@ -1081,11 +1081,11 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { skin.meshes = []; sources.forEach( function(meshID) { meshEntry = this.resources.getEntry(meshID); - theLoader.meshesRequested++; + theLoader.meshesRequested ++; meshEntry.object.onComplete(function(mesh) { skin.meshes.push(mesh); - theLoader.meshesLoaded++; + theLoader.meshesLoaded ++; theLoader.checkComplete(); }); }, this); @@ -1144,7 +1144,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var dobones = true; var i, len = skin.meshes.length; - for (i = 0; i < len; i++) { + for (i = 0; i < len; i ++) { var mesh = skin.meshes[i]; var threeMesh = null; mesh.primitives.forEach(function(primitive) { @@ -1167,7 +1167,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { else if (geometry.attributes.position) { var a = geometry.attributes.position.array; var v = new THREE.Vector3; - for ( j = 0; j < a.length / 3; j++ ) { + for ( j = 0; j < a.length / 3; j ++ ) { v.set(a[j * 3], a[j * 3 + 1], a[j * 3 + 2]); v.applyMatrix4( skin.bindShapeMatrix ); a[j * 3] = v.x; @@ -1185,7 +1185,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var bones = []; var boneInverses = []; var i, len = jointsIds.length; - for (i = 0; i < len; i++) { + for (i = 0; i < len; i ++) { var jointId = jointsIds[i]; var nodeForJoint = this.joints[jointId]; var joint = this.resources.getEntry(nodeForJoint).object; @@ -1204,7 +1204,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { boneInverses.push(mat); } else { - console.log("WARNING: jointId:"+jointId+" cannot be found in skeleton:"+skeleton); + console.log("WARNING: jointId:" + jointId + " cannot be found in skeleton:" + skeleton); } } @@ -1310,7 +1310,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var interps = []; var i, len = animation.channels.length; - for (i = 0; i < len; i++) { + for (i = 0; i < len; i ++) { var channel = animation.channels[i]; var sampler = animation.samplers[channel.sampler]; @@ -1356,12 +1356,12 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { value: function(entryID, description, userInfo) { var self = this; - theLoader.animationsRequested++; + theLoader.animationsRequested ++; var animation = new Animation(); animation.name = entryID; animation.onload = function() { // self.buildAnimation(animation); - theLoader.animationsLoaded++; + theLoader.animationsLoaded ++; theLoader.animations.push(animation); theLoader.checkComplete(); }; @@ -1372,7 +1372,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var parameters = description.parameters; if (!parameters) { //FIXME: not implemented in delegate - console.log("MISSING_PARAMETERS for animation:"+ entryID); + console.log("MISSING_PARAMETERS for animation:" + entryID); return false; } @@ -1380,7 +1380,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var params = Object.keys(parameters); params.forEach( function(param) { - animation.totalParameters++; + animation.totalParameters ++; var parameter = parameters[param]; var accessor = this.resources.getEntry(parameter); if (!accessor) @@ -1535,12 +1535,12 @@ THREE.glTFLoader.prototype.checkComplete = function() { && this.animationsLoaded == this.animationsRequested) { - for (var i = 0; i < this.pendingMeshes.length; i++) { + for (var i = 0; i < this.pendingMeshes.length; i ++) { var pending = this.pendingMeshes[i]; pending.mesh.attachToNode(pending.node); } - for (var i = 0; i < this.animationsLoaded; i++) { + for (var i = 0; i < this.animationsLoaded; i ++) { var animation = this.animations[i]; this.loader.buildAnimation(animation); } diff --git a/examples/js/loaders/gltf/glTFLoaderUtils.js b/examples/js/loaders/gltf/glTFLoaderUtils.js index 9a937b21a4365e..961fdc946b25cb 100644 --- a/examples/js/loaders/gltf/glTFLoaderUtils.js +++ b/examples/js/loaders/gltf/glTFLoaderUtils.js @@ -48,7 +48,7 @@ THREE.GLTFLoaderUtils = Object.create(Object, { } if (this._containsResource[resourceID]) { - console.log("WARNING: resource:"+resourceID+" is already stored, overriding"); + console.log("WARNING: resource:" + resourceID + " is already stored, overriding"); } this._resources[resourceID] = resource; @@ -100,7 +100,7 @@ THREE.GLTFLoaderUtils = Object.create(Object, { var resourceStatus = this._resourcesStatus[request.id]; if (resourceStatus) { - this._resourcesStatus[request.id]++; + this._resourcesStatus[request.id] ++; } else { @@ -114,7 +114,7 @@ THREE.GLTFLoaderUtils = Object.create(Object, { return; } - this._streamsStatus[request.path] = { status : "loading", requests : [request] }; + this._streamsStatus[request.path] = { status : "loading", requests : [ request ] }; var self = this; var processResourceDelegate = {}; @@ -127,7 +127,7 @@ THREE.GLTFLoaderUtils = Object.create(Object, { var convertedResource = req_.delegate.convert(subArray, req_.ctx); self._storeResource(req_.id, convertedResource); req_.delegate.resourceAvailable(convertedResource, req_.ctx); - --self._resourcesStatus[req_.id]; + -- self._resourcesStatus[req_.id]; }, this); @@ -174,9 +174,9 @@ THREE.GLTFLoaderUtils = Object.create(Object, { var bufferView = wrappedBufferView.bufferView; var buffer = bufferView.buffer; var byteOffset = wrappedBufferView.byteOffset + bufferView.description.byteOffset; - var range = [byteOffset , (this._elementSizeForGLType(wrappedBufferView.type) * wrappedBufferView.count) + byteOffset]; + var range = [ byteOffset, (this._elementSizeForGLType(wrappedBufferView.type) * wrappedBufferView.count) + byteOffset ]; - this._handleRequest({ "id" : wrappedBufferView.id, + this._handleRequest({ "id" : wrappedBufferView.id, "range" : range, "type" : buffer.description.type, "path" : buffer.description.path, @@ -207,9 +207,9 @@ THREE.GLTFLoaderUtils = Object.create(Object, { request.delegate = delegate; request.ctx = ctx; - this._handleRequest({ "id" : request.id, + this._handleRequest({ "id" : request.id, "path" : request.path, - "range" : [0], + "range" : [ 0 ], "type" : "text", "delegate" : delegate, "ctx" : ctx }, null); diff --git a/examples/js/math/Lut.js b/examples/js/math/Lut.js index b91c97ed70a436..f488f9a93c166a 100644 --- a/examples/js/math/Lut.js +++ b/examples/js/math/Lut.js @@ -42,7 +42,7 @@ THREE.Lut.prototype = { constructor: THREE.Lut, - lut: [], map: [], mapname: 'rainbow' , n: 256, minV: 0, maxV: 1, legend: null, + lut: [], map: [], mapname: 'rainbow', n: 256, minV: 0, maxV: 1, legend: null, set: function ( value ) { @@ -167,7 +167,7 @@ THREE.Lut.prototype = { for ( var i = 1; i >= 0; i-=step ) { - for ( var j = this.map.length - 1; j >= 0; j-- ) { + for ( var j = this.map.length - 1; j >= 0; j -- ) { if ( i < this.map[ j ][ 0 ] && i >= this.map[ j - 1 ][ 0 ] ) { @@ -194,7 +194,7 @@ THREE.Lut.prototype = { this.legend.ctx.putImageData( imageData, 0, 0 ); this.legend.texture.needsUpdate = true; - this.legend.legendGeometry = new THREE.PlaneBufferGeometry( this.legend.dimensions.width , this.legend.dimensions.height ); + this.legend.legendGeometry = new THREE.PlaneBufferGeometry( this.legend.dimensions.width, this.legend.dimensions.height ); this.legend.legendMaterial = new THREE.MeshBasicMaterial( { map : this.legend.texture, side : THREE.DoubleSide } ); this.legend.mesh = new THREE.Mesh( this.legend.legendGeometry, this.legend.legendMaterial ); @@ -269,7 +269,7 @@ THREE.Lut.prototype = { this.legend.labels.title = parameters.hasOwnProperty( 'title' ) ? parameters[ 'title' ] : ''; - this.legend.labels.um = parameters.hasOwnProperty( 'um' ) ? ' [ '+ parameters[ 'um' ] + ' ]': ''; + this.legend.labels.um = parameters.hasOwnProperty( 'um' ) ? ' [ ' + parameters[ 'um' ] + ' ]' : ''; this.legend.labels.ticks = parameters.hasOwnProperty( 'ticks' ) ? parameters[ 'ticks' ] : 0; @@ -340,7 +340,7 @@ THREE.Lut.prototype = { } - for ( var i = 0; i < this.legend.labels.ticks; i++ ) { + for ( var i = 0; i < this.legend.labels.ticks; i ++ ) { var value = ( this.maxV - this.minV ) / ( this.legend.labels.ticks - 1 ) * i ; @@ -429,7 +429,7 @@ THREE.Lut.prototype = { var linePosition = ( this.legend.position.y - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( value / ( this.maxV - this.minV ) * 0.99 ); - geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.55, linePosition , this.legend.position.z ) ); + geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.55, linePosition, this.legend.position.z ) ); geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.7, linePosition, this.legend.position.z ) ); @@ -463,9 +463,9 @@ THREE.Lut.prototype = { THREE.ColorMapKeywords = { - "rainbow": [ [ 0.0, '0x0000FF' ], [ 0.2, '0x00FFFF' ], [ 0.5, '0x00FF00' ], [ 0.8, '0xFFFF00'], [1.0, '0xFF0000' ] ], - "cooltowarm": [ [ 0.0, '0x3C4EC2' ], [ 0.2, '0x9BBCFF' ], [ 0.5, '0xDCDCDC' ], [ 0.8, '0xF6A385'], [1.0, '0xB40426' ] ], - "blackbody" : [ [ 0.0, '0x000000' ], [ 0.2, '0x780000' ], [ 0.5, '0xE63200' ], [ 0.8, '0xFFFF00'], [1.0, '0xFFFFFF' ] ], - "grayscale" : [ [ 0.0, '0x000000' ], [ 0.2, '0x404040' ], [ 0.5, '0x7F7F80' ], [ 0.8, '0xBFBFBF'], [1.0, '0xFFFFFF' ] ] + "rainbow": [ [ 0.0, '0x0000FF' ], [ 0.2, '0x00FFFF' ], [ 0.5, '0x00FF00' ], [ 0.8, '0xFFFF00' ], [ 1.0, '0xFF0000' ] ], + "cooltowarm": [ [ 0.0, '0x3C4EC2' ], [ 0.2, '0x9BBCFF' ], [ 0.5, '0xDCDCDC' ], [ 0.8, '0xF6A385' ], [ 1.0, '0xB40426' ] ], + "blackbody" : [ [ 0.0, '0x000000' ], [ 0.2, '0x780000' ], [ 0.5, '0xE63200' ], [ 0.8, '0xFFFF00' ], [ 1.0, '0xFFFFFF' ] ], + "grayscale" : [ [ 0.0, '0x000000' ], [ 0.2, '0x404040' ], [ 0.5, '0x7F7F80' ], [ 0.8, '0xBFBFBF' ], [ 1.0, '0xFFFFFF' ] ] }; diff --git a/examples/js/modifiers/SubdivisionModifier.js b/examples/js/modifiers/SubdivisionModifier.js index 410c9caa0ac5b7..2a9da86ae317b9 100644 --- a/examples/js/modifiers/SubdivisionModifier.js +++ b/examples/js/modifiers/SubdivisionModifier.js @@ -26,7 +26,7 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { var repeats = this.subdivisions; - while ( repeats-- > 0 ) { + while ( repeats -- > 0 ) { this.smooth( geometry ); } @@ -101,11 +101,11 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { var i, il, face, edge; - for ( i = 0, il = vertices.length; i < il; i++ ) { + for ( i = 0, il = vertices.length; i < il; i ++ ) { metaVertices[ i ] = { edges: [] }; } - for ( i = 0, il = faces.length; i < il; i++ ) { + for ( i = 0, il = faces.length; i < il; i ++ ) { face = faces[ i ]; processEdge( face.a, face.b, vertices, edges, face, metaVertices ); @@ -194,11 +194,11 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { tmp.set( 0, 0, 0 ); - for ( j = 0; j < connectedFaces; j++ ) { + for ( j = 0; j < connectedFaces; j ++ ) { face = currentEdge.faces[ j ]; - for ( k = 0; k < 3; k++ ) { + for ( k = 0; k < 3; k ++ ) { other = oldVertices[ face[ ABC[k] ] ]; if (other !== currentEdge.a && other !== currentEdge.b ) break; @@ -229,7 +229,7 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { var connectingEdge, connectingEdges, oldVertex, newSourceVertex; newSourceVertices = []; - for ( i = 0, il = oldVertices.length; i < il; i++ ) { + for ( i = 0, il = oldVertices.length; i < il; i ++ ) { oldVertex = oldVertices[ i ]; @@ -284,7 +284,7 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { tmp.set( 0, 0, 0 ); - for ( j=0; j < n; j++ ) { + for ( j = 0; j < n; j ++ ) { connectingEdge = connectingEdges[ j ]; other = connectingEdge.a !== oldVertex ? connectingEdge.a : connectingEdge.b; @@ -312,7 +312,7 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { var sl = newSourceVertices.length, edge1, edge2, edge3; newFaces = []; - for ( i = 0, il = oldFaces.length; i < il; i++ ) { + for ( i = 0, il = oldFaces.length; i < il; i ++ ) { face = oldFaces[ i ]; diff --git a/examples/js/postprocessing/AdaptiveToneMappingPass.js b/examples/js/postprocessing/AdaptiveToneMappingPass.js index 8e631c7d616aa6..63c374f0456c9a 100644 --- a/examples/js/postprocessing/AdaptiveToneMappingPass.js +++ b/examples/js/postprocessing/AdaptiveToneMappingPass.js @@ -11,7 +11,7 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) { this.resolution = ( resolution !== undefined ) ? resolution : 256; this.needsInit = true; - this.adaptive = adaptive !== undefined? !!adaptive : true; + this.adaptive = adaptive !== undefined ? !!adaptive : true; this.luminanceRT = null; this.previousLuminanceRT = null; @@ -190,7 +190,7 @@ THREE.AdaptiveToneMappingPass.prototype = { this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT; } //Put something in the adaptive luminance texture so that the scene can render initially - this.quad.material = new THREE.MeshBasicMaterial( {color: 0x777777 }); + this.quad.material = new THREE.MeshBasicMaterial( { color: 0x777777 }); this.materialLuminance.needsUpdate = true; this.materialAdaptiveLum.needsUpdate = true; this.materialToneMap.needsUpdate = true; diff --git a/examples/js/postprocessing/GlitchPass.js b/examples/js/postprocessing/GlitchPass.js index b9a71948132df0..28062edf92f870 100644 --- a/examples/js/postprocessing/GlitchPass.js +++ b/examples/js/postprocessing/GlitchPass.js @@ -9,10 +9,10 @@ THREE.GlitchPass = function ( dt_size ) { var shader = THREE.DigitalGlitch; this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); - if(dt_size==undefined) dt_size=64; + if (dt_size == undefined) dt_size = 64; - this.uniforms[ "tDisp"].value=this.generateHeightmap(dt_size); + this.uniforms[ "tDisp"].value = this.generateHeightmap(dt_size); this.material = new THREE.ShaderMaterial({ @@ -34,8 +34,8 @@ THREE.GlitchPass = function ( dt_size ) { this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null ); this.scene.add( this.quad ); - this.goWild=false; - this.curF=0; + this.goWild = false; + this.curF = 0; this.generateTrigger(); }; @@ -45,34 +45,34 @@ THREE.GlitchPass.prototype = { render: function ( renderer, writeBuffer, readBuffer, delta ) { this.uniforms[ "tDiffuse" ].value = readBuffer; - this.uniforms[ 'seed' ].value=Math.random();//default seeding - this.uniforms[ 'byp' ].value=0; + this.uniforms[ 'seed' ].value = Math.random();//default seeding + this.uniforms[ 'byp' ].value = 0; - if(this.curF % this.randX ==0 || this.goWild==true) + if (this.curF % this.randX == 0 || this.goWild == true) { - this.uniforms[ 'amount' ].value=Math.random()/30; - this.uniforms[ 'angle' ].value=THREE.Math.randFloat(-Math.PI,Math.PI); - this.uniforms[ 'seed_x' ].value=THREE.Math.randFloat(-1,1); - this.uniforms[ 'seed_y' ].value=THREE.Math.randFloat(-1,1); - this.uniforms[ 'distortion_x' ].value=THREE.Math.randFloat(0,1); - this.uniforms[ 'distortion_y' ].value=THREE.Math.randFloat(0,1); - this.curF=0; + this.uniforms[ 'amount' ].value = Math.random() / 30; + this.uniforms[ 'angle' ].value = THREE.Math.randFloat(-Math.PI, Math.PI); + this.uniforms[ 'seed_x' ].value = THREE.Math.randFloat(-1, 1); + this.uniforms[ 'seed_y' ].value = THREE.Math.randFloat(-1, 1); + this.uniforms[ 'distortion_x' ].value = THREE.Math.randFloat(0, 1); + this.uniforms[ 'distortion_y' ].value = THREE.Math.randFloat(0, 1); + this.curF = 0; this.generateTrigger(); } - else if(this.curF % this.randX > 16; @@ -393,19 +393,19 @@ THREE.SoftwareRenderer = function ( parameters ) { if ( !isTransparent ) { buffer[ colorOffset ] = (material.palette[cIndex] * tdata[tIndex]) >> 8; - buffer[ colorOffset + 1 ] = (material.palette[cIndex+1] * tdata[tIndex+1]) >> 8; - buffer[ colorOffset + 2 ] = (material.palette[cIndex+2] * tdata[tIndex+2]) >> 8; + buffer[ colorOffset + 1 ] = (material.palette[cIndex + 1] * tdata[tIndex + 1]) >> 8; + buffer[ colorOffset + 2 ] = (material.palette[cIndex + 2] * tdata[tIndex + 2]) >> 8; buffer[ colorOffset + 3 ] = material.opacity * 255; depthBuf[ offset ] = depth; } else { - var opaci = tdata[tIndex+3] * material.opacity; + var opaci = tdata[tIndex + 3] * material.opacity; var foreColor = ((material.palette[cIndex] * tdata[tIndex]) << 16) - + ((material.palette[cIndex+1] * tdata[tIndex+1]) << 8 ) - + (material.palette[cIndex+2] * tdata[tIndex+2]); + + ((material.palette[cIndex + 1] * tdata[tIndex + 1]) << 8 ) + + (material.palette[cIndex + 2] * tdata[tIndex + 2]); - if(opaci < 250) { + if (opaci < 250) { var backColor = buffer[ colorOffset ] << 24 + buffer[ colorOffset + 1 ] << 16 + buffer[ colorOffset + 2 ] << 8; - foreColor = foreColor * opaci + backColor * (1-opaci); + foreColor = foreColor * opaci + backColor * (1 - opaci); } buffer[ colorOffset ] = (foreColor & 0xff0000) >> 16; @@ -587,11 +587,11 @@ THREE.SoftwareRenderer = function ( parameters ) { bHasUV = true; tu1 = uv1.x; - tv1 = 1-uv1.y; + tv1 = 1 - uv1.y; tu2 = uv2.x; - tv2 = 1-uv2.y; + tv2 = 1 - uv2.y; tu3 = uv3.x; - tv3 = 1-uv3.y; + tv3 = 1 - uv3.y; } // Normal values @@ -660,9 +660,9 @@ THREE.SoftwareRenderer = function ( parameters ) { // Z interpolation setup var dz12 = z1 - z2, dz31 = z3 - z1; - var invDet = 1.0 / (dx12*dy31 - dx31*dy12); - var dzdx = (invDet * (dz12*dy31 - dz31*dy12)); // dz per one subpixel step in x - var dzdy = (invDet * (dz12*dx31 - dx12*dz31)); // dz per one subpixel step in y + var invDet = 1.0 / (dx12 * dy31 - dx31 * dy12); + var dzdx = (invDet * (dz12 * dy31 - dz31 * dy12)); // dz per one subpixel step in x + var dzdy = (invDet * (dz12 * dx31 - dx12 * dz31)); // dz per one subpixel step in y // Z at top/left corner of rast area @@ -678,11 +678,11 @@ THREE.SoftwareRenderer = function ( parameters ) { if ( bHasUV ) { // UV interpolation setup var dtu12 = tu1 - tu2, dtu31 = tu3 - tu1; - var dtudx = (invDet * (dtu12*dy31 - dtu31*dy12)); // dtu per one subpixel step in x - var dtudy = (invDet * (dtu12*dx31 - dx12*dtu31)); // dtu per one subpixel step in y + var dtudx = (invDet * (dtu12 * dy31 - dtu31 * dy12)); // dtu per one subpixel step in x + var dtudy = (invDet * (dtu12 * dx31 - dx12 * dtu31)); // dtu per one subpixel step in y var dtv12 = tv1 - tv2, dtv31 = tv3 - tv1; - dtvdx = (invDet * (dtv12*dy31 - dtv31*dy12)); // dtv per one subpixel step in x - dtvdy = (invDet * (dtv12*dx31 - dx12*dtv31)); // dtv per one subpixel step in y + dtvdx = (invDet * (dtv12 * dy31 - dtv31 * dy12)); // dtv per one subpixel step in x + dtvdy = (invDet * (dtv12 * dx31 - dx12 * dtv31)); // dtv per one subpixel step in y // UV at top/left corner of rast area cbtu = ( tu1 + (minXfixscale - x1) * dtudx + (minYfixscale - y1) * dtudy ); @@ -699,8 +699,8 @@ THREE.SoftwareRenderer = function ( parameters ) { if ( bHasNormal ) { // Normal interpolation setup var dnz12 = nz1 - nz2, dnz31 = nz3 - nz1; - var dnzdx = (invDet * (dnz12*dy31 - dnz31*dy12)); // dnz per one subpixel step in x - var dnzdy = (invDet * (dnz12*dx31 - dx12*dnz31)); // dnz per one subpixel step in y + var dnzdx = (invDet * (dnz12 * dy31 - dnz31 * dy12)); // dnz per one subpixel step in x + var dnzdy = (invDet * (dnz12 * dx31 - dx12 * dnz31)); // dnz per one subpixel step in y // Normal at top/left corner of rast area cbnz = ( nz1 + (minXfixscale - x1) * dnzdx + (minYfixscale - y1) * dnzdy ); @@ -716,14 +716,14 @@ THREE.SoftwareRenderer = function ( parameters ) { var nmin2 = 0, nmax2 = 0; var nmin3 = 0, nmax3 = 0; var nminz = 0, nmaxz = 0; - if (dx12 >= 0) nmax1 -= qm1*dx12; else nmin1 -= qm1*dx12; - if (dy12 >= 0) nmax1 -= qm1*dy12; else nmin1 -= qm1*dy12; - if (dx23 >= 0) nmax2 -= qm1*dx23; else nmin2 -= qm1*dx23; - if (dy23 >= 0) nmax2 -= qm1*dy23; else nmin2 -= qm1*dy23; - if (dx31 >= 0) nmax3 -= qm1*dx31; else nmin3 -= qm1*dx31; - if (dy31 >= 0) nmax3 -= qm1*dy31; else nmin3 -= qm1*dy31; - if (dzdx >= 0) nmaxz += qm1*dzdx; else nminz += qm1*dzdx; - if (dzdy >= 0) nmaxz += qm1*dzdy; else nminz += qm1*dzdy; + if (dx12 >= 0) nmax1 -= qm1 * dx12; else nmin1 -= qm1 * dx12; + if (dy12 >= 0) nmax1 -= qm1 * dy12; else nmin1 -= qm1 * dy12; + if (dx23 >= 0) nmax2 -= qm1 * dx23; else nmin2 -= qm1 * dx23; + if (dy23 >= 0) nmax2 -= qm1 * dy23; else nmin2 -= qm1 * dy23; + if (dx31 >= 0) nmax3 -= qm1 * dx31; else nmin3 -= qm1 * dx31; + if (dy31 >= 0) nmax3 -= qm1 * dy31; else nmin3 -= qm1 * dy31; + if (dzdx >= 0) nmaxz += qm1 * dzdx; else nminz += qm1 * dzdx; + if (dzdy >= 0) nmaxz += qm1 * dzdy; else nminz += qm1 * dzdy; // Loop through blocks var linestep = canvasWidth - q; @@ -894,7 +894,7 @@ THREE.SoftwareRenderer = function ( parameters ) { cxnz += dnzdx; } - offset++; + offset ++; } @@ -978,7 +978,7 @@ THREE.SoftwareRenderer = function ( parameters ) { cxnz += dnzdx; } - offset++; + offset ++; } @@ -1005,18 +1005,18 @@ THREE.SoftwareRenderer = function ( parameters ) { } // Advance to next row of blocks - cb1 += q*dx12; - cb2 += q*dx23; - cb3 += q*dx31; - cbz += q*dzdy; + cb1 += q * dx12; + cb2 += q * dx23; + cb3 += q * dx31; + cbz += q * dzdy; if ( bHasUV ) { - cbtu += q*dtudy; - cbtv += q*dtvdy; + cbtu += q * dtudy; + cbtv += q * dtvdy; } if ( bHasNormal ) { - cbnz += q*dnzdy; + cbnz += q * dnzdy; } } @@ -1081,7 +1081,7 @@ THREE.SoftwareRenderer.Texture = function() { this.fromImage = function( image ) { - if( !image || image.width <= 0 || image.height <= 0 ) + if ( !image || image.width <= 0 || image.height <= 0 ) return; if ( canvas === undefined ) { diff --git a/examples/js/renderers/plugins/DepthPassPlugin.js b/examples/js/renderers/plugins/DepthPassPlugin.js index 94e067cef783c7..08491865f44103 100644 --- a/examples/js/renderers/plugins/DepthPassPlugin.js +++ b/examples/js/renderers/plugins/DepthPassPlugin.js @@ -107,7 +107,7 @@ THREE.DepthPassPlugin = function () { // set object matrices & frustum culling _renderList.length = 0; - projectObject(scene,scene,camera); + projectObject(scene, scene, camera); // render regular objects @@ -189,7 +189,7 @@ THREE.DepthPassPlugin = function () { }; - function projectObject(scene, object,camera){ + function projectObject(scene, object,camera) { if ( object.visible ) { @@ -198,7 +198,7 @@ THREE.DepthPassPlugin = function () { if (webglObjects && (object.frustumCulled === false || _frustum.intersectsObject( object ) === true) ) { - for (var i = 0, l = webglObjects.length; i < l; i++){ + for (var i = 0, l = webglObjects.length; i < l; i ++) { var webglObject = webglObjects[i]; @@ -208,7 +208,7 @@ THREE.DepthPassPlugin = function () { } } - for(var i = 0, l = object.children.length; i < l; i++) { + for (var i = 0, l = object.children.length; i < l; i ++) { projectObject(scene, object.children[i], camera); } diff --git a/examples/js/shaders/BokehShader2.js b/examples/js/shaders/BokehShader2.js index c0963c3c3bab0d..3aa5125ecded15 100644 --- a/examples/js/shaders/BokehShader2.js +++ b/examples/js/shaders/BokehShader2.js @@ -44,7 +44,7 @@ THREE.BokehShader = { "pentagon": { type: "i", value: 0 }, "shaderFocus": { type: "i", value: 1 }, - "focusCoords": { type: "v2", value: new THREE.Vector2()}, + "focusCoords": { type: "v2", value: new THREE.Vector2() }, }, diff --git a/examples/js/shaders/ConvolutionShader.js b/examples/js/shaders/ConvolutionShader.js index c1b06c0b08b3ad..65ba07e21f9773 100644 --- a/examples/js/shaders/ConvolutionShader.js +++ b/examples/js/shaders/ConvolutionShader.js @@ -83,7 +83,7 @@ THREE.ConvolutionShader = { values = new Array( kernelSize ); sum = 0.0; - for ( i = 0; i < kernelSize; ++i ) { + for ( i = 0; i < kernelSize; ++ i ) { values[ i ] = gauss( i - halfWidth, sigma ); sum += values[ i ]; @@ -92,7 +92,7 @@ THREE.ConvolutionShader = { // normalize the kernel - for ( i = 0; i < kernelSize; ++i ) values[ i ] /= sum; + for ( i = 0; i < kernelSize; ++ i ) values[ i ] /= sum; return values; diff --git a/examples/js/shaders/FXAAShader.js b/examples/js/shaders/FXAAShader.js index 907cff3e5bf833..a949dbe15d8288 100644 --- a/examples/js/shaders/FXAAShader.js +++ b/examples/js/shaders/FXAAShader.js @@ -13,7 +13,7 @@ THREE.FXAAShader = { uniforms: { "tDiffuse": { type: "t", value: null }, - "resolution": { type: "v2", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } + "resolution": { type: "v2", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } }, diff --git a/examples/js/shaders/NormalDisplacementShader.js b/examples/js/shaders/NormalDisplacementShader.js index 7cde51f96e2c5e..e651743ce56c3e 100644 --- a/examples/js/shaders/NormalDisplacementShader.js +++ b/examples/js/shaders/NormalDisplacementShader.js @@ -350,7 +350,7 @@ THREE.NormalDisplacementShader = { " #if MAX_HEMI_LIGHTS > 0", " vec3 hemiDiffuse = vec3( 0.0 );", - " vec3 hemiSpecular = vec3( 0.0 );" , + " vec3 hemiSpecular = vec3( 0.0 );", " for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {", diff --git a/examples/js/shaders/TriangleBlurShader.js b/examples/js/shaders/TriangleBlurShader.js index c6a7eda6d00b14..69963fec6149c1 100644 --- a/examples/js/shaders/TriangleBlurShader.js +++ b/examples/js/shaders/TriangleBlurShader.js @@ -15,7 +15,7 @@ THREE.TriangleBlurShader = { uniforms : { "texture": { type: "t", value: null }, - "delta": { type: "v2", value:new THREE.Vector2( 1, 1 ) } + "delta": { type: "v2", value:new THREE.Vector2( 1, 1 ) } }, diff --git a/examples/js/utils/UVsDebug.js b/examples/js/utils/UVsDebug.js index a22f10f7ea8d4d..d98f3e9ff47c49 100644 --- a/examples/js/utils/UVsDebug.js +++ b/examples/js/utils/UVsDebug.js @@ -44,7 +44,7 @@ THREE.UVsDebug = function( geometry, size ) { ctx.fillStyle = 'rgba( 255, 255, 255, 1.0 )'; ctx.fillRect( 0, 0, width, height ); - for ( i = 0, il = uvs.length; i < il; i++ ) { + for ( i = 0, il = uvs.length; i < il; i ++ ) { uv = uvs[ i ]; @@ -54,7 +54,7 @@ THREE.UVsDebug = function( geometry, size ) { a.set( 0, 0 ); - for ( j = 0, jl = uv.length; j < jl; j++ ) { + for ( j = 0, jl = uv.length; j < jl; j ++ ) { u = uv[ j ]; @@ -95,7 +95,7 @@ THREE.UVsDebug = function( geometry, size ) { // label uv edge orders - for ( j = 0, jl = uv.length; j < jl; j++ ) { + for ( j = 0, jl = uv.length; j < jl; j ++ ) { u = uv[ j ]; b.addVectors( a, u ).divideScalar( 2 ); diff --git a/examples/js/wip/ProxyGeometry.js b/examples/js/wip/ProxyGeometry.js index 312301a8162544..b4725e53b34c85 100644 --- a/examples/js/wip/ProxyGeometry.js +++ b/examples/js/wip/ProxyGeometry.js @@ -56,17 +56,17 @@ Object.defineProperties(THREE.ProxyGeometry.prototype, { verticesNeedUpdate: { enumerable: true, - get: function() { if (this.attributes[ 'position' ]) return this.attributes[ 'position' ].needsUpdate; } , + get: function() { if (this.attributes[ 'position' ]) return this.attributes[ 'position' ].needsUpdate; }, set: function(v) { if (this.attributes[ 'position' ]) this.attributes[ 'position' ].needsUpdate = v; } }, colorsNeedUpdate: { enumerable: true, - get: function() { if (this.attributes[ 'color' ]) return this.attributes[ 'color' ].needsUpdate; } , + get: function() { if (this.attributes[ 'color' ]) return this.attributes[ 'color' ].needsUpdate; }, set: function(v) { if (this.attributes[ 'color' ]) this.attributes[ 'color' ].needsUpdate = v; } }, normalsNeedUpdate: { enumerable: true, - get: function() { if (this.attributes[ 'normal' ]) return this.attributes[ 'normal' ].needsUpdate; } , + get: function() { if (this.attributes[ 'normal' ]) return this.attributes[ 'normal' ].needsUpdate; }, set: function(v) { if (this.attributes[ 'normal' ]) this.attributes[ 'normal' ].needsUpdate = v; } }, }); @@ -95,7 +95,7 @@ THREE.ProxyGeometry.prototype.createVertexProxies = function(values) { if (values) { - for (var i = 0; i < values.length; i++) { + for (var i = 0; i < values.length; i ++) { this.vertices[i].copy(values[i]); @@ -166,7 +166,7 @@ THREE.ProxyGeometry.prototype.createFaceProxies = function(values) { for ( var i = 0, l = positionarray.length / 3; i < l; i += 3 ) { var o = i * 3; - var v1 = i, v2 = i+1, v3 = i+2; + var v1 = i, v2 = i + 1, v3 = i + 2; var face = new THREE.ProxyFace3( v1, v2, v3 ); faces.push(face); @@ -179,7 +179,7 @@ THREE.ProxyGeometry.prototype.createFaceProxies = function(values) { if (values) { - for (var i = 0, l = values.length; i < l; i++) { + for (var i = 0, l = values.length; i < l; i ++) { var f = faces[i], v = values[i]; @@ -222,7 +222,7 @@ THREE.ProxyGeometry.prototype.createFaceVertexNormalProxies = function(values) { var normalarray = this.attributes[ 'normal' ].array; - for (var i = 0, l = this.faces.length; i < l; i++) { + for (var i = 0, l = this.faces.length; i < l; i ++) { var f = this.faces[i]; @@ -240,14 +240,14 @@ THREE.ProxyGeometry.prototype.createFaceVertexNormalProxies = function(values) { if (values) { - for (var i = 0, l = values.length; i < l; i++) { + for (var i = 0, l = values.length; i < l; i ++) { var f = this.faces[i], v = values[i]; if (v.vertexNormals.length > 0) { - for (var j = 0, l2 = f.vertexNormals.length; j < l2; j++) { + for (var j = 0, l2 = f.vertexNormals.length; j < l2; j ++) { f.vertexNormals[j].copy(v.vertexNormals[j]); @@ -271,7 +271,7 @@ THREE.ProxyGeometry.prototype.createFaceVertexColorProxies = function(values) { var colorarray = this.attributes[ 'color' ].array; - for (var i = 0, l = this.faces.length; i < l; i++) { + for (var i = 0, l = this.faces.length; i < l; i ++) { var f = this.faces[i]; if ( this.attributes[ 'index' ] ) { @@ -298,12 +298,12 @@ THREE.ProxyGeometry.prototype.createFaceVertexColorProxies = function(values) { if (values) { - for (var i = 0, l = values.length; i < l; i++) { + for (var i = 0, l = values.length; i < l; i ++) { var f = this.faces[i], v = values[i]; - for (var j = 0, l2 = f.vertexColors.length; j < l2; j++) { + for (var j = 0, l2 = f.vertexColors.length; j < l2; j ++) { if (v.vertexColors.length > 0) { @@ -329,7 +329,7 @@ THREE.ProxyGeometry.prototype.createFaceVertexTangentProxies = function(values) var tangentarray = this.attributes[ 'tangent' ].array; - for (var i = 0, l = this.faces.length; i < l; i++) { + for (var i = 0, l = this.faces.length; i < l; i ++) { var f = this.faces[i]; @@ -346,14 +346,14 @@ THREE.ProxyGeometry.prototype.createFaceVertexTangentProxies = function(values) if (values) { - for (var i = 0, l = values.length; i < l; i++) { + for (var i = 0, l = values.length; i < l; i ++) { var f = this.faces[i], v = values[i]; if (v.vertexTangents.length > 0) { - for (var j = 0, l2 = f.vertexTangents.length; j < l2; j++) { + for (var j = 0, l2 = f.vertexTangents.length; j < l2; j ++) { f.vertexTangents[j].copy(v.vertexTangents[j]); @@ -384,7 +384,7 @@ THREE.ProxyGeometry.prototype.createUvProxies = function(values) { var faces = this.faces; var uvarray = this.attributes[ 'uv' ].array; - for (var i = 0, l = faces.length; i < l; i++) { + for (var i = 0, l = faces.length; i < l; i ++) { var f = faces[i]; this.faceVertexUvs[0][i] = []; @@ -408,9 +408,9 @@ THREE.ProxyGeometry.prototype.createUvProxies = function(values) { if (values) { - for (var i = 0, l = values.length; i < l; i++) { + for (var i = 0, l = values.length; i < l; i ++) { - for (var j = 0, l2 = values[i].length; j < l2; j++) { + for (var j = 0, l2 = values[i].length; j < l2; j ++) { var uv = values[i][j]; this.faceVertexUvs[0][i][j].copy(uv); @@ -445,7 +445,7 @@ THREE.ProxyGeometry.prototype.createSkinIndexProxies = function(values) { if (values) { - for (var i = 0; i < values.length; i++) { + for (var i = 0; i < values.length; i ++) { this.skinIndices[i].copy(values[i]); @@ -477,7 +477,7 @@ THREE.ProxyGeometry.prototype.createSkinWeightProxies = function(values) { if (values) { - for (var i = 0; i < values.length; i++) { + for (var i = 0; i < values.length; i ++) { this.skinWeights[i].copy(values[i]); @@ -509,7 +509,7 @@ THREE.ProxyGeometry.prototype.createColorProxies = function(values) { if (values) { - for (var i = 0; i < values.length; i++) { + for (var i = 0; i < values.length; i ++) { this.colors[i].copy(values[i]); @@ -585,7 +585,7 @@ THREE.ProxyGeometry.prototype.mergeVertices = function () { // have to remove them from the geometry. var faceIndicesToRemove = []; - for( i = 0, il = this.faces.length; i < il; i ++ ) { + for ( i = 0, il = this.faces.length; i < il; i ++ ) { face = this.faces[ i ]; diff --git a/examples/js/wip/benchmark/BoxGeometry2.js b/examples/js/wip/benchmark/BoxGeometry2.js index 32f4eb29e9a3cf..75a351fd7c0dfe 100644 --- a/examples/js/wip/benchmark/BoxGeometry2.js +++ b/examples/js/wip/benchmark/BoxGeometry2.js @@ -86,9 +86,9 @@ THREE.BoxGeometry2 = function ( width, height, depth, widthSegments, heightSegme } - for ( iy = 0; iy < gridY; iy++ ) { + for ( iy = 0; iy < gridY; iy ++ ) { - for ( ix = 0; ix < gridX; ix++ ) { + for ( ix = 0; ix < gridX; ix ++ ) { var a = ix + gridX1 * iy; var b = ix + gridX1 * ( iy + 1 ); diff --git a/examples/js/wip/benchmark/Geometry4.js b/examples/js/wip/benchmark/Geometry4.js index 8a4e327557bb70..b9b055abaa607d 100644 --- a/examples/js/wip/benchmark/Geometry4.js +++ b/examples/js/wip/benchmark/Geometry4.js @@ -24,7 +24,7 @@ THREE.VectorArrayProxy = function(attribute) { this.attribute = attribute; - for (var i = 0, l = this.attribute.array.length / this.attribute.itemSize; i < l; i++) { + for (var i = 0, l = this.attribute.array.length / this.attribute.itemSize; i < l; i ++) { Object.defineProperty(this, i, { get: (function(i) { return function() { return this.getValue(i); }})(i), diff --git a/examples/js/wip/proxies/MultiColor.js b/examples/js/wip/proxies/MultiColor.js index 76800f5dc749b9..2a708bab26580e 100644 --- a/examples/js/wip/proxies/MultiColor.js +++ b/examples/js/wip/proxies/MultiColor.js @@ -12,7 +12,7 @@ THREE.MultiColor.prototype.constructor = THREE.MultiColor; THREE.MultiColor.prototype.setAll = function(axis, value) { - for (var i = 0, l = this.links.length; i < l; i++) { + for (var i = 0, l = this.links.length; i < l; i ++) { this.links[i][axis] = value; diff --git a/examples/js/wip/proxies/MultiVector3.js b/examples/js/wip/proxies/MultiVector3.js index 837d25ab5d7abf..62f4a21f77232c 100644 --- a/examples/js/wip/proxies/MultiVector3.js +++ b/examples/js/wip/proxies/MultiVector3.js @@ -12,7 +12,7 @@ THREE.MultiVector3.prototype.constructor = THREE.MultiVector3; THREE.MultiVector3.prototype.setAll = function(axis, value) { - for (var i = 0, l = this.links.length; i < l; i++) { + for (var i = 0, l = this.links.length; i < l; i ++) { this.links[i][axis] = value; diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 4842bd410ca0c4..3afb965aca5383 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -302,7 +302,7 @@ THREE.Object3D.prototype = { if ( arguments.length > 1 ) { - for ( var i = 0; i < arguments.length; i++ ) { + for ( var i = 0; i < arguments.length; i ++ ) { this.add( arguments[ i ] ); @@ -346,7 +346,7 @@ THREE.Object3D.prototype = { if ( arguments.length > 1 ) { - for ( var i = 0; i < arguments.length; i++ ) { + for ( var i = 0; i < arguments.length; i ++ ) { this.remove( arguments[ i ] ); diff --git a/src/extras/FontUtils.js b/src/extras/FontUtils.js index 2dbf79d5684f63..b3f1e56db8590d 100644 --- a/src/extras/FontUtils.js +++ b/src/extras/FontUtils.js @@ -156,7 +156,7 @@ THREE.FontUtils = { x = outline[ i ++ ] * scaleX + offset; y = outline[ i ++ ] * scaleY; - path.lineTo( x,y ); + path.lineTo( x, y ); break; case 'q': @@ -367,7 +367,7 @@ THREE.FontUtils.generateShapes = function ( text, parameters ) { /* remove v from the remaining polygon */ - for ( s = v, t = v + 1; t < nv; s++, t++ ) { + for ( s = v, t = v + 1; t < nv; s ++, t ++ ) { verts[ s ] = verts[ t ]; diff --git a/src/extras/ImageUtils.js b/src/extras/ImageUtils.js index 48cb94f7fd994d..b841603a56ca2b 100644 --- a/src/extras/ImageUtils.js +++ b/src/extras/ImageUtils.js @@ -144,7 +144,7 @@ THREE.ImageUtils = { points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] ); points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] ); points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] ); - points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] ); + points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] ); points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] ); points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] ); points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] ); diff --git a/src/extras/animation/Animation.js b/src/extras/animation/Animation.js index aeaf5823e515c3..55ab0786f5d919 100644 --- a/src/extras/animation/Animation.js +++ b/src/extras/animation/Animation.js @@ -28,7 +28,7 @@ THREE.Animation.prototype.keyTypes = [ "pos", "rot", "scl" ]; THREE.Animation.prototype.play = function ( startTime, weight ) { this.currentTime = startTime !== undefined ? startTime : 0; - this.weight = weight !== undefined ? weight: 1; + this.weight = weight !== undefined ? weight : 1; this.isPlaying = true; @@ -119,7 +119,7 @@ THREE.Animation.prototype.resetBlendWeights = function () { }; -THREE.Animation.prototype.update = (function(){ +THREE.Animation.prototype.update = (function() { var points = []; var target = new THREE.Vector3(); diff --git a/src/extras/core/Curve.js b/src/extras/core/Curve.js index 3998d226c8facc..5183b2b2a4db01 100644 --- a/src/extras/core/Curve.js +++ b/src/extras/core/Curve.js @@ -107,7 +107,7 @@ THREE.Curve.prototype.getLength = function () { THREE.Curve.prototype.getLengths = function ( divisions ) { - if ( ! divisions ) divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions): 200; + if ( ! divisions ) divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions) : 200; if ( this.cacheArcLengths && ( this.cacheArcLengths.length == divisions + 1 ) @@ -222,7 +222,7 @@ THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) { // add that fractional amount to t - var t = ( i + segmentFraction ) / ( il -1 ); + var t = ( i + segmentFraction ) / ( il - 1 ); return t; @@ -281,8 +281,8 @@ THREE.Curve.Utils = { tangentCubicBezier: function (t, p0, p1, p2, p3 ) { return - 3 * p0 * (1 - t) * (1 - t) + - 3 * p1 * (1 - t) * (1-t) - 6 *t *p1 * (1-t) + - 6 * t * p2 * (1-t) - 3 * t * t * p2 + + 3 * p1 * (1 - t) * (1 - t) - 6 * t * p1 * (1 - t) + + 6 * t * p2 * (1 - t) - 3 * t * t * p2 + 3 * t * t * p3; }, diff --git a/src/extras/core/CurvePath.js b/src/extras/core/CurvePath.js index 3cd14fe81926cc..6fd68346ad9fc9 100644 --- a/src/extras/core/CurvePath.js +++ b/src/extras/core/CurvePath.js @@ -36,7 +36,7 @@ THREE.CurvePath.prototype.closePath = function() { // and verify for vector3 (needs to implement equals) // Add a line curve if start and end of lines are not connected var startPoint = this.curves[0].getPoint(0); - var endPoint = this.curves[this.curves.length-1].getPoint(1); + var endPoint = this.curves[this.curves.length - 1].getPoint(1); if (! startPoint.equals(endPoint)) { this.curves.push( new THREE.LineCurve(endPoint, startPoint) ); diff --git a/src/extras/core/Path.js b/src/extras/core/Path.js index 6e40375f96c2fd..50917c87b9b169 100644 --- a/src/extras/core/Path.js +++ b/src/extras/core/Path.js @@ -228,7 +228,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) { action = item.action; args = item.args; - switch( action ) { + switch ( action ) { case THREE.PathActions.MOVE_TO: @@ -520,7 +520,7 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) { // with the horizontal line through inPt, left of inPt // not counting lowerY endpoints of edges and whole edges on that line var inside = false; - for( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { + for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { var edgeLowPt = inPolygon[ p ]; var edgeHighPt = inPolygon[ q ]; diff --git a/src/extras/core/Shape.js b/src/extras/core/Shape.js index 568e9dec330f9a..de3bfbd4ce695b 100644 --- a/src/extras/core/Shape.js +++ b/src/extras/core/Shape.js @@ -173,16 +173,16 @@ THREE.Shape.Utils = { if ( perpSeg2 == 0 ) { if ( ( inExcludeAdjacentSegs ) && ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return []; - return [ inSeg1Pt1 ]; + return [ inSeg1Pt1 ]; } if ( perpSeg2 == limit ) { if ( ( inExcludeAdjacentSegs ) && ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return []; - return [ inSeg1Pt2 ]; + return [ inSeg1Pt2 ]; } // intersection at endpoint of segment#2? - if ( perpSeg1 == 0 ) return [ inSeg2Pt1 ]; - if ( perpSeg1 == limit ) return [ inSeg2Pt2 ]; + if ( perpSeg1 == 0 ) return [ inSeg2Pt1 ]; + if ( perpSeg1 == limit ) return [ inSeg2Pt2 ]; // return real intersection point var factorSeg1 = perpSeg2 / limit; @@ -200,17 +200,17 @@ THREE.Shape.Utils = { if ( seg1Pt && seg2Pt ) { if ( (inSeg1Pt1.x != inSeg2Pt1.x) || (inSeg1Pt1.y != inSeg2Pt1.y) ) return []; // they are distinct points - return [ inSeg1Pt1 ]; // they are the same point + return [ inSeg1Pt1 ]; // they are the same point } // segment#1 is a single point if ( seg1Pt ) { if (! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) ) return []; // but not in segment#2 - return [ inSeg1Pt1 ]; + return [ inSeg1Pt1 ]; } // segment#2 is a single point if ( seg2Pt ) { if (! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) ) return []; // but not in segment#1 - return [ inSeg2Pt1 ]; + return [ inSeg2Pt1 ]; } // they are collinear segments, which might overlap @@ -341,7 +341,7 @@ THREE.Shape.Utils = { // checks for intersections with shape edges var sIdx, nextIdx, intersection; for ( sIdx = 0; sIdx < shape.length; sIdx ++ ) { - nextIdx = sIdx+1; nextIdx %= shape.length; + nextIdx = sIdx + 1; nextIdx %= shape.length; intersection = intersect_segments_2D( inShapePt, inHolePt, shape[sIdx], shape[nextIdx], true ); if ( intersection.length > 0 ) return true; } @@ -358,7 +358,7 @@ THREE.Shape.Utils = { for ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) { chkHole = holes[indepHoles[ihIdx]]; for ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) { - nextIdx = hIdx+1; nextIdx %= chkHole.length; + nextIdx = hIdx + 1; nextIdx %= chkHole.length; intersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[hIdx], chkHole[nextIdx], true ); if ( intersection.length > 0 ) return true; } @@ -410,12 +410,12 @@ THREE.Shape.Utils = { if ( intersectsHoleEdge( shapePt, holePt ) ) continue; holeIndex = h2; - indepHoles.splice(h,1); + indepHoles.splice(h, 1); - tmpShape1 = shape.slice( 0, shapeIndex+1 ); + tmpShape1 = shape.slice( 0, shapeIndex + 1 ); tmpShape2 = shape.slice( shapeIndex ); tmpHole1 = hole.slice( holeIndex ); - tmpHole2 = hole.slice( 0, holeIndex+1 ); + tmpHole2 = hole.slice( 0, holeIndex + 1 ); shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 ); diff --git a/src/extras/curves/SplineCurve.js b/src/extras/curves/SplineCurve.js index f79532f75ec63b..e695090fe9655a 100644 --- a/src/extras/curves/SplineCurve.js +++ b/src/extras/curves/SplineCurve.js @@ -21,8 +21,8 @@ THREE.SplineCurve.prototype.getPoint = function ( t ) { var point0 = points[ intPoint == 0 ? intPoint : intPoint - 1 ] var point1 = points[ intPoint ] - var point2 = points[ intPoint > points.length - 2 ? points.length -1 : intPoint + 1 ] - var point3 = points[ intPoint > points.length - 3 ? points.length -1 : intPoint + 2 ] + var point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ] + var point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ] var vector = new THREE.Vector2(); diff --git a/src/extras/geometries/ExtrudeGeometry.js b/src/extras/geometries/ExtrudeGeometry.js index b511496a964192..e1e11c7ad16c8b 100644 --- a/src/extras/geometries/ExtrudeGeometry.js +++ b/src/extras/geometries/ExtrudeGeometry.js @@ -163,7 +163,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var contour = vertices; // vertices has all points but contour has only points of circumference - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { ahole = holes[ h ]; @@ -296,7 +296,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var pt_j = contour[ j ]; var pt_k = contour[ k ]; - contourMovements[ i ]= getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); + contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); } @@ -314,7 +314,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { if ( k === il ) k = 0; // (j)---(i)---(k) - oneHoleMovements[ i ]= getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); + oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); } @@ -333,7 +333,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { z = bevelThickness * ( 1 - t ); //z = bevelThickness * t; - bs = bevelSize * ( Math.sin ( t * Math.PI/2 ) ) ; // curved + bs = bevelSize * ( Math.sin ( t * Math.PI / 2 ) ) ; // curved //bs = bevelSize * t ; // linear // contract shape @@ -433,7 +433,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { t = b / bevelSegments; z = bevelThickness * ( 1 - t ); //bs = bevelSize * ( 1-Math.sin ( ( 1 - t ) * Math.PI/2 ) ); - bs = bevelSize * Math.sin ( t * Math.PI/2 ) ; + bs = bevelSize * Math.sin ( t * Math.PI / 2 ) ; // contract shape @@ -496,7 +496,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { for ( i = 0; i < flen; i ++ ) { face = faces[ i ]; - f3( face[ 2 ]+ offset, face[ 1 ]+ offset, face[ 0 ] + offset ); + f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset ); } @@ -543,7 +543,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { sidewalls( contour, layeroffset ); layeroffset += contour.length; - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { ahole = holes[ h ]; sidewalls( ahole, layeroffset ); @@ -560,7 +560,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var j, k; i = contour.length; - while ( --i >= 0 ) { + while ( -- i >= 0 ) { j = i; k = i - 1; diff --git a/src/extras/geometries/TubeGeometry.js b/src/extras/geometries/TubeGeometry.js index 581c9d541d223a..6874642ffde786 100644 --- a/src/extras/geometries/TubeGeometry.js +++ b/src/extras/geometries/TubeGeometry.js @@ -252,17 +252,17 @@ THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { for ( i = 1; i < numpoints; i ++ ) { - normals[ i ] = normals[ i-1 ].clone(); + normals[ i ] = normals[ i - 1 ].clone(); - binormals[ i ] = binormals[ i-1 ].clone(); + binormals[ i ] = binormals[ i - 1 ].clone(); - vec.crossVectors( tangents[ i-1 ], tangents[ i ] ); + vec.crossVectors( tangents[ i - 1 ], tangents[ i ] ); if ( vec.length() > epsilon ) { vec.normalize(); - theta = Math.acos( THREE.Math.clamp( tangents[ i-1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors + theta = Math.acos( THREE.Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); @@ -277,10 +277,10 @@ THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { if ( closed ) { - theta = Math.acos( THREE.Math.clamp( normals[ 0 ].dot( normals[ numpoints-1 ] ), - 1, 1 ) ); + theta = Math.acos( THREE.Math.clamp( normals[ 0 ].dot( normals[ numpoints - 1 ] ), - 1, 1 ) ); theta /= ( numpoints - 1 ); - if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ numpoints-1 ] ) ) > 0 ) { + if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ numpoints - 1 ] ) ) > 0 ) { theta = - theta; diff --git a/src/lights/DirectionalLight.js b/src/lights/DirectionalLight.js index 20c38e095c45d0..f78192e8f106b3 100644 --- a/src/lights/DirectionalLight.js +++ b/src/lights/DirectionalLight.js @@ -47,7 +47,7 @@ THREE.DirectionalLight = function ( color, intensity ) { this.shadowCascadeHeight = [ 512, 512, 512 ]; this.shadowCascadeNearZ = [ - 1.000, 0.990, 0.998 ]; - this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ]; + this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ]; this.shadowCascadeArray = []; diff --git a/src/loaders/BinaryTextureLoader.js b/src/loaders/BinaryTextureLoader.js index b9266f57a6a1e8..913a5e318f49cb 100644 --- a/src/loaders/BinaryTextureLoader.js +++ b/src/loaders/BinaryTextureLoader.js @@ -34,7 +34,7 @@ THREE.BinaryTextureLoader.prototype = { texture.image = texData.image; - } else if ( undefined !== texData.data ){ + } else if ( undefined !== texData.data ) { texture.image.width = texData.width; texture.image.height = texData.height; diff --git a/src/math/Ray.js b/src/math/Ray.js index 8ebc86373faf21..253de466c6c076 100644 --- a/src/math/Ray.js +++ b/src/math/Ray.js @@ -345,7 +345,7 @@ THREE.Ray.prototype = { }(), - intersectBox: function ( box , optionalTarget ) { + intersectBox: function ( box, optionalTarget ) { // http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-box-intersection/ diff --git a/src/math/Sphere.js b/src/math/Sphere.js index cadacfe746749b..0f47f548f7b433 100644 --- a/src/math/Sphere.js +++ b/src/math/Sphere.js @@ -26,7 +26,7 @@ THREE.Sphere.prototype = { var box = new THREE.Box3(); - return function ( points, optionalCenter ) { + return function ( points, optionalCenter ) { var center = this.center; diff --git a/src/objects/LensFlare.js b/src/objects/LensFlare.js index 2598207e087423..0f83750cdd9a42 100644 --- a/src/objects/LensFlare.js +++ b/src/objects/LensFlare.js @@ -12,7 +12,7 @@ THREE.LensFlare = function ( texture, size, distance, blending, color ) { this.positionScreen = new THREE.Vector3(); this.customUpdateCallback = undefined; - if( texture !== undefined ) { + if ( texture !== undefined ) { this.add( texture, size, distance, blending, color ); @@ -64,7 +64,7 @@ THREE.LensFlare.prototype.updateLensFlares = function () { var vecX = - this.positionScreen.x * 2; var vecY = - this.positionScreen.y * 2; - for( f = 0; f < fl; f ++ ) { + for ( f = 0; f < fl; f ++ ) { flare = this.lensFlares[ f ]; diff --git a/src/objects/Line.js b/src/objects/Line.js index 89a324d55ff6bd..e622b31f45601c 100644 --- a/src/objects/Line.js +++ b/src/objects/Line.js @@ -72,7 +72,7 @@ THREE.Line.prototype.raycast = ( function () { } - for ( var oi = 0; oi < offsets.length; oi++){ + for ( var oi = 0; oi < offsets.length; oi ++) { var start = offsets[ oi ].start; var count = offsets[ oi ].count; diff --git a/src/objects/Mesh.js b/src/objects/Mesh.js index 573b993f7610bc..7467affca904a2 100644 --- a/src/objects/Mesh.js +++ b/src/objects/Mesh.js @@ -90,7 +90,7 @@ THREE.Mesh.prototype.raycast = ( function () { if ( geometry.boundingBox !== null ) { - if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) { + if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) { return; @@ -121,7 +121,7 @@ THREE.Mesh.prototype.raycast = ( function () { } - for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) { + for ( var oi = 0, ol = offsets.length; oi < ol; ++ oi ) { var start = offsets[ oi ].start; var count = offsets[ oi ].count; diff --git a/src/objects/PointCloud.js b/src/objects/PointCloud.js index a05a186f3ae0dd..e47fe5e5faed37 100644 --- a/src/objects/PointCloud.js +++ b/src/objects/PointCloud.js @@ -91,7 +91,7 @@ THREE.PointCloud.prototype.raycast = ( function () { } - for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) { + for ( var oi = 0, ol = offsets.length; oi < ol; ++ oi ) { var start = offsets[ oi ].start; var count = offsets[ oi ].count; diff --git a/src/objects/SkinnedMesh.js b/src/objects/SkinnedMesh.js index 8f2ac780e8b737..7c692c18bfca6e 100644 --- a/src/objects/SkinnedMesh.js +++ b/src/objects/SkinnedMesh.js @@ -25,7 +25,7 @@ THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) { var bone, gbone, p, q, s; - for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++b ) { + for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) { gbone = this.geometry.bones[ b ]; @@ -52,7 +52,7 @@ THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) { } - for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++b ) { + for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) { gbone = this.geometry.bones[ b ]; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 5b34e299a1e1d8..c6f7033656a31e 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -356,7 +356,7 @@ THREE.WebGLRenderer = function ( parameters ) { var formats = _gl.getParameter( _gl.COMPRESSED_TEXTURE_FORMATS ); - for ( var i = 0; i < formats.length; i ++ ){ + for ( var i = 0; i < formats.length; i ++ ) { array.push( formats[ i ] ); diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 99fd2bf915eab6..7e50e996ff2a0f 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -278,7 +278,7 @@ THREE.WebGLProgram = ( function () { '#define MAX_SHADOWS ' + parameters.maxShadows, - parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest: '', + parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '', _this.gammaInput ? '#define GAMMA_INPUT' : '', _this.gammaOutput ? '#define GAMMA_OUTPUT' : '', diff --git a/src/renderers/webgl/plugins/ShadowMapPlugin.js b/src/renderers/webgl/plugins/ShadowMapPlugin.js index 3755aebdc1fd82..ed7d7b88487a4d 100644 --- a/src/renderers/webgl/plugins/ShadowMapPlugin.js +++ b/src/renderers/webgl/plugins/ShadowMapPlugin.js @@ -348,7 +348,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje }; - function projectObject( scene, object, shadowCamera ){ + function projectObject( scene, object, shadowCamera ) { if ( object.visible ) { From 4ce1d34951d7767f67b53ec825432ead8fe568b7 Mon Sep 17 00:00:00 2001 From: daron1337 Date: Thu, 19 Feb 2015 14:45:07 +0100 Subject: [PATCH 161/333] Added cylindricalRotation feature to TrackballControls. Updated the related example --- examples/js/controls/TrackballControls.js | 191 ++++++++++++++++++---- examples/misc_controls_trackball.html | 24 ++- 2 files changed, 181 insertions(+), 34 deletions(-) diff --git a/examples/js/controls/TrackballControls.js b/examples/js/controls/TrackballControls.js index 7be25a137b5db7..198987e9161c6d 100644 --- a/examples/js/controls/TrackballControls.js +++ b/examples/js/controls/TrackballControls.js @@ -1,6 +1,8 @@ /** * @author Eberhard Graether / http://egraether.com/ * @author Mark Lundin / http://mark-lundin.com + * @author Simone Manini / http://daron1337.github.io + * @author Luca Antiga / http://lantiga.github.io */ THREE.TrackballControls = function ( object, domElement ) { @@ -28,6 +30,7 @@ THREE.TrackballControls = function ( object, domElement ) { this.staticMoving = false; this.dynamicDampingFactor = 0.2; + this.cylindricalRotation = true; this.minDistance = 0; this.maxDistance = Infinity; @@ -50,6 +53,12 @@ THREE.TrackballControls = function ( object, domElement ) { _rotateStart = new THREE.Vector3(), _rotateEnd = new THREE.Vector3(), + _movePrev = new THREE.Vector2(), + _moveCurr = new THREE.Vector2(), + + _lastAxis = new THREE.Vector3(), + _lastAngle = 0, + _zoomStart = new THREE.Vector2(), _zoomEnd = new THREE.Vector2(), @@ -124,6 +133,22 @@ THREE.TrackballControls = function ( object, domElement ) { }() ); + var getMouseOnCircle = ( function () { + + var vector = new THREE.Vector2(); + + return function ( pageX, pageY ) { + + vector.set( + ( ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / ( _this.screen.width * 0.5 ) ), + ( ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / ( _this.screen.height * 0.5 ) / _this.screen.width * _this.screen.height ) + ); + + return vector; + }; + + }() ); + var getMouseProjectionOnBall = ( function () { var vector = new THREE.Vector3(); @@ -133,8 +158,8 @@ THREE.TrackballControls = function ( object, domElement ) { return function ( pageX, pageY ) { mouseOnBall.set( - ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5), - ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / (_this.screen.height*.5), + ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / ( _this.screen.width * 0.5 ), + ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / ( _this.screen.height * 0.5 ), 0.0 ); @@ -148,8 +173,8 @@ THREE.TrackballControls = function ( object, domElement ) { } else { - mouseOnBall.z = .5 / length; - + mouseOnBall.z = 0.5 / length; + } } else if ( length > 1.0 ) { @@ -164,7 +189,7 @@ THREE.TrackballControls = function ( object, domElement ) { _eye.copy( _this.object.position ).sub( _this.target ); - vector.copy( _this.object.up ).setLength( mouseOnBall.y ) + vector.copy( _this.object.up ).setLength( mouseOnBall.y ); vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) ); vector.add( _eye.setLength( mouseOnBall.z ) ); @@ -174,56 +199,111 @@ THREE.TrackballControls = function ( object, domElement ) { }() ); + this.rotateCamera = (function(){ var axis = new THREE.Vector3(), - quaternion = new THREE.Quaternion(); - + quaternion = new THREE.Quaternion(), + eyeDirection = new THREE.Vector3(), + objectUpDirection = new THREE.Vector3(), + objectSidewaysDirection = new THREE.Vector3(), + moveDirection = new THREE.Vector3(), + angle; return function () { - var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() ); + if ( _this.cylindricalRotation ) { - if ( angle ) { + moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 ); + angle = moveDirection.length(); - axis.crossVectors( _rotateStart, _rotateEnd ).normalize(); + if ( angle ) { - angle *= _this.rotateSpeed; + _eye.copy( _this.object.position ).sub( _this.target ); - quaternion.setFromAxisAngle( axis, -angle ); + eyeDirection.copy( _eye ).normalize(); + objectUpDirection.copy( _this.object.up ).normalize(); + objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize(); - _eye.applyQuaternion( quaternion ); - _this.object.up.applyQuaternion( quaternion ); + objectUpDirection.setLength( _moveCurr.y - _movePrev.y ); + objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x ); - _rotateEnd.applyQuaternion( quaternion ); + moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) ); - if ( _this.staticMoving ) { + axis.crossVectors( moveDirection, _eye ).normalize(); - _rotateStart.copy( _rotateEnd ); + angle *= _this.rotateSpeed; + quaternion.setFromAxisAngle( axis, angle ); - } else { + _eye.applyQuaternion( quaternion ); + _this.object.up.applyQuaternion( quaternion ); + + _lastAxis.copy( axis ); + _lastAngle = angle; + + } + else if ( !_this.staticMoving && _lastAngle ) { + + _lastAngle *= Math.sqrt( 1.0 - _this.dynamicDampingFactor ); + _eye.copy( _this.object.position ).sub( _this.target ); + quaternion.setFromAxisAngle( _lastAxis, _lastAngle ); + _eye.applyQuaternion( quaternion ); + _this.object.up.applyQuaternion( quaternion ); + + } + + _movePrev.copy( _moveCurr ); + + } else { + + angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() ); + + if ( angle ) { + + axis.crossVectors( _rotateStart, _rotateEnd ).normalize(); + + angle *= _this.rotateSpeed; + + quaternion.setFromAxisAngle( axis, -angle ); + + _eye.applyQuaternion( quaternion ); + _this.object.up.applyQuaternion( quaternion ); + + _rotateEnd.applyQuaternion( quaternion ); + + if ( _this.staticMoving ) { + + _rotateStart.copy( _rotateEnd ); + + } else { + + quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) ); + _rotateStart.applyQuaternion( quaternion ); - quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) ); - _rotateStart.applyQuaternion( quaternion ); + } } } - } + + }; }()); + this.zoomCamera = function () { + var factor; + if ( _state === STATE.TOUCH_ZOOM_PAN ) { - var factor = _touchZoomDistanceStart / _touchZoomDistanceEnd; + factor = _touchZoomDistanceStart / _touchZoomDistanceEnd; _touchZoomDistanceStart = _touchZoomDistanceEnd; _eye.multiplyScalar( factor ); } else { - var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed; + factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed; if ( factor !== 1.0 && factor > 0.0 ) { @@ -276,7 +356,7 @@ THREE.TrackballControls = function ( object, domElement ) { } } - } + }; }()); @@ -412,8 +492,17 @@ THREE.TrackballControls = function ( object, domElement ) { if ( _state === STATE.ROTATE && !_this.noRotate ) { - _rotateStart.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) ); - _rotateEnd.copy( _rotateStart ); + if ( _this.cylindricalRotation ) { + + _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); + _movePrev.copy(_moveCurr); + + } else { + + _rotateStart.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) ); + _rotateEnd.copy( _rotateStart ); + + } } else if ( _state === STATE.ZOOM && !_this.noZoom ) { @@ -423,7 +512,7 @@ THREE.TrackballControls = function ( object, domElement ) { } else if ( _state === STATE.PAN && !_this.noPan ) { _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - _panEnd.copy(_panStart) + _panEnd.copy(_panStart); } @@ -443,7 +532,16 @@ THREE.TrackballControls = function ( object, domElement ) { if ( _state === STATE.ROTATE && !_this.noRotate ) { - _rotateEnd.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) ); + if ( _this.cylindricalRotation ) { + + _movePrev.copy(_moveCurr); + _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); + + } else { + + _rotateEnd.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) ); + + } } else if ( _state === STATE.ZOOM && !_this.noZoom ) { @@ -505,8 +603,18 @@ THREE.TrackballControls = function ( object, domElement ) { case 1: _state = STATE.TOUCH_ROTATE; - _rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - _rotateEnd.copy( _rotateStart ); + + if ( _this.cylindricalRotation ) { + + _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); + _movePrev.copy(_moveCurr); + + } else { + + _rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); + _rotateEnd.copy( _rotateStart ); + + } break; case 2: @@ -540,7 +648,16 @@ THREE.TrackballControls = function ( object, domElement ) { switch ( event.touches.length ) { case 1: - _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); + if ( _this.cylindricalRotation ) { + + _movePrev.copy(_moveCurr); + _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); + + } else { + + _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); + + } break; case 2: @@ -567,8 +684,16 @@ THREE.TrackballControls = function ( object, domElement ) { switch ( event.touches.length ) { case 1: - _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - _rotateStart.copy( _rotateEnd ); + if ( _this.cylindricalRotation ) { + + _movePrev.copy(_moveCurr); + _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); + + } else { + + _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); + _rotateStart.copy( _rotateEnd ); + } break; case 2: diff --git a/examples/misc_controls_trackball.html b/examples/misc_controls_trackball.html index 0a3c64fa91182c..27265bcda7ed5b 100644 --- a/examples/misc_controls_trackball.html +++ b/examples/misc_controls_trackball.html @@ -35,7 +35,8 @@
three.js - trackball controls example
- MOVE mouse & press LEFT/A: rotate, MIDDLE/S: zoom, RIGHT/D: pan + MOVE mouse & press LEFT/A: rotate, MIDDLE/S: zoom, RIGHT/D: pan
+ R: switch from cylindrical (default) to spherical rotation
@@ -134,12 +135,33 @@ window.addEventListener( 'resize', onWindowResize, false ); + window.addEventListener( "keypress", onKeyPress, true); + // render(); } + function onKeyPress ( e ) { + + if ( e.keyCode == 114 ) { + + if (controls.cylindricalRotation) { + + controls.cylindricalRotation = false; + } + + else { + + controls.cylindricalRotation = true; + + } + + } + + } + function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; From e9732f574421c040f408691cfd457baa8592d02b Mon Sep 17 00:00:00 2001 From: erichlof Date: Thu, 19 Feb 2015 09:22:33 -0600 Subject: [PATCH 162/333] Update webgl_shadowmesh.html --- examples/webgl_shadowmesh.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/webgl_shadowmesh.html b/examples/webgl_shadowmesh.html index df597fd2116207..3eb929462ceac0 100644 --- a/examples/webgl_shadowmesh.html +++ b/examples/webgl_shadowmesh.html @@ -84,7 +84,7 @@ scene.add( camera ); onWindowResize(); - sunLight.position.set( 5, 7, -1 ); + sunLight.position.set( 5, 7, - 1 ); sunLight.lookAt( scene.position ); scene.add( sunLight ); @@ -106,7 +106,7 @@ arrowHelper2 = new THREE.ArrowHelper( arrowDirection, arrowPosition2, 0.9, 0xffff00, 0.25, 0.08 ); scene.add( arrowHelper2 ); - arrowPosition3.copy( sunLight.position ).add( new THREE.Vector3( 0, -0.2, 0 ) ); + arrowPosition3.copy( sunLight.position ).add( new THREE.Vector3( 0, - 0.2, 0 ) ); arrowHelper3 = new THREE.ArrowHelper( arrowDirection, arrowPosition3, 0.9, 0xffff00, 0.25, 0.08 ); scene.add( arrowHelper3 ); @@ -134,7 +134,7 @@ var cubeGeometry = new THREE.BoxGeometry( 1, 1, 1 ); var cubeMaterial = new THREE.MeshLambertMaterial( { color: 'rgb(255,0,0)', emissive: 0x200000 } ); cube = new THREE.Mesh( cubeGeometry, cubeMaterial ); - cube.position.z = -1; + cube.position.z = - 1; scene.add( cube ); cubeShadow = new THREE.ShadowMesh( cube ); @@ -144,7 +144,7 @@ var cylinderGeometry = new THREE.CylinderGeometry( 0.3, 0.3, 2 ); var cylinderMaterial = new THREE.MeshPhongMaterial( { color: 'rgb(0,0,255)', emissive: 0x000020 } ); cylinder = new THREE.Mesh( cylinderGeometry, cylinderMaterial ); - cylinder.position.z = -2.5; + cylinder.position.z = - 2.5; scene.add( cylinder ); cylinderShadow = new THREE.ShadowMesh( cylinder ); @@ -154,7 +154,7 @@ var torusGeometry = new THREE.TorusGeometry( 1, 0.2, 10, 16, TWO_PI ); var torusMaterial = new THREE.MeshPhongMaterial( { color: 'rgb(255,0,255)', emissive: 0x200020 } ); torus = new THREE.Mesh( torusGeometry, torusMaterial ); - torus.position.z = -6; + torus.position.z = - 6; scene.add( torus ); torusShadow = new THREE.ShadowMesh( torus ); @@ -174,7 +174,7 @@ var pyramidGeometry = new THREE.CylinderGeometry( 0, 0.5, 2, 4 ); var pyramidMaterial = new THREE.MeshLambertMaterial( { color: 'rgb(255,255,0)', emissive: 0x440000, shading: THREE.FlatShading } ); pyramid = new THREE.Mesh( pyramidGeometry, pyramidMaterial ); - pyramid.position.set( -4, 1, 2 ); + pyramid.position.set( - 4, 1, 2 ); scene.add( pyramid ); pyramidShadow = new THREE.ShadowMesh( pyramid ); @@ -204,7 +204,7 @@ if ( horizontalAngle > TWO_PI ) horizontalAngle -= TWO_PI; cube.position.x = Math.sin( horizontalAngle ) * 4; - cylinder.position.x = Math.sin( horizontalAngle ) * -4; + cylinder.position.x = Math.sin( horizontalAngle ) * - 4; torus.position.x = Math.cos( horizontalAngle ) * 4; verticalAngle += 1.5 * frameTime; @@ -252,7 +252,7 @@ renderer.setClearColor( 'rgb(0,150,255)' ); groundMesh.material.color.set( 'rgb(0,130,0)' ); - sunLight.position.set( 5, 7, -1 ); + sunLight.position.set( 5, 7, - 1 ); sunLight.lookAt( scene.position ); lightPosition4D.x = sunLight.position.x; @@ -275,7 +275,7 @@ renderer.setClearColor( 'rgb(0,0,0)' ); groundMesh.material.color.set( 'rgb(150,150,150)' ); - sunLight.position.set( 0, 6, -2 ); + sunLight.position.set( 0, 6, - 2 ); sunLight.lookAt( scene.position ); lightSphere.position.copy( sunLight.position ); lightHolder.position.copy( lightSphere.position ); From cdd6d71522cc4e353426f1a15e6ad7021414d279 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 19 Feb 2015 11:25:25 -0500 Subject: [PATCH 163/333] reduce greeness of light in morph example. --- examples/webgl_animation_skinning_morph.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/webgl_animation_skinning_morph.html b/examples/webgl_animation_skinning_morph.html index 3d3a389026575a..d62bcd4051b0cc 100644 --- a/examples/webgl_animation_skinning_morph.html +++ b/examples/webgl_animation_skinning_morph.html @@ -127,7 +127,7 @@ // - var light = new THREE.DirectionalLight( 0x497f13, 1 ); + var light = new THREE.DirectionalLight( 0x493f13, 1 ); light.position.set( 0, -1, 0 ); scene.add( light ); From 8019d61f78c52719ef7de49c318067b18edcf6aa Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 19 Feb 2015 11:25:36 -0500 Subject: [PATCH 164/333] fix bug in merge - need to use outgoingColor here. --- src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl b/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl index 485e84fb8db6ee..3d40053aa55ba9 100644 --- a/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl @@ -1 +1 @@ - gl_FragColor.xyz = linearToOutput( gl_FragColor.xyz ); \ No newline at end of file + outgoingLight.xyz = linearToOutput( outgoingLight.xyz ); \ No newline at end of file From 74b09dd33ef5e551ede7104d07298ee3ea494546 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 19 Feb 2015 11:30:21 -0500 Subject: [PATCH 165/333] for consistency with new outgoingLight variable in shaders. --- examples/js/ShaderSkin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 299d5ff93fc69a..8f1da0b3711565 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -518,7 +518,7 @@ THREE.ShaderSkin = { "if ( passID == 0 ) {", - "gl_FragColor = vec4( sqrt( outgoingLight ), diffuseColor.w );", + "outgoingLight = sqrt( outgoingLight );", "} else if ( passID == 1 ) {", From 784a89015aea9dc1402e05e73ed14c464c5c124c Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 19 Feb 2015 11:48:44 -0500 Subject: [PATCH 166/333] minor fix to get ShaderSkin skin shader matching previous state exactly. --- examples/js/ShaderSkin.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 8f1da0b3711565..72a3dc0767dddb 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -514,7 +514,7 @@ THREE.ShaderSkin = { "#endif", - "outgoingLight += diffuseColor.rgb * totalDiffuseLight;", + "outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalSpecularLight );", "if ( passID == 0 ) {", @@ -547,13 +547,15 @@ THREE.ShaderSkin = { //"gl_FragColor = vec4( vec3( 0.25, 0.6, 0.8 ) * nonblurColor + vec3( 0.15, 0.25, 0.2 ) * blur1Color + vec3( 0.15, 0.15, 0.0 ) * blur2Color + vec3( 0.45, 0.0, 0.0 ) * blur3Color, gl_FragColor.w );", - "outgoingLight += vec3( vec3( 0.22, 0.437, 0.635 ) * nonblurColor + ", + "outgoingLight = vec3( vec3( 0.22, 0.437, 0.635 ) * nonblurColor + ", "vec3( 0.101, 0.355, 0.365 ) * blur1Color + ", "vec3( 0.119, 0.208, 0.0 ) * blur2Color + ", "vec3( 0.114, 0.0, 0.0 ) * blur3Color + ", "vec3( 0.444, 0.0, 0.0 ) * blur4Color );", - "outgoingLight += ambientLightColor * diffuse + totalSpecularLight;", + "outgoingLight *= sqrt( colDiffuse.xyz );", + + "outgoingLight += ambientLightColor * diffuse * colDiffuse.xyz + totalSpecularLight;", "#ifndef VERSION1", From 40c93f92c7bac60d83f5cfb0002b60ede0d6444e Mon Sep 17 00:00:00 2001 From: danschumann Date: Thu, 19 Feb 2015 10:53:33 -0600 Subject: [PATCH 167/333] Added fail callback I was getting random fails, not sure why, maybe timeout. My workaround is to try again if it fails, but there was no fail callback. --- examples/js/loaders/ColladaLoader.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index 580e8308ad4f6b..6e03c35560acb9 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -56,7 +56,7 @@ THREE.ColladaLoader = function () { var colladaUp = 'Y'; var upConversion = null; - function load ( url, readyCallback, progressCallback ) { + function load ( url, readyCallback, progressCallback, failCallback ) { var length = 0; @@ -85,7 +85,10 @@ THREE.ColladaLoader = function () { } else { - console.error( "ColladaLoader: Empty or non-existing file (" + url + ")" ); + if (faillCallback) + failCallback(); + else + console.error( "ColladaLoader: Empty or non-existing file (" + url + ")" ); } From 4501d5a51d49e2e709930188a02af8d3dec5da61 Mon Sep 17 00:00:00 2001 From: gero3 Date: Thu, 19 Feb 2015 17:34:37 +0000 Subject: [PATCH 168/333] revert last commit --- editor/js/Sidebar.Object3D.js | 2 +- examples/js/BlendCharacter.js | 12 +- examples/js/CurveExtras.js | 16 +- examples/js/ParametricGeometries.js | 6 +- examples/js/SimplexNoise.js | 422 ++-- examples/js/Sparks.js | 290 +-- examples/js/controls/MouseControls.js | 50 +- examples/js/controls/TransformControls.js | 24 +- examples/js/effects/VREffect.js | 2 +- examples/js/geometries/ConvexGeometry.js | 10 +- examples/js/geometries/DecalGeometry.js | 4 +- examples/js/loaders/AWDLoader.js | 1288 ++++++------ examples/js/loaders/ColladaLoader.js | 52 +- examples/js/loaders/PVRLoader.js | 32 +- examples/js/loaders/RGBELoader.js | 6 +- examples/js/loaders/STLLoader.js | 14 +- examples/js/loaders/TGALoader.js | 12 +- examples/js/loaders/UTF8Loader.js | 572 +++--- examples/js/loaders/VRMLLoader.js | 2 +- examples/js/loaders/ctm/ctm.js | 714 +++---- examples/js/loaders/ctm/lzma.js | 696 +++---- examples/js/loaders/deprecated/SceneLoader.js | 2 +- examples/js/loaders/gltf/glTF-parser.js | 336 ++-- examples/js/loaders/gltf/glTFLoader.js | 1784 ++++++++--------- examples/js/loaders/gltf/glTFLoaderUtils.js | 204 +- examples/js/renderers/SVGRenderer.js | 2 +- examples/js/renderers/SoftwareRenderer.js | 4 +- examples/js/utils/UVsDebug.js | 110 +- examples/js/wip/benchmark/Geometry4.js | 50 +- src/extras/FontUtils.js | 6 +- src/extras/core/Curve.js | 8 +- src/extras/core/Path.js | 4 +- src/extras/geometries/ExtrudeGeometry.js | 12 +- src/loaders/CompressedTextureLoader.js | 2 +- src/loaders/JSONLoader.js | 2 +- src/math/Matrix4.js | 8 +- src/math/Sphere.js | 2 +- src/math/Vector2.js | 14 +- src/math/Vector3.js | 16 +- src/math/Vector4.js | 58 +- src/renderers/WebGLRenderer.js | 46 +- 41 files changed, 3448 insertions(+), 3448 deletions(-) diff --git a/editor/js/Sidebar.Object3D.js b/editor/js/Sidebar.Object3D.js index b2b0394e3b942f..4bea46dc1ed46b 100644 --- a/editor/js/Sidebar.Object3D.js +++ b/editor/js/Sidebar.Object3D.js @@ -84,7 +84,7 @@ Sidebar.Object3D = function ( editor ) { var objectNameRow = new UI.Panel(); var objectName = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () { - editor.nameObject( editor.selected, objectName.getValue() ); + editor.nameObject( editor.selected, objectName.getValue() ); } ); diff --git a/examples/js/BlendCharacter.js b/examples/js/BlendCharacter.js index ca7a142a95c329..430eb7f4f255e0 100644 --- a/examples/js/BlendCharacter.js +++ b/examples/js/BlendCharacter.js @@ -203,17 +203,17 @@ THREE.BlendCharacter = function () { this.unPauseAll = function() { - for ( var a in this.animations ) { + for ( var a in this.animations ) { - if ( this.animations[ a ].isPlaying && this.animations[ a ].isPaused ) { + if ( this.animations[ a ].isPlaying && this.animations[ a ].isPaused ) { - this.animations[ a ].pause(); + this.animations[ a ].pause(); - } + } - } + } - }; + }; this.stopAll = function() { diff --git a/examples/js/CurveExtras.js b/examples/js/CurveExtras.js index f9340f9fe8aff8..6b0864d60ebc85 100644 --- a/examples/js/CurveExtras.js +++ b/examples/js/CurveExtras.js @@ -18,12 +18,12 @@ THREE.Curves = {}; THREE.Curves.GrannyKnot = THREE.Curve.create( function() {}, function(t) { - t = 2 * Math.PI * t; + t = 2 * Math.PI * t; - var x = -0.22 * Math.cos(t) - 1.28 * Math.sin(t) - 0.44 * Math.cos(3 * t) - 0.78 * Math.sin(3 * t); - var y = -0.1 * Math.cos(2 * t) - 0.27 * Math.sin(2 * t) + 0.38 * Math.cos(4 * t) + 0.46 * Math.sin(4 * t); - var z = 0.7 * Math.cos(3 * t) - 0.4 * Math.sin(3 * t); - return new THREE.Vector3(x, y, z).multiplyScalar(20); + var x = -0.22 * Math.cos(t) - 1.28 * Math.sin(t) - 0.44 * Math.cos(3 * t) - 0.78 * Math.sin(3 * t); + var y = -0.1 * Math.cos(2 * t) - 0.27 * Math.sin(2 * t) + 0.38 * Math.cos(4 * t) + 0.46 * Math.sin(4 * t); + var z = 0.7 * Math.cos(3 * t) - 0.4 * Math.sin(3 * t); + return new THREE.Vector3(x, y, z).multiplyScalar(20); } ); @@ -214,10 +214,10 @@ THREE.Curves.TrefoilPolynomialKnot = THREE.Curve.create( // } var scaleTo = function(x, y, t) { - var r = y - x; - return t * r + x; + var r = y - x; + return t * r + x; - } +} THREE.Curves.FigureEightPolynomialKnot = THREE.Curve.create( diff --git a/examples/js/ParametricGeometries.js b/examples/js/ParametricGeometries.js index 41cf6aab9b45ec..8c2cc66c79483b 100644 --- a/examples/js/ParametricGeometries.js +++ b/examples/js/ParametricGeometries.js @@ -108,9 +108,9 @@ THREE.ParametricGeometries.TubeGeometry = function(path, segments, radius, segme binormals = frames.binormals; // proxy internals - this.tangents = tangents; - this.normals = normals; - this.binormals = binormals; + this.tangents = tangents; + this.normals = normals; + this.binormals = binormals; diff --git a/examples/js/SimplexNoise.js b/examples/js/SimplexNoise.js index d0952c1979d5d6..1dd120d443f649 100644 --- a/examples/js/SimplexNoise.js +++ b/examples/js/SimplexNoise.js @@ -13,11 +13,11 @@ */ var SimplexNoise = function(r) { if (r == undefined) r = Math; - this.grad3 = [[ 1,1,0 ],[ -1,1,0 ],[ 1,-1,0 ],[ -1,-1,0 ], + this.grad3 = [[ 1,1,0 ],[ -1,1,0 ],[ 1,-1,0 ],[ -1,-1,0 ], [ 1,0,1 ],[ -1,0,1 ],[ 1,0,-1 ],[ -1,0,-1 ], [ 0,1,1 ],[ 0,-1,1 ],[ 0,1,-1 ],[ 0,-1,-1 ]]; - this.grad4 = [[ 0,1,1,1 ], [ 0,1,1,-1 ], [ 0,1,-1,1 ], [ 0,1,-1,-1 ], + this.grad4 = [[ 0,1,1,1 ], [ 0,1,1,-1 ], [ 0,1,-1,1 ], [ 0,1,-1,-1 ], [ 0,-1,1,1 ], [ 0,-1,1,-1 ], [ 0,-1,-1,1 ], [ 0,-1,-1,-1 ], [ 1,0,1,1 ], [ 1,0,1,-1 ], [ 1,0,-1,1 ], [ 1,0,-1,-1 ], [ -1,0,1,1 ], [ -1,0,1,-1 ], [ -1,0,-1,1 ], [ -1,0,-1,-1 ], @@ -26,19 +26,19 @@ var SimplexNoise = function(r) { [ 1,1,1,0 ], [ 1,1,-1,0 ], [ 1,-1,1,0 ], [ 1,-1,-1,0 ], [ -1,1,1,0 ], [ -1,1,-1,0 ], [ -1,-1,1,0 ], [ -1,-1,-1,0 ]]; - this.p = []; - for (var i = 0; i < 256; i ++) { - this.p[i] = Math.floor(r.random() * 256); - } + this.p = []; + for (var i = 0; i < 256; i ++) { + this.p[i] = Math.floor(r.random() * 256); + } // To remove the need for index wrapping, double the permutation table length - this.perm = []; - for (var i = 0; i < 512; i ++) { + this.perm = []; + for (var i = 0; i < 512; i ++) { this.perm[i] = this.p[i & 255]; } // A lookup table to traverse the simplex around a given point in 4D. // Details can be found where this table is used, in the 4D noise method. - this.simplex = [ + this.simplex = [ [ 0,1,2,3 ],[ 0,1,3,2 ],[ 0,0,0,0 ],[ 0,2,3,1 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 1,2,3,0 ], [ 0,2,1,3 ],[ 0,0,0,0 ],[ 0,3,1,2 ],[ 0,3,2,1 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 1,3,2,0 ], [ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ], @@ -54,149 +54,149 @@ SimplexNoise.prototype.dot = function(g, x, y) { }; SimplexNoise.prototype.dot3 = function(g, x, y, z) { - return g[0] * x + g[1] * y + g[2] * z; + return g[0] * x + g[1] * y + g[2] * z; } SimplexNoise.prototype.dot4 = function(g, x, y, z, w) { - return g[0] * x + g[1] * y + g[2] * z + g[3] * w; + return g[0] * x + g[1] * y + g[2] * z + g[3] * w; }; SimplexNoise.prototype.noise = function(xin, yin) { - var n0, n1, n2; // Noise contributions from the three corners + var n0, n1, n2; // Noise contributions from the three corners // Skew the input space to determine which simplex cell we're in - var F2 = 0.5 * (Math.sqrt(3.0) - 1.0); - var s = (xin + yin) * F2; // Hairy factor for 2D - var i = Math.floor(xin + s); - var j = Math.floor(yin + s); - var G2 = (3.0 - Math.sqrt(3.0)) / 6.0; - var t = (i + j) * G2; - var X0 = i - t; // Unskew the cell origin back to (x,y) space - var Y0 = j - t; - var x0 = xin - X0; // The x,y distances from the cell origin - var y0 = yin - Y0; + var F2 = 0.5 * (Math.sqrt(3.0) - 1.0); + var s = (xin + yin) * F2; // Hairy factor for 2D + var i = Math.floor(xin + s); + var j = Math.floor(yin + s); + var G2 = (3.0 - Math.sqrt(3.0)) / 6.0; + var t = (i + j) * G2; + var X0 = i - t; // Unskew the cell origin back to (x,y) space + var Y0 = j - t; + var x0 = xin - X0; // The x,y distances from the cell origin + var y0 = yin - Y0; // For the 2D case, the simplex shape is an equilateral triangle. // Determine which simplex we are in. - var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords - if (x0 > y0) {i1 = 1; j1 = 0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1) - else {i1 = 0; j1 = 1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1) + var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords + if (x0 > y0) {i1 = 1; j1 = 0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1) + else {i1 = 0; j1 = 1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1) // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where // c = (3-sqrt(3))/6 - var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords - var y1 = y0 - j1 + G2; - var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords - var y2 = y0 - 1.0 + 2.0 * G2; + var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords + var y1 = y0 - j1 + G2; + var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords + var y2 = y0 - 1.0 + 2.0 * G2; // Work out the hashed gradient indices of the three simplex corners - var ii = i & 255; - var jj = j & 255; - var gi0 = this.perm[ii + this.perm[jj]] % 12; - var gi1 = this.perm[ii + i1 + this.perm[jj + j1]] % 12; - var gi2 = this.perm[ii + 1 + this.perm[jj + 1]] % 12; + var ii = i & 255; + var jj = j & 255; + var gi0 = this.perm[ii + this.perm[jj]] % 12; + var gi1 = this.perm[ii + i1 + this.perm[jj + j1]] % 12; + var gi2 = this.perm[ii + 1 + this.perm[jj + 1]] % 12; // Calculate the contribution from the three corners - var t0 = 0.5 - x0 * x0 - y0 * y0; - if (t0 < 0) n0 = 0.0; - else { - t0 *= t0; - n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient - } - var t1 = 0.5 - x1 * x1 - y1 * y1; - if (t1 < 0) n1 = 0.0; - else { - t1 *= t1; - n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1); - } - var t2 = 0.5 - x2 * x2 - y2 * y2; - if (t2 < 0) n2 = 0.0; - else { - t2 *= t2; - n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2); - } + var t0 = 0.5 - x0 * x0 - y0 * y0; + if (t0 < 0) n0 = 0.0; + else { + t0 *= t0; + n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient + } + var t1 = 0.5 - x1 * x1 - y1 * y1; + if (t1 < 0) n1 = 0.0; + else { + t1 *= t1; + n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1); + } + var t2 = 0.5 - x2 * x2 - y2 * y2; + if (t2 < 0) n2 = 0.0; + else { + t2 *= t2; + n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2); + } // Add contributions from each corner to get the final noise value. // The result is scaled to return values in the interval [-1,1]. - return 70.0 * (n0 + n1 + n2); + return 70.0 * (n0 + n1 + n2); }; // 3D simplex noise SimplexNoise.prototype.noise3d = function(xin, yin, zin) { - var n0, n1, n2, n3; // Noise contributions from the four corners + var n0, n1, n2, n3; // Noise contributions from the four corners // Skew the input space to determine which simplex cell we're in - var F3 = 1.0 / 3.0; - var s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D - var i = Math.floor(xin + s); - var j = Math.floor(yin + s); - var k = Math.floor(zin + s); - var G3 = 1.0 / 6.0; // Very nice and simple unskew factor, too - var t = (i + j + k) * G3; - var X0 = i - t; // Unskew the cell origin back to (x,y,z) space - var Y0 = j - t; - var Z0 = k - t; - var x0 = xin - X0; // The x,y,z distances from the cell origin - var y0 = yin - Y0; - var z0 = zin - Z0; + var F3 = 1.0 / 3.0; + var s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D + var i = Math.floor(xin + s); + var j = Math.floor(yin + s); + var k = Math.floor(zin + s); + var G3 = 1.0 / 6.0; // Very nice and simple unskew factor, too + var t = (i + j + k) * G3; + var X0 = i - t; // Unskew the cell origin back to (x,y,z) space + var Y0 = j - t; + var Z0 = k - t; + var x0 = xin - X0; // The x,y,z distances from the cell origin + var y0 = yin - Y0; + var z0 = zin - Z0; // For the 3D case, the simplex shape is a slightly irregular tetrahedron. // Determine which simplex we are in. - var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords - var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords - if (x0 >= y0) { - if (y0 >= z0) + var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords + var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords + if (x0 >= y0) { + if (y0 >= z0) { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } // X Y Z order else if (x0 >= z0) { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1; } // X Z Y order - else { i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1; } // Z X Y order - } - else { // x0 y0) ? 32 : 0; - var c2 = (x0 > z0) ? 16 : 0; - var c3 = (y0 > z0) ? 8 : 0; - var c4 = (x0 > w0) ? 4 : 0; - var c5 = (y0 > w0) ? 2 : 0; - var c6 = (z0 > w0) ? 1 : 0; - var c = c1 + c2 + c3 + c4 + c5 + c6; - var i1, j1, k1, l1; // The integer offsets for the second simplex corner - var i2, j2, k2, l2; // The integer offsets for the third simplex corner - var i3, j3, k3, l3; // The integer offsets for the fourth simplex corner + var c1 = (x0 > y0) ? 32 : 0; + var c2 = (x0 > z0) ? 16 : 0; + var c3 = (y0 > z0) ? 8 : 0; + var c4 = (x0 > w0) ? 4 : 0; + var c5 = (y0 > w0) ? 2 : 0; + var c6 = (z0 > w0) ? 1 : 0; + var c = c1 + c2 + c3 + c4 + c5 + c6; + var i1, j1, k1, l1; // The integer offsets for the second simplex corner + var i2, j2, k2, l2; // The integer offsets for the third simplex corner + var i3, j3, k3, l3; // The integer offsets for the fourth simplex corner // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order. // Many values of c will never occur, since e.g. x>y>z>w makes x= 3 ? 1 : 0; - j1 = simplex[c][1] >= 3 ? 1 : 0; - k1 = simplex[c][2] >= 3 ? 1 : 0; - l1 = simplex[c][3] >= 3 ? 1 : 0; + i1 = simplex[c][0] >= 3 ? 1 : 0; + j1 = simplex[c][1] >= 3 ? 1 : 0; + k1 = simplex[c][2] >= 3 ? 1 : 0; + l1 = simplex[c][3] >= 3 ? 1 : 0; // The number 2 in the "simplex" array is at the second largest coordinate. - i2 = simplex[c][0] >= 2 ? 1 : 0; - j2 = simplex[c][1] >= 2 ? 1 : 0; k2 = simplex[c][2] >= 2 ? 1 : 0; - l2 = simplex[c][3] >= 2 ? 1 : 0; + i2 = simplex[c][0] >= 2 ? 1 : 0; + j2 = simplex[c][1] >= 2 ? 1 : 0; k2 = simplex[c][2] >= 2 ? 1 : 0; + l2 = simplex[c][3] >= 2 ? 1 : 0; // The number 1 in the "simplex" array is at the second smallest coordinate. - i3 = simplex[c][0] >= 1 ? 1 : 0; - j3 = simplex[c][1] >= 1 ? 1 : 0; - k3 = simplex[c][2] >= 1 ? 1 : 0; - l3 = simplex[c][3] >= 1 ? 1 : 0; + i3 = simplex[c][0] >= 1 ? 1 : 0; + j3 = simplex[c][1] >= 1 ? 1 : 0; + k3 = simplex[c][2] >= 1 ? 1 : 0; + l3 = simplex[c][3] >= 1 ? 1 : 0; // The fifth corner has all coordinate offsets = 1, so no need to look that up. - var x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords - var y1 = y0 - j1 + G4; - var z1 = z0 - k1 + G4; - var w1 = w0 - l1 + G4; - var x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords - var y2 = y0 - j2 + 2.0 * G4; - var z2 = z0 - k2 + 2.0 * G4; - var w2 = w0 - l2 + 2.0 * G4; - var x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords - var y3 = y0 - j3 + 3.0 * G4; - var z3 = z0 - k3 + 3.0 * G4; - var w3 = w0 - l3 + 3.0 * G4; - var x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords - var y4 = y0 - 1.0 + 4.0 * G4; - var z4 = z0 - 1.0 + 4.0 * G4; - var w4 = w0 - 1.0 + 4.0 * G4; + var x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords + var y1 = y0 - j1 + G4; + var z1 = z0 - k1 + G4; + var w1 = w0 - l1 + G4; + var x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords + var y2 = y0 - j2 + 2.0 * G4; + var z2 = z0 - k2 + 2.0 * G4; + var w2 = w0 - l2 + 2.0 * G4; + var x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords + var y3 = y0 - j3 + 3.0 * G4; + var z3 = z0 - k3 + 3.0 * G4; + var w3 = w0 - l3 + 3.0 * G4; + var x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords + var y4 = y0 - 1.0 + 4.0 * G4; + var z4 = z0 - 1.0 + 4.0 * G4; + var w4 = w0 - 1.0 + 4.0 * G4; // Work out the hashed gradient indices of the five simplex corners - var ii = i & 255; - var jj = j & 255; - var kk = k & 255; - var ll = l & 255; - var gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32; - var gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32; - var gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32; - var gi3 = perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32; - var gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; + var ii = i & 255; + var jj = j & 255; + var kk = k & 255; + var ll = l & 255; + var gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32; + var gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32; + var gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32; + var gi3 = perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32; + var gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; // Calculate the contribution from the five corners - var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; - if (t0 < 0) n0 = 0.0; - else { - t0 *= t0; - n0 = t0 * t0 * this.dot4(grad4[gi0], x0, y0, z0, w0); - } - var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; - if (t1 < 0) n1 = 0.0; - else { - t1 *= t1; - n1 = t1 * t1 * this.dot4(grad4[gi1], x1, y1, z1, w1); - } - var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; - if (t2 < 0) n2 = 0.0; - else { - t2 *= t2; - n2 = t2 * t2 * this.dot4(grad4[gi2], x2, y2, z2, w2); - } var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; - if (t3 < 0) n3 = 0.0; - else { - t3 *= t3; - n3 = t3 * t3 * this.dot4(grad4[gi3], x3, y3, z3, w3); - } - var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; - if (t4 < 0) n4 = 0.0; - else { - t4 *= t4; - n4 = t4 * t4 * this.dot4(grad4[gi4], x4, y4, z4, w4); - } + var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; + if (t0 < 0) n0 = 0.0; + else { + t0 *= t0; + n0 = t0 * t0 * this.dot4(grad4[gi0], x0, y0, z0, w0); + } + var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; + if (t1 < 0) n1 = 0.0; + else { + t1 *= t1; + n1 = t1 * t1 * this.dot4(grad4[gi1], x1, y1, z1, w1); + } + var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; + if (t2 < 0) n2 = 0.0; + else { + t2 *= t2; + n2 = t2 * t2 * this.dot4(grad4[gi2], x2, y2, z2, w2); + } var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; + if (t3 < 0) n3 = 0.0; + else { + t3 *= t3; + n3 = t3 * t3 * this.dot4(grad4[gi3], x3, y3, z3, w3); + } + var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; + if (t4 < 0) n4 = 0.0; + else { + t4 *= t4; + n4 = t4 * t4 * this.dot4(grad4[gi4], x4, y4, z4, w4); + } // Sum up and scale the result to cover the range [-1,1] - return 27.0 * (n0 + n1 + n2 + n3 + n4); + return 27.0 * (n0 + n1 + n2 + n3 + n4); }; diff --git a/examples/js/Sparks.js b/examples/js/Sparks.js index 5d2fdea3e82c1a..230d39cd06d184 100644 --- a/examples/js/Sparks.js +++ b/examples/js/Sparks.js @@ -19,18 +19,18 @@ var SPARKS = {}; SPARKS.Emitter = function (counter) { - this._counter = counter ? counter : new SPARKS.SteadyCounter(10); // provides number of particles to produce + this._counter = counter ? counter : new SPARKS.SteadyCounter(10); // provides number of particles to produce - this._particles = []; + this._particles = []; - this._initializers = []; // use for creation of particles - this._actions = []; // uses action to update particles - this._activities = []; // not supported yet + this._initializers = []; // use for creation of particles + this._actions = []; // uses action to update particles + this._activities = []; // not supported yet - this._handlers = []; + this._handlers = []; - this.callbacks = {}; + this.callbacks = {}; }; @@ -99,108 +99,108 @@ SPARKS.Emitter.prototype = { // Update particle engine in seconds, not milliseconds update: function(time) { - var i, j; - var len = this._counter.updateEmitter( this, time ); + var i, j; + var len = this._counter.updateEmitter( this, time ); // Create particles - for ( i = 0; i < len; i ++ ) { - this.createParticle(); - } + for ( i = 0; i < len; i ++ ) { + this.createParticle(); + } // Update activities - len = this._activities.length; - for ( i = 0; i < len; i ++ ) + len = this._activities.length; + for ( i = 0; i < len; i ++ ) { - this._activities[i].update( this, time ); - } + this._activities[i].update( this, time ); + } - len = this._actions.length; + len = this._actions.length; - var particle; - var action; - var len2 = this._particles.length; + var particle; + var action; + var len2 = this._particles.length; - for ( j = 0; j < len; j ++ ) + for ( j = 0; j < len; j ++ ) { - action = this._actions[j]; - for ( i = 0; i < len2; ++ i ) + action = this._actions[j]; + for ( i = 0; i < len2; ++ i ) { - particle = this._particles[i]; - action.update( this, particle, time ); - } - } + particle = this._particles[i]; + action.update( this, particle, time ); + } + } // remove dead particles - for ( i = len2; i --; ) + for ( i = len2; i --; ) { - particle = this._particles[i]; - if ( particle.isDead ) + particle = this._particles[i]; + if ( particle.isDead ) { //particle = - this._particles.splice( i, 1 ); - this.dispatchEvent("dead", particle); - SPARKS.VectorPool.release(particle.position); // - SPARKS.VectorPool.release(particle.velocity); + this._particles.splice( i, 1 ); + this.dispatchEvent("dead", particle); + SPARKS.VectorPool.release(particle.position); // + SPARKS.VectorPool.release(particle.velocity); - } else { - this.dispatchEvent("updated", particle); - } - } + } else { + this.dispatchEvent("updated", particle); + } + } - this.dispatchEvent("loopUpdated"); + this.dispatchEvent("loopUpdated"); }, createParticle: function() { - var particle = new SPARKS.Particle(); + var particle = new SPARKS.Particle(); // In future, use a Particle Factory - var len = this._initializers.length, i; + var len = this._initializers.length, i; - for ( i = 0; i < len; i ++ ) { - this._initializers[i].initialize( this, particle ); - } + for ( i = 0; i < len; i ++ ) { + this._initializers[i].initialize( this, particle ); + } - this._particles.push( particle ); + this._particles.push( particle ); - this.dispatchEvent("created", particle); // ParticleCreated + this.dispatchEvent("created", particle); // ParticleCreated - return particle; + return particle; }, addInitializer: function (initializer) { - this._initializers.push(initializer); + this._initializers.push(initializer); }, addAction: function (action) { - this._actions.push(action); + this._actions.push(action); }, removeInitializer: function (initializer) { - var index = this._initializers.indexOf(initializer); - if (index > -1) { - this._initializers.splice( index, 1 ); - } + var index = this._initializers.indexOf(initializer); + if (index > -1) { + this._initializers.splice( index, 1 ); + } }, removeAction: function (action) { - var index = this._actions.indexOf(action); - if (index > -1) { - this._actions.splice( index, 1 ); - } + var index = this._actions.indexOf(action); + if (index > -1) { + this._actions.splice( index, 1 ); + } //console.log('removeAction', index, this._actions); }, addCallback: function(name, callback) { - this.callbacks[name] = callback; + this.callbacks[name] = callback; }, dispatchEvent: function(name, args) { - var callback = this.callbacks[name]; - if (callback) { - callback(args); - } + var callback = this.callbacks[name]; + if (callback) { + callback(args); + } } @@ -227,7 +227,7 @@ SPARKS.EVENT_LOOP_UPDATED = "loopUpdated"; // Number of particles per seconds SPARKS.SteadyCounter = function(rate) { - this.rate = rate; + this.rate = rate; // we use a shortfall counter to make up for slow emitters this.leftover = 0; @@ -277,31 +277,31 @@ SPARKS.Particle = function() { /** * The lifetime of the particle, in seconds. */ - this.lifetime = 0; + this.lifetime = 0; /** * The age of the particle, in seconds. */ - this.age = 0; + this.age = 0; /** * The energy of the particle. */ - this.energy = 1; + this.energy = 1; /** * Whether the particle is dead and should be removed from the stage. */ - this.isDead = false; + this.isDead = false; - this.target = null; // tag + this.target = null; // tag /** * For 3D */ - this.position = SPARKS.VectorPool.get().set(0, 0, 0); //new THREE.Vector3( 0, 0, 0 ); - this.velocity = SPARKS.VectorPool.get().set(0, 0, 0); //new THREE.Vector3( 0, 0, 0 ); + this.position = SPARKS.VectorPool.get().set(0, 0, 0); //new THREE.Vector3( 0, 0, 0 ); + this.velocity = SPARKS.VectorPool.get().set(0, 0, 0); //new THREE.Vector3( 0, 0, 0 ); this._oldvelocity = SPARKS.VectorPool.get().set(0, 0, 0); // rotation vec3 // angVelocity vec3 @@ -317,26 +317,26 @@ SPARKS.Particle = function() { * update function *********************************/ SPARKS.Action = function() { - this._priority = 0; + this._priority = 0; }; SPARKS.Age = function(easing) { - this._easing = (easing == null) ? TWEEN.Easing.Linear.None : easing; + this._easing = (easing == null) ? TWEEN.Easing.Linear.None : easing; }; SPARKS.Age.prototype.update = function (emitter, particle, time) { - particle.age += time; - if ( particle.age >= particle.lifetime ) + particle.age += time; + if ( particle.age >= particle.lifetime ) { - particle.energy = 0; - particle.isDead = true; - } + particle.energy = 0; + particle.isDead = true; + } else - { - var t = this._easing(particle.age / particle.lifetime); - particle.energy = -1 * t + 1; - } + { + var t = this._easing(particle.age / particle.lifetime); + particle.energy = -1 * t + 1; + } }; /* @@ -360,9 +360,9 @@ SPARKS.Move = function() { SPARKS.Move.prototype.update = function(emitter, particle, time) { // attempt verlet velocity updating. - var p = particle.position; + var p = particle.position; var v = particle.velocity; - var old = particle._oldvelocity; + var old = particle._oldvelocity; if (this._velocityVerlet) { p.x += (v.x + old.x) * 0.5 * time; @@ -384,12 +384,12 @@ SPARKS.Move.prototype.update = function(emitter, particle, time) { /* Marks particles found in specified zone dead */ SPARKS.DeathZone = function(zone) { - this.zone = zone; + this.zone = zone; }; SPARKS.DeathZone.prototype.update = function(emitter, particle, time) { - if (this.zone.contains(particle.position)) { + if (this.zone.contains(particle.position)) { particle.isDead = true; } @@ -400,12 +400,12 @@ SPARKS.DeathZone.prototype.update = function(emitter, particle, time) { */ SPARKS.ActionZone = function(action, zone) { this.action = action; - this.zone = zone; + this.zone = zone; }; SPARKS.ActionZone.prototype.update = function(emitter, particle, time) { - if (this.zone.contains(particle.position)) { + if (this.zone.contains(particle.position)) { this.action.update( emitter, particle, time ); } @@ -421,20 +421,20 @@ SPARKS.Accelerate = function(x,y,z) { return; } - this.acceleration = new THREE.Vector3(x,y,z); + this.acceleration = new THREE.Vector3(x,y,z); }; SPARKS.Accelerate.prototype.update = function(emitter, particle, time) { - var acc = this.acceleration; + var acc = this.acceleration; - var v = particle.velocity; + var v = particle.velocity; particle._oldvelocity.set(v.x, v.y, v.z); - v.x += acc.x * time; - v.y += acc.y * time; - v.z += acc.z * time; + v.x += acc.x * time; + v.y += acc.y * time; + v.z += acc.z * time; }; @@ -442,16 +442,16 @@ SPARKS.Accelerate.prototype.update = function(emitter, particle, time) { * Accelerate Factor accelerate based on a factor of particle's velocity. */ SPARKS.AccelerateFactor = function(factor) { - this.factor = factor; + this.factor = factor; }; SPARKS.AccelerateFactor.prototype.update = function(emitter, particle, time) { - var factor = this.factor; + var factor = this.factor; - var v = particle.velocity; + var v = particle.velocity; var len = v.length(); var adjFactor; - if (len > 0) { + if (len > 0) { adjFactor = factor * time / len; adjFactor += 1; @@ -475,14 +475,14 @@ SPARKS.AccelerateVelocity = function(factor) { }; SPARKS.AccelerateVelocity.prototype.update = function(emitter, particle, time) { - var factor = this.factor; + var factor = this.factor; - var v = particle.velocity; + var v = particle.velocity; - v.z += - v.x * factor; - v.y += v.z * factor; - v.x += v.y * factor; + v.z += - v.x * factor; + v.y += v.z * factor; + v.x += v.y * factor; }; @@ -494,18 +494,18 @@ SPARKS.RandomDrift = function(x,y,z) { return; } - this.drift = new THREE.Vector3(x,y,z); + this.drift = new THREE.Vector3(x,y,z); } SPARKS.RandomDrift.prototype.update = function(emitter, particle, time) { - var drift = this.drift; + var drift = this.drift; - var v = particle.velocity; + var v = particle.velocity; - v.x += ( Math.random() - 0.5 ) * drift.x * time; - v.y += ( Math.random() - 0.5 ) * drift.y * time; - v.z += ( Math.random() - 0.5 ) * drift.z * time; + v.x += ( Math.random() - 0.5 ) * drift.x * time; + v.y += ( Math.random() - 0.5 ) * drift.y * time; + v.z += ( Math.random() - 0.5 ) * drift.z * time; }; @@ -521,29 +521,29 @@ SPARKS.Zone = function() { // TODO, contains() for Zone SPARKS.PointZone = function(pos) { - this.pos = pos; + this.pos = pos; }; SPARKS.PointZone.prototype.getLocation = function() { - return this.pos; + return this.pos; }; SPARKS.PointZone = function(pos) { - this.pos = pos; + this.pos = pos; }; SPARKS.PointZone.prototype.getLocation = function() { - return this.pos; + return this.pos; }; SPARKS.LineZone = function(start, end) { - this.start = start; + this.start = start; this.end = end; this._length = end.clone().sub( start ); }; SPARKS.LineZone.prototype.getLocation = function() { - var len = this._length.clone(); + var len = this._length.clone(); len.multiplyScalar( Math.random() ); return len.add( this.start ); @@ -552,7 +552,7 @@ SPARKS.LineZone.prototype.getLocation = function() { // Basically a RectangleZone SPARKS.ParallelogramZone = function(corner, side1, side2) { - this.corner = corner; + this.corner = corner; this.side1 = side1; this.side2 = side2; }; @@ -567,7 +567,7 @@ SPARKS.ParallelogramZone.prototype.getLocation = function() { }; SPARKS.CubeZone = function(position, x, y, z) { - this.position = position; + this.position = position; this.x = x; this.y = y; this.z = z; @@ -674,29 +674,29 @@ SPARKS.DiscZone.prototype.getLocation = function() { */ SPARKS.SphereCapZone = function(x, y, z, minr, maxr, angle) { - this.x = x; - this.y = y; - this.z = z; - this.minr = minr; - this.maxr = maxr; - this.angle = angle; + this.x = x; + this.y = y; + this.z = z; + this.minr = minr; + this.maxr = maxr; + this.angle = angle; }; SPARKS.SphereCapZone.prototype.getLocation = function() { - var theta = Math.PI * 2 * SPARKS.Utils.random(); - var r = SPARKS.Utils.random(); + var theta = Math.PI * 2 * SPARKS.Utils.random(); + var r = SPARKS.Utils.random(); //new THREE.Vector3 - var v = SPARKS.VectorPool.get().set(r * Math.cos(theta), -1 / Math.tan(this.angle * SPARKS.Utils.DEGREE_TO_RADIAN), r * Math.sin(theta)); + var v = SPARKS.VectorPool.get().set(r * Math.cos(theta), -1 / Math.tan(this.angle * SPARKS.Utils.DEGREE_TO_RADIAN), r * Math.sin(theta)); //v.length = StardustMath.interpolate(0, _minRadius, 1, _maxRadius, Math.random()); - var i = this.minr - ((this.minr - this.maxr) * Math.random() ); - v.multiplyScalar(i); + var i = this.minr - ((this.minr - this.maxr) * Math.random() ); + v.multiplyScalar(i); v.__markedForReleased = true; - return v; + return v; }; @@ -709,33 +709,33 @@ SPARKS.SphereCapZone.prototype.getLocation = function() { // Specifies random life between max and min SPARKS.Lifetime = function(min, max) { - this._min = min; + this._min = min; - this._max = max ? max : min; + this._max = max ? max : min; }; SPARKS.Lifetime.prototype.initialize = function( emitter/*Emitter*/, particle/*Particle*/ ) { - particle.lifetime = this._min + SPARKS.Utils.random() * ( this._max - this._min ); + particle.lifetime = this._min + SPARKS.Utils.random() * ( this._max - this._min ); }; SPARKS.Position = function(zone) { - this.zone = zone; + this.zone = zone; }; SPARKS.Position.prototype.initialize = function( emitter/*Emitter*/, particle/*Particle*/ ) { - var pos = this.zone.getLocation(); - particle.position.set(pos.x, pos.y, pos.z); + var pos = this.zone.getLocation(); + particle.position.set(pos.x, pos.y, pos.z); }; SPARKS.Velocity = function(zone) { - this.zone = zone; + this.zone = zone; }; SPARKS.Velocity.prototype.initialize = function( emitter/*Emitter*/, particle/*Particle*/ ) { - var pos = this.zone.getLocation(); - particle.velocity.set(pos.x, pos.y, pos.z); + var pos = this.zone.getLocation(); + particle.velocity.set(pos.x, pos.y, pos.z); if (pos.__markedForReleased) { //console.log("release"); SPARKS.VectorPool.release(pos); @@ -744,17 +744,17 @@ SPARKS.Velocity.prototype.initialize = function( emitter/*Emitter*/, particle/*P }; SPARKS.Target = function(target, callback) { - this.target = target; - this.callback = callback; + this.target = target; + this.callback = callback; }; SPARKS.Target.prototype.initialize = function( emitter, particle ) { - if (this.callback) { - particle.target = this.callback(); - } else { - particle.target = this.target; - } + if (this.callback) { + particle.target = this.callback(); + } else { + particle.target = this.target; + } }; @@ -807,7 +807,7 @@ SPARKS.VectorPool = { *********************************/ SPARKS.Utils = { random: function() { - return Math.random(); + return Math.random(); }, DEGREE_TO_RADIAN: Math.PI / 180, TWOPI: Math.PI * 2, diff --git a/examples/js/controls/MouseControls.js b/examples/js/controls/MouseControls.js index d8295ab8e18493..470e50768b3502 100644 --- a/examples/js/controls/MouseControls.js +++ b/examples/js/controls/MouseControls.js @@ -6,50 +6,50 @@ THREE.MouseControls = function ( object ) { - var scope = this; - var PI_2 = Math.PI / 2; - var mouseQuat = { + var scope = this; + var PI_2 = Math.PI / 2; + var mouseQuat = { x: new THREE.Quaternion(), y: new THREE.Quaternion() }; - var object = object; - var xVector = new THREE.Vector3( 1, 0, 0 ); - var yVector = new THREE.Vector3( 0, 1, 0 ); + var object = object; + var xVector = new THREE.Vector3( 1, 0, 0 ); + var yVector = new THREE.Vector3( 0, 1, 0 ); - var onMouseMove = function ( event ) { + var onMouseMove = function ( event ) { - if ( scope.enabled === false ) return; + if ( scope.enabled === false ) return; - var orientation = scope.orientation; + var orientation = scope.orientation; - var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; - var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; + var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; + var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; - orientation.y += movementX * 0.0025; - orientation.x += movementY * 0.0025; + orientation.y += movementX * 0.0025; + orientation.x += movementY * 0.0025; - orientation.x = Math.max( - PI_2, Math.min( PI_2, orientation.x ) ); + orientation.x = Math.max( - PI_2, Math.min( PI_2, orientation.x ) ); - }; + }; - this.enabled = true; + this.enabled = true; - this.orientation = { + this.orientation = { x: 0, y: 0, }; - this.update = function() { + this.update = function() { - if ( this.enabled === false ) return; + if ( this.enabled === false ) return; - mouseQuat.x.setFromAxisAngle( xVector, this.orientation.x ); - mouseQuat.y.setFromAxisAngle( yVector, this.orientation.y ); - object.quaternion.copy(mouseQuat.y).multiply(mouseQuat.x) - return; + mouseQuat.x.setFromAxisAngle( xVector, this.orientation.x ); + mouseQuat.y.setFromAxisAngle( yVector, this.orientation.y ); + object.quaternion.copy(mouseQuat.y).multiply(mouseQuat.x) + return; - }; + }; - document.addEventListener( 'mousemove', onMouseMove, false ); + document.addEventListener( 'mousemove', onMouseMove, false ); }; diff --git a/examples/js/controls/TransformControls.js b/examples/js/controls/TransformControls.js index 809c28374d142d..a87b41a5dc8e8b 100644 --- a/examples/js/controls/TransformControls.js +++ b/examples/js/controls/TransformControls.js @@ -30,8 +30,8 @@ } else { - this.color.copy( this.oldColor ); - this.opacity = this.oldOpacity; + this.color.copy( this.oldColor ); + this.opacity = this.oldOpacity; } @@ -65,8 +65,8 @@ } else { - this.color.copy( this.oldColor ); - this.opacity = this.oldOpacity; + this.color.copy( this.oldColor ); + this.opacity = this.oldOpacity; } @@ -331,15 +331,15 @@ var CircleGeometry = function ( radius, facing, arc ) { - var geometry = new THREE.Geometry(); - arc = arc ? arc : 1; - for ( var i = 0; i <= 64 * arc; ++ i ) { - if ( facing == 'x' ) geometry.vertices.push( new THREE.Vector3( 0, Math.cos( i / 32 * Math.PI ), Math.sin( i / 32 * Math.PI ) ).multiplyScalar(radius) ); - if ( facing == 'y' ) geometry.vertices.push( new THREE.Vector3( Math.cos( i / 32 * Math.PI ), 0, Math.sin( i / 32 * Math.PI ) ).multiplyScalar(radius) ); - if ( facing == 'z' ) geometry.vertices.push( new THREE.Vector3( Math.sin( i / 32 * Math.PI ), Math.cos( i / 32 * Math.PI ), 0 ).multiplyScalar(radius) ); - } + var geometry = new THREE.Geometry(); + arc = arc ? arc : 1; + for ( var i = 0; i <= 64 * arc; ++ i ) { + if ( facing == 'x' ) geometry.vertices.push( new THREE.Vector3( 0, Math.cos( i / 32 * Math.PI ), Math.sin( i / 32 * Math.PI ) ).multiplyScalar(radius) ); + if ( facing == 'y' ) geometry.vertices.push( new THREE.Vector3( Math.cos( i / 32 * Math.PI ), 0, Math.sin( i / 32 * Math.PI ) ).multiplyScalar(radius) ); + if ( facing == 'z' ) geometry.vertices.push( new THREE.Vector3( Math.sin( i / 32 * Math.PI ), Math.cos( i / 32 * Math.PI ), 0 ).multiplyScalar(radius) ); + } - return geometry; + return geometry; }; this.handleGizmos = { diff --git a/examples/js/effects/VREffect.js b/examples/js/effects/VREffect.js index 8e71ea7f2d48ae..1c48e2fedec66e 100644 --- a/examples/js/effects/VREffect.js +++ b/examples/js/effects/VREffect.js @@ -56,7 +56,7 @@ THREE.VREffect = function ( renderer, done ) { } if ( done ) { if ( !vrHMD ) { - error = 'HMD not available'; + error = 'HMD not available'; } done( error ); } diff --git a/examples/js/geometries/ConvexGeometry.js b/examples/js/geometries/ConvexGeometry.js index 37b41a643087cc..57f10fff13d1d8 100644 --- a/examples/js/geometries/ConvexGeometry.js +++ b/examples/js/geometries/ConvexGeometry.js @@ -176,14 +176,14 @@ THREE.ConvexGeometry = function( vertices ) { for ( var j = 0; j < 3; j ++ ) { - if ( newId[ face[ j ] ] === undefined ) { + if ( newId[ face[ j ] ] === undefined ) { - newId[ face[ j ] ] = id ++; - this.vertices.push( vertices[ face[ j ] ] ); + newId[ face[ j ] ] = id ++; + this.vertices.push( vertices[ face[ j ] ] ); - } + } - face[ j ] = newId[ face[ j ] ]; + face[ j ] = newId[ face[ j ] ]; } diff --git a/examples/js/geometries/DecalGeometry.js b/examples/js/geometries/DecalGeometry.js index bc3c2cd008edc4..c5ec7fa8ae1278 100644 --- a/examples/js/geometries/DecalGeometry.js +++ b/examples/js/geometries/DecalGeometry.js @@ -191,8 +191,8 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) { vertices = this.clipFace( vertices, new THREE.Vector3( -1, 0, 0 ) ); } if ( check.y ) { - vertices = this.clipFace( vertices, new THREE.Vector3( 0, 1, 0 ) ); - vertices = this.clipFace( vertices, new THREE.Vector3( 0, -1, 0 ) ); + vertices = this.clipFace( vertices, new THREE.Vector3( 0, 1, 0 ) ); + vertices = this.clipFace( vertices, new THREE.Vector3( 0, -1, 0 ) ); } if ( check.z ) { vertices = this.clipFace( vertices, new THREE.Vector3( 0, 0, 1 ) ); diff --git a/examples/js/loaders/AWDLoader.js b/examples/js/loaders/AWDLoader.js index d0dcc1daaf8927..22b86d787b7327 100644 --- a/examples/js/loaders/AWDLoader.js +++ b/examples/js/loaders/AWDLoader.js @@ -7,7 +7,7 @@ THREE.AWDLoader = (function () { - var UNCOMPRESSED = 0, + var UNCOMPRESSED = 0, DEFLATE = 1, LZMA = 2, @@ -46,139 +46,139 @@ THREE.AWDLoader = (function () { FLOAT64 = 8; - var littleEndian = true; + var littleEndian = true; // ResourcesLoader // ============= // handle loading for external resources - function ResourcesLoader( awdUrl ) { + function ResourcesLoader( awdUrl ) { - this._baseDir = awdUrl.substr( 0, awdUrl.lastIndexOf( '/' ) + 1 ); + this._baseDir = awdUrl.substr( 0, awdUrl.lastIndexOf( '/' ) + 1 ); - this._loadingManager = new THREE.LoadingManager(); + this._loadingManager = new THREE.LoadingManager(); - } + } - ResourcesLoader.prototype = { + ResourcesLoader.prototype = { loadTexture : function( path ) { - var tex = new THREE.Texture(); + var tex = new THREE.Texture(); - var loader = new THREE.ImageLoader( this._loadingManager ); + var loader = new THREE.ImageLoader( this._loadingManager ); - loader.load( this._baseDir + path, function( image ) { - tex.image = image; - tex.needsUpdate = true; - }); + loader.load( this._baseDir + path, function( image ) { + tex.image = image; + tex.needsUpdate = true; + }); - return tex; + return tex; } } - function Block() { - this.id = 0; - this.data = null; - } + function Block() { + this.id = 0; + this.data = null; + } - function AWDLoader( showStatus ) { + function AWDLoader( showStatus ) { - THREE.Loader.call( this, showStatus ); + THREE.Loader.call( this, showStatus ); - this.trunk = new THREE.Object3D(); + this.trunk = new THREE.Object3D(); - this.materialFactory = undefined; + this.materialFactory = undefined; - this._resourceLoader = null; - this._url = ''; + this._resourceLoader = null; + this._url = ''; - this._data; - this._ptr = 0; + this._data; + this._ptr = 0; - this._version = []; - this._streaming = false; - this._optimized_for_accuracy = false; - this._compression = 0; - this._bodylen = 0xFFFFFFFF; + this._version = []; + this._streaming = false; + this._optimized_for_accuracy = false; + this._compression = 0; + this._bodylen = 0xFFFFFFFF; - this._blocks = [ new Block() ]; + this._blocks = [ new Block() ]; - this._accuracyMatrix = false; - this._accuracyGeo = false; - this._accuracyProps = false; + this._accuracyMatrix = false; + this._accuracyGeo = false; + this._accuracyProps = false; - }; + }; - AWDLoader.prototype = Object.create( THREE.Loader.prototype ); - AWDLoader.prototype.constructor = AWDLoader; + AWDLoader.prototype = Object.create( THREE.Loader.prototype ); + AWDLoader.prototype.constructor = AWDLoader; - AWDLoader.prototype.load = function ( url, callback ) { + AWDLoader.prototype.load = function ( url, callback ) { - var that = this; - this._url = url; - var xhr = new XMLHttpRequest(); - xhr.open( "GET", url, true ); - xhr.responseType = 'arraybuffer'; + var that = this; + this._url = url; + var xhr = new XMLHttpRequest(); + xhr.open( "GET", url, true ); + xhr.responseType = 'arraybuffer'; - xhr.onreadystatechange = function () { + xhr.onreadystatechange = function () { - if ( xhr.readyState == 4 ) { + if ( xhr.readyState == 4 ) { - if ( xhr.status == 200 || xhr.status == 0 ) { - that.parse( xhr.response ); - callback( that.trunk ); + if ( xhr.status == 200 || xhr.status == 0 ) { + that.parse( xhr.response ); + callback( that.trunk ); - } else { + } else { - console.error( 'AWDLoader: Couldn\'t load ' + url + ' (' + xhr.status + ')' ); + console.error( 'AWDLoader: Couldn\'t load ' + url + ' (' + xhr.status + ')' ); - } + } - } + } - }; + }; - xhr.send( null ); + xhr.send( null ); - }; + }; - AWDLoader.prototype.parse = function ( data ) { + AWDLoader.prototype.parse = function ( data ) { - var blen = data.byteLength; + var blen = data.byteLength; - this._ptr = 0; - this._data = new DataView( data ); + this._ptr = 0; + this._data = new DataView( data ); - this._parseHeader( ); + this._parseHeader( ); - if ( this._compression != 0 ) { - console.error( 'compressed AWD not supported' ); - } + if ( this._compression != 0 ) { + console.error( 'compressed AWD not supported' ); + } - if (!this._streaming && this._bodylen != data.byteLength - this._ptr ) { - console.error('AWDLoader: body len does not match file length', this._bodylen, blen - this._ptr); - } + if (!this._streaming && this._bodylen != data.byteLength - this._ptr ) { + console.error('AWDLoader: body len does not match file length', this._bodylen, blen - this._ptr); + } - while ( this._ptr < blen ) { - this.parseNextBlock(); - } + while ( this._ptr < blen ) { + this.parseNextBlock(); + } - return this.trunk; + return this.trunk; - } + } - AWDLoader.prototype.parseNextBlock = function ( ) { + AWDLoader.prototype.parseNextBlock = function ( ) { - var assetData, + var assetData, ns, type, len, block, blockId = this.readU32(), ns = this.readU8(), @@ -187,127 +187,127 @@ THREE.AWDLoader = (function () { len = this.readU32(); - switch (type) { - case 1: - assetData = this.parseMeshData(len); - break; - case 22: - assetData = this.parseContainer(len); - break; - case 23: - assetData = this.parseMeshInstance(len); - break; - case 81: - assetData = this.parseMaterial(len); - break; - case 82: - assetData = this.parseTexture(len); - break; - case 101: - assetData = this.parseSkeleton(len); - break; + switch (type) { + case 1: + assetData = this.parseMeshData(len); + break; + case 22: + assetData = this.parseContainer(len); + break; + case 23: + assetData = this.parseMeshInstance(len); + break; + case 81: + assetData = this.parseMaterial(len); + break; + case 82: + assetData = this.parseTexture(len); + break; + case 101: + assetData = this.parseSkeleton(len); + break; // case 111: // assetData = this.parseMeshPoseAnimation(len, true); // break; - case 112: - assetData = this.parseMeshPoseAnimation(len, false); - break; - case 113: - assetData = this.parseVertexAnimationSet(len); - break; - case 102: - assetData = this.parseSkeletonPose(len); - break; - case 103: - assetData = this.parseSkeletonAnimation(len); - break; - case 122: - assetData = this.parseAnimatorSet(len); - break; + case 112: + assetData = this.parseMeshPoseAnimation(len, false); + break; + case 113: + assetData = this.parseVertexAnimationSet(len); + break; + case 102: + assetData = this.parseSkeletonPose(len); + break; + case 103: + assetData = this.parseSkeletonAnimation(len); + break; + case 122: + assetData = this.parseAnimatorSet(len); + break; // case 121: // assetData = parseUVAnimation(len); // break; - default: + default: //debug('Ignoring block!',type, len); - this._ptr += len; - break; - } + this._ptr += len; + break; + } // Store block reference for later use - this._blocks[blockId] = block = new Block(); - block.data = assetData; - block.id = blockId; + this._blocks[blockId] = block = new Block(); + block.data = assetData; + block.id = blockId; - } + } - AWDLoader.prototype._parseHeader = function () { + AWDLoader.prototype._parseHeader = function () { - var version = this._version, + var version = this._version, awdmagic = ( this.readU8()<<16) | ( this.readU8()<<8 ) | this.readU8(); - if ( awdmagic != 4282180 ) + if ( awdmagic != 4282180 ) throw new Error( "AWDLoader - bad magic" ); - version[0] = this.readU8(); - version[1] = this.readU8(); + version[0] = this.readU8(); + version[1] = this.readU8(); - var flags = this.readU16(); + var flags = this.readU16(); - this._streaming = (flags & 0x1) == 0x1; + this._streaming = (flags & 0x1) == 0x1; - if ((version[0] === 2) && (version[1] === 1)) { - this._accuracyMatrix = (flags & 0x2) === 0x2; - this._accuracyGeo = (flags & 0x4) === 0x4; - this._accuracyProps = (flags & 0x8) === 0x8; - } + if ((version[0] === 2) && (version[1] === 1)) { + this._accuracyMatrix = (flags & 0x2) === 0x2; + this._accuracyGeo = (flags & 0x4) === 0x4; + this._accuracyProps = (flags & 0x8) === 0x8; + } - this._geoNrType = this._accuracyGeo ? FLOAT64 : FLOAT32; - this._matrixNrType = this._accuracyMatrix ? FLOAT64 : FLOAT32; - this._propsNrType = this._accuracyProps ? FLOAT64 : FLOAT32; + this._geoNrType = this._accuracyGeo ? FLOAT64 : FLOAT32; + this._matrixNrType = this._accuracyMatrix ? FLOAT64 : FLOAT32; + this._propsNrType = this._accuracyProps ? FLOAT64 : FLOAT32; - this._optimized_for_accuracy = (flags & 0x2) === 0x2; + this._optimized_for_accuracy = (flags & 0x2) === 0x2; - this._compression = this.readU8(); - this._bodylen = this.readU32(); + this._compression = this.readU8(); + this._bodylen = this.readU32(); - } + } - AWDLoader.prototype.parseContainer = function ( len ) { - var parent, + AWDLoader.prototype.parseContainer = function ( len ) { + var parent, ctr = new THREE.Object3D(), par_id = this.readU32(), mtx = this.parseMatrix4(); - ctr.name = this.readUTF(); - ctr.applyMatrix( mtx ); + ctr.name = this.readUTF(); + ctr.applyMatrix( mtx ); - parent = this._blocks[par_id].data || this.trunk; - parent.add(ctr); + parent = this._blocks[par_id].data || this.trunk; + parent.add(ctr); - this.parseProperties({ + this.parseProperties({ 1:this._matrixNrType, 2:this._matrixNrType, 3:this._matrixNrType, 4:UINT8 }); - ctr.extra = this.parseUserAttributes(); + ctr.extra = this.parseUserAttributes(); - return ctr; - } + return ctr; + } - AWDLoader.prototype.parseMeshInstance = function ( len ) { - var name, + AWDLoader.prototype.parseMeshInstance = function ( len ) { + var name, mesh, geometries, meshLen, meshes, par_id, data_id, mtx, @@ -317,68 +317,68 @@ THREE.AWDLoader = (function () { parent, i; - par_id = this.readU32(); - mtx = this.parseMatrix4(); - name = this.readUTF(); - data_id = this.readU32(); - num_materials = this.readU16(); + par_id = this.readU32(); + mtx = this.parseMatrix4(); + name = this.readUTF(); + data_id = this.readU32(); + num_materials = this.readU16(); - geometries = this.getBlock( data_id ); + geometries = this.getBlock( data_id ); - materials = []; - materials_parsed = 0; + materials = []; + materials_parsed = 0; - for ( i = 0; i < num_materials; i ++) { - mat_id = this.readU32(); - mat = this.getBlock( mat_id ); - materials.push( mat ); - } + for ( i = 0; i < num_materials; i ++) { + mat_id = this.readU32(); + mat = this.getBlock( mat_id ); + materials.push( mat ); + } - meshLen = geometries.length - meshes = []; + meshLen = geometries.length + meshes = []; // TODO : BufferGeometry don't support "geometryGroups" for now. // so we create sub meshes for each groups - if ( meshLen > 1 ) { - mesh = new THREE.Object3D() - for ( i = 0; i < meshLen; i ++) { - var sm = new THREE.Mesh( geometries[i] ); - meshes.push( sm ); - mesh.add( sm ); - } - } - else { - mesh = new THREE.Mesh( geometries[0] ); - meshes.push( mesh ); - } - - mesh.applyMatrix( mtx ); - mesh.name = name; - - - parent = this.getBlock( par_id ) || this.trunk; - parent.add( mesh ); - - - var matLen = materials.length; - var maxLen = Math.max( meshLen, matLen); - for ( i = 0; i < maxLen; i ++ ) + if ( meshLen > 1 ) { + mesh = new THREE.Object3D() + for ( i = 0; i < meshLen; i ++) { + var sm = new THREE.Mesh( geometries[i] ); + meshes.push( sm ); + mesh.add( sm ); + } + } + else { + mesh = new THREE.Mesh( geometries[0] ); + meshes.push( mesh ); + } + + mesh.applyMatrix( mtx ); + mesh.name = name; + + + parent = this.getBlock( par_id ) || this.trunk; + parent.add( mesh ); + + + var matLen = materials.length; + var maxLen = Math.max( meshLen, matLen); + for ( i = 0; i < maxLen; i ++ ) meshes[ i%meshLen ].material = materials[ i % matLen ]; // Ignore for now - this.parseProperties( null ); - mesh.extra = this.parseUserAttributes(); + this.parseProperties( null ); + mesh.extra = this.parseUserAttributes(); - return mesh; - } + return mesh; + } - AWDLoader.prototype.parseMaterial = function ( len ) { - var name, + AWDLoader.prototype.parseMaterial = function ( len ) { + var name, type, props, mat, @@ -387,15 +387,15 @@ THREE.AWDLoader = (function () { num_methods, methods_parsed; - name = this.readUTF(); - type = this.readU8(); - num_methods = this.readU8(); + name = this.readUTF(); + type = this.readU8(); + num_methods = this.readU8(); //log( "AWDLoader parseMaterial ",name ) // Read material numerical properties // (1=color, 2=bitmap url, 11=alpha_blending, 12=alpha_threshold, 13=repeat) - props = this.parseProperties({ + props = this.parseProperties({ 1: AWD_FIELD_INT32, 2: AWD_FIELD_BADDR, 11: AWD_FIELD_BOOL, @@ -403,276 +403,276 @@ THREE.AWDLoader = (function () { 13: AWD_FIELD_BOOL }); - methods_parsed = 0; + methods_parsed = 0; - while ( methods_parsed < num_methods ) { - var method_type = this.readU16(); - this.parseProperties( null ); - this.parseUserAttributes(); - } + while ( methods_parsed < num_methods ) { + var method_type = this.readU16(); + this.parseProperties( null ); + this.parseUserAttributes(); + } - attributes = this.parseUserAttributes(); + attributes = this.parseUserAttributes(); - if ( this.materialFactory !== undefined ) { - mat = this.materialFactory( name ); - if ( mat ) return mat; - } + if ( this.materialFactory !== undefined ) { + mat = this.materialFactory( name ); + if ( mat ) return mat; + } - mat = new THREE.MeshPhongMaterial(); + mat = new THREE.MeshPhongMaterial(); - if (type === 1) { // Color material - mat.color.setHex( props.get(1, 0xcccccc) ); - } + if (type === 1) { // Color material + mat.color.setHex( props.get(1, 0xcccccc) ); + } else if (type === 2) { // Bitmap material - var tex_addr = props.get(2, 0); - mat.map = this.getBlock( tex_addr ); + var tex_addr = props.get(2, 0); + mat.map = this.getBlock( tex_addr ); } - mat.extra = attributes; - mat.alphaThreshold = props.get(12, 0.0); - mat.repeat = props.get(13, false); + mat.extra = attributes; + mat.alphaThreshold = props.get(12, 0.0); + mat.repeat = props.get(13, false); - return mat; - } + return mat; + } - AWDLoader.prototype.parseTexture = function( len ) { + AWDLoader.prototype.parseTexture = function( len ) { - var name = this.readUTF(), + var name = this.readUTF(), type = this.readU8(), asset, data_len; // External - if (type === 0) { - data_len = this.readU32(); - var url = this.readUTFBytes(data_len); - console.log( url ); + if (type === 0) { + data_len = this.readU32(); + var url = this.readUTFBytes(data_len); + console.log( url ); - asset = this.loadTexture( url ); - } else { + asset = this.loadTexture( url ); + } else { // embed texture not supported - } + } // Ignore for now - this.parseProperties( null ); + this.parseProperties( null ); - this.parseUserAttributes(); - return asset; - } + this.parseUserAttributes(); + return asset; + } - AWDLoader.prototype.loadTexture = function( url ) { + AWDLoader.prototype.loadTexture = function( url ) { - if ( null === this._resourceLoader ) + if ( null === this._resourceLoader ) this._resourceLoader = new ResourcesLoader( this._url ); - return this._resourceLoader.loadTexture( url ); - } + return this._resourceLoader.loadTexture( url ); + } // broken : skeleton pose format is different than threejs one - AWDLoader.prototype.parseSkeleton = function(len) // Array + AWDLoader.prototype.parseSkeleton = function(len) // Array { - var name = this.readUTF(), + var name = this.readUTF(), num_joints = this.readU16(), skeleton = [], joints_parsed = 0; - this.parseProperties( null ); + this.parseProperties( null ); - while (joints_parsed < num_joints) { - var joint, ibp; + while (joints_parsed < num_joints) { + var joint, ibp; // Ignore joint id - this.readU16(); + this.readU16(); - joint = new THREE.Bone(); - joint.parent = this.readU16() - 1; // 0=null in AWD - joint.name = this.readUTF(); + joint = new THREE.Bone(); + joint.parent = this.readU16() - 1; // 0=null in AWD + joint.name = this.readUTF(); - ibp = this.parseMatrix4(); - joint.skinMatrix = ibp; + ibp = this.parseMatrix4(); + joint.skinMatrix = ibp; // Ignore joint props/attributes for now - this.parseProperties(null); - this.parseUserAttributes(); + this.parseProperties(null); + this.parseUserAttributes(); - skeleton.push(joint); - joints_parsed ++; - } + skeleton.push(joint); + joints_parsed ++; + } // Discard attributes for now - this.parseUserAttributes(); + this.parseUserAttributes(); - return skeleton; - } + return skeleton; + } - AWDLoader.prototype.parseSkeletonPose = function(blockID) + AWDLoader.prototype.parseSkeletonPose = function(blockID) { - var name = this.readUTF(); + var name = this.readUTF(); - var num_joints = this.readU16(); - this.parseProperties(null); + var num_joints = this.readU16(); + this.parseProperties(null); // debug( 'parse Skeleton Pose. joints : ' + num_joints); - var pose = []; + var pose = []; - var joints_parsed = 0; + var joints_parsed = 0; - while (joints_parsed < num_joints) { + while (joints_parsed < num_joints) { - var joint_pose; + var joint_pose; - var has_transform; //:uint; - var mtx_data; + var has_transform; //:uint; + var mtx_data; - has_transform = this.readU8(); + has_transform = this.readU8(); - if (has_transform === 1) { - mtx_data = this.parseMatrix4(); - } else - { - mtx_data = new THREE.Matrix4(); - } - pose[joints_parsed] = mtx_data; - joints_parsed ++; - } + if (has_transform === 1) { + mtx_data = this.parseMatrix4(); + } else + { + mtx_data = new THREE.Matrix4(); + } + pose[joints_parsed] = mtx_data; + joints_parsed ++; + } // Skip attributes for now - this.parseUserAttributes(); + this.parseUserAttributes(); - return pose - } + return pose + } - AWDLoader.prototype.parseSkeletonAnimation = function(blockID) + AWDLoader.prototype.parseSkeletonAnimation = function(blockID) { - var frame_dur; - var pose_addr; - var pose; + var frame_dur; + var pose_addr; + var pose; - var name = this.readUTF(); + var name = this.readUTF(); - var clip = []; + var clip = []; - var num_frames = this.readU16(); - this.parseProperties(null); + var num_frames = this.readU16(); + this.parseProperties(null); - var frames_parsed = 0; - var returnedArray; + var frames_parsed = 0; + var returnedArray; // debug( 'parse Skeleton Animation. frames : ' + num_frames); - while (frames_parsed < num_frames) { - pose_addr = this.readU32(); - frame_dur = this.readU16(); + while (frames_parsed < num_frames) { + pose_addr = this.readU32(); + frame_dur = this.readU16(); - pose = this._blocks[pose_addr].data + pose = this._blocks[pose_addr].data // debug( 'pose address ',pose[2].elements[12],pose[2].elements[13],pose[2].elements[14] ); - clip.push( { + clip.push( { pose : pose, duration : frame_dur } ); - frames_parsed ++; - } - if (clip.length == 0) { + frames_parsed ++; + } + if (clip.length == 0) { // debug("Could not this SkeletonClipNode, because no Frames where set."); - return; - } + return; + } // Ignore attributes for now - this.parseUserAttributes(); - return clip; - } + this.parseUserAttributes(); + return clip; + } - AWDLoader.prototype.parseVertexAnimationSet = function(len) + AWDLoader.prototype.parseVertexAnimationSet = function(len) { - var poseBlockAdress, + var poseBlockAdress, name = this.readUTF(), num_frames = this.readU16(), props = this.parseProperties({ 1:UINT16 }), frames_parsed = 0, skeletonFrames = []; - while (frames_parsed < num_frames) { - poseBlockAdress = this.readU32(); - skeletonFrames.push(this._blocks[poseBlockAdress].data); - frames_parsed ++; - } + while (frames_parsed < num_frames) { + poseBlockAdress = this.readU32(); + skeletonFrames.push(this._blocks[poseBlockAdress].data); + frames_parsed ++; + } - this.parseUserAttributes(); + this.parseUserAttributes(); - return skeletonFrames; - } + return skeletonFrames; + } - AWDLoader.prototype.parseAnimatorSet = function(len) + AWDLoader.prototype.parseAnimatorSet = function(len) { - var targetMesh; + var targetMesh; - var animSetBlockAdress; //:int + var animSetBlockAdress; //:int - var targetAnimationSet; //:AnimationSetBase; - var outputString = ""; //:String = ""; - var name = this.readUTF(); - var type = this.readU16(); + var targetAnimationSet; //:AnimationSetBase; + var outputString = ""; //:String = ""; + var name = this.readUTF(); + var type = this.readU16(); - var props = this.parseProperties({ 1:BADDR }); + var props = this.parseProperties({ 1:BADDR }); - animSetBlockAdress = this.readU32(); - var targetMeshLength = this.readU16(); + animSetBlockAdress = this.readU32(); + var targetMeshLength = this.readU16(); - var meshAdresses = []; //:Vector. = new Vector.; + var meshAdresses = []; //:Vector. = new Vector.; - for (var i = 0; i < targetMeshLength; i ++) + for (var i = 0; i < targetMeshLength; i ++) meshAdresses.push( this.readU32() ); - var activeState = this.readU16(); - var autoplay = Boolean(this.readU8()); - this.parseUserAttributes(); - this.parseUserAttributes(); + var activeState = this.readU16(); + var autoplay = Boolean(this.readU8()); + this.parseUserAttributes(); + this.parseUserAttributes(); - var returnedArray; - var targetMeshes = []; //:Vector. = new Vector.; + var returnedArray; + var targetMeshes = []; //:Vector. = new Vector.; - for (i = 0; i < meshAdresses.length; i ++) { + for (i = 0; i < meshAdresses.length; i ++) { // returnedArray = getAssetByID(meshAdresses[i], [AssetType.MESH]); // if (returnedArray[0]) - targetMeshes.push(this._blocks[meshAdresses[i]].data); - } + targetMeshes.push(this._blocks[meshAdresses[i]].data); + } - targetAnimationSet = this._blocks[animSetBlockAdress].data - var thisAnimator; + targetAnimationSet = this._blocks[animSetBlockAdress].data + var thisAnimator; - if (type == 1) { + if (type == 1) { - thisAnimator = { + thisAnimator = { animationSet : targetAnimationSet, skeleton : this._blocks[props.get(1, 0)].data }; - } else if (type == 2) { + } else if (type == 2) { // debug( "vertex Anim???"); - } + } - for (i = 0; i < targetMeshes.length; i ++) { - targetMeshes[i].animator = thisAnimator; - } + for (i = 0; i < targetMeshes.length; i ++) { + targetMeshes[i].animator = thisAnimator; + } // debug("Parsed a Animator: Name = " + name); - return thisAnimator; - } + return thisAnimator; + } @@ -680,9 +680,9 @@ THREE.AWDLoader = (function () { - AWDLoader.prototype.parseMeshData = function ( len ) { + AWDLoader.prototype.parseMeshData = function ( len ) { - var name = this.readUTF(), + var name = this.readUTF(), num_subs = this.readU16(), geom, subs_parsed = 0, @@ -694,7 +694,7 @@ THREE.AWDLoader = (function () { - props = this.parseProperties({ + props = this.parseProperties({ 1: this._geoNrType, 2: this._geoNrType }); @@ -702,27 +702,27 @@ THREE.AWDLoader = (function () { // Loop through sub meshes - while (subs_parsed < num_subs) { + while (subs_parsed < num_subs) { - var sm_len, sm_end, attrib; + var sm_len, sm_end, attrib; - geom = new THREE.BufferGeometry(); - geom.name = name; - geometries.push( geom ); + geom = new THREE.BufferGeometry(); + geom.name = name; + geometries.push( geom ); - sm_len = this.readU32(); - sm_end = this._ptr + sm_len; + sm_len = this.readU32(); + sm_end = this._ptr + sm_len; // Ignore for now - this.parseProperties({ 1:this._geoNrType, 2:this._geoNrType }); + this.parseProperties({ 1:this._geoNrType, 2:this._geoNrType }); // Loop through data streams - while ( this._ptr < sm_end ) { + while ( this._ptr < sm_end ) { - var idx = 0, + var idx = 0, str_type = this.readU8(), str_ftype = this.readU8(), str_len = this.readU32(), @@ -734,78 +734,78 @@ THREE.AWDLoader = (function () { // VERTICES // ------------------ - if ( str_type === 1 ) { + if ( str_type === 1 ) { - buffer = new Float32Array( ( str_len / 12 ) * 3 ); - attrib = new THREE.BufferAttribute( buffer, 3 ); + buffer = new Float32Array( ( str_len / 12 ) * 3 ); + attrib = new THREE.BufferAttribute( buffer, 3 ); - geom.addAttribute( 'position', attrib ); - idx = 0; + geom.addAttribute( 'position', attrib ); + idx = 0; - while (this._ptr < str_end) { - buffer[idx] = -this.readF32(); - buffer[idx + 1] = this.readF32(); - buffer[idx + 2] = this.readF32(); - idx+=3; - } - } + while (this._ptr < str_end) { + buffer[idx] = -this.readF32(); + buffer[idx + 1] = this.readF32(); + buffer[idx + 2] = this.readF32(); + idx+=3; + } + } // INDICES // ----------------- else if (str_type === 2) { - buffer = new Uint16Array( str_len / 2 ); - attrib = new THREE.BufferAttribute( buffer, 1 ); - geom.addAttribute( 'index', attrib ); + buffer = new Uint16Array( str_len / 2 ); + attrib = new THREE.BufferAttribute( buffer, 1 ); + geom.addAttribute( 'index', attrib ); - geom.offsets.push({ + geom.offsets.push({ start: 0, index: 0, count: str_len / 2 }); - idx = 0; + idx = 0; - while (this._ptr < str_end) { - buffer[idx + 1] = this.readU16(); - buffer[idx] = this.readU16(); - buffer[idx + 2] = this.readU16(); - idx+=3; - } + while (this._ptr < str_end) { + buffer[idx + 1] = this.readU16(); + buffer[idx] = this.readU16(); + buffer[idx + 2] = this.readU16(); + idx+=3; + } } // UVS // ------------------- else if (str_type === 3) { - buffer = new Float32Array( ( str_len / 8 ) * 2 ); - attrib = new THREE.BufferAttribute( buffer, 2 ); + buffer = new Float32Array( ( str_len / 8 ) * 2 ); + attrib = new THREE.BufferAttribute( buffer, 2 ); - geom.addAttribute( 'uv', attrib ); - idx = 0; + geom.addAttribute( 'uv', attrib ); + idx = 0; - while (this._ptr < str_end) { - buffer[idx] = this.readF32(); - buffer[idx + 1] = 1.0 - this.readF32(); - idx+=2; - } + while (this._ptr < str_end) { + buffer[idx] = this.readF32(); + buffer[idx + 1] = 1.0 - this.readF32(); + idx+=2; + } } // NORMALS else if (str_type === 4) { - buffer = new Float32Array( ( str_len / 12 ) * 3 ); - attrib = new THREE.BufferAttribute( buffer, 3 ); - geom.addAttribute( 'normal', attrib ); - idx = 0; + buffer = new Float32Array( ( str_len / 12 ) * 3 ); + attrib = new THREE.BufferAttribute( buffer, 3 ); + geom.addAttribute( 'normal', attrib ); + idx = 0; - while (this._ptr < str_end) { - buffer[idx] = -this.readF32(); - buffer[idx + 1] = this.readF32(); - buffer[idx + 2] = this.readF32(); - idx+=3; - } + while (this._ptr < str_end) { + buffer[idx] = -this.readF32(); + buffer[idx + 1] = this.readF32(); + buffer[idx + 2] = this.readF32(); + idx+=3; + } } @@ -828,34 +828,34 @@ THREE.AWDLoader = (function () { // idx++; // } // } - else { - this._ptr = str_end; - } + else { + this._ptr = str_end; + } - } + } - this.parseUserAttributes(); + this.parseUserAttributes(); - geom.computeBoundingSphere(); - subs_parsed ++; - } + geom.computeBoundingSphere(); + subs_parsed ++; + } //geom.computeFaceNormals(); - this.parseUserAttributes(); + this.parseUserAttributes(); //finalizeAsset(geom, name); - return geometries; - } + return geometries; + } - AWDLoader.prototype.parseMeshPoseAnimation = function(len, poseOnly) + AWDLoader.prototype.parseMeshPoseAnimation = function(len, poseOnly) { - var num_frames = 1, + var num_frames = 1, num_submeshes, frames_parsed, subMeshParsed, @@ -880,84 +880,84 @@ THREE.AWDLoader = (function () { geoAdress = this.readU32(); - var mesh = this.getBlock( geoAdress ); + var mesh = this.getBlock( geoAdress ); - if (mesh == null) { - console.log( "parseMeshPoseAnimation target mesh not found at:", geoAdress ); - return; - } + if (mesh == null) { + console.log( "parseMeshPoseAnimation target mesh not found at:", geoAdress ); + return; + } - geom = mesh.geometry; - geom.morphTargets = []; + geom = mesh.geometry; + geom.morphTargets = []; - if (!poseOnly) + if (!poseOnly) num_frames = this.readU16(); - num_submeshes = this.readU16(); - num_Streams = this.readU16(); + num_submeshes = this.readU16(); + num_Streams = this.readU16(); // debug("VA num_frames : ", num_frames ); // debug("VA num_submeshes : ", num_submeshes ); // debug("VA numstreams : ", num_Streams ); - streamsParsed = 0; - while (streamsParsed < num_Streams) { - streamtypes.push(this.readU16()); - streamsParsed ++; - } - props = this.parseProperties({ 1:BOOL, 2:BOOL }); + streamsParsed = 0; + while (streamsParsed < num_Streams) { + streamtypes.push(this.readU16()); + streamsParsed ++; + } + props = this.parseProperties({ 1:BOOL, 2:BOOL }); - clip.looping = props.get(1, true); - clip.stitchFinalFrame = props.get(2, false); + clip.looping = props.get(1, true); + clip.stitchFinalFrame = props.get(2, false); - frames_parsed = 0; + frames_parsed = 0; - while (frames_parsed < num_frames) { + while (frames_parsed < num_frames) { - frame_dur = this.readU16(); - subMeshParsed = 0; + frame_dur = this.readU16(); + subMeshParsed = 0; - while (subMeshParsed < num_submeshes) { + while (subMeshParsed < num_submeshes) { - streamsParsed = 0; - str_len = this.readU32(); - str_end = this._ptr + str_len; + streamsParsed = 0; + str_len = this.readU32(); + str_end = this._ptr + str_len; - while (streamsParsed < num_Streams) { + while (streamsParsed < num_Streams) { - if (streamtypes[streamsParsed] == 1) { + if (streamtypes[streamsParsed] == 1) { //geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 ); - var buffer = new Float32Array(str_len / 4); - geom.morphTargets.push( { + var buffer = new Float32Array(str_len / 4); + geom.morphTargets.push( { array : buffer }); //buffer = geom.attributes['morphTarget'+frames_parsed].array - idx = 0; + idx = 0; - while ( this._ptr < str_end ) { - buffer[idx] = this.readF32(); - buffer[idx + 1] = this.readF32(); - buffer[idx + 2] = this.readF32(); - idx += 3; - } + while ( this._ptr < str_end ) { + buffer[idx] = this.readF32(); + buffer[idx + 1] = this.readF32(); + buffer[idx + 2] = this.readF32(); + idx += 3; + } - subMeshParsed ++; - } else + subMeshParsed ++; + } else this._ptr = str_end; - streamsParsed ++; - } - } + streamsParsed ++; + } + } - frames_parsed ++; - } - this.parseUserAttributes(); + frames_parsed ++; + } + this.parseUserAttributes(); - return null; - } + return null; + } @@ -967,191 +967,191 @@ THREE.AWDLoader = (function () { - AWDLoader.prototype.getBlock = function ( id ) { - return this._blocks[id].data; - }, + AWDLoader.prototype.getBlock = function ( id ) { + return this._blocks[id].data; + }, AWDLoader.prototype.parseMatrix4 = function ( ) { - var mtx = new THREE.Matrix4(); - var e = mtx.elements; + var mtx = new THREE.Matrix4(); + var e = mtx.elements; - e[0] = this.readF32(); - e[1] = this.readF32(); - e[2] = this.readF32(); - e[3] = 0.0; + e[0] = this.readF32(); + e[1] = this.readF32(); + e[2] = this.readF32(); + e[3] = 0.0; //e[3] = 0.0; - e[4] = this.readF32(); - e[5] = this.readF32(); - e[6] = this.readF32(); + e[4] = this.readF32(); + e[5] = this.readF32(); + e[6] = this.readF32(); //e[7] = this.readF32(); - e[7] = 0.0; + e[7] = 0.0; - e[8] = this.readF32(); - e[9] = this.readF32(); - e[10] = this.readF32(); + e[8] = this.readF32(); + e[9] = this.readF32(); + e[10] = this.readF32(); //e[11] = this.readF32(); - e[11] = 0.0; + e[11] = 0.0; - e[12] = -this.readF32(); - e[13] = this.readF32(); - e[14] = this.readF32(); + e[12] = -this.readF32(); + e[13] = this.readF32(); + e[14] = this.readF32(); //e[15] = this.readF32(); - e[15] = 1.0; - return mtx; + e[15] = 1.0; + return mtx; } - AWDLoader.prototype.parseProperties = function ( expected ) { - var list_len = this.readU32(); - var list_end = this._ptr + list_len; + AWDLoader.prototype.parseProperties = function ( expected ) { + var list_len = this.readU32(); + var list_end = this._ptr + list_len; - var props = new AWDProperties(); + var props = new AWDProperties(); - if ( expected ) { + if ( expected ) { - while ( this._ptr < list_end ) { + while ( this._ptr < list_end ) { - var key = this.readU16(); - var len = this.readU32(); - var type; + var key = this.readU16(); + var len = this.readU32(); + var type; - if ( expected.hasOwnProperty( key ) ) { - type = expected[ key ]; - props.set( key, this.parseAttrValue( type, len ) ); - } else { - this._ptr += len; - } - } + if ( expected.hasOwnProperty( key ) ) { + type = expected[ key ]; + props.set( key, this.parseAttrValue( type, len ) ); + } else { + this._ptr += len; + } + } - } + } - return props; + return props; - }; + }; - AWDLoader.prototype.parseUserAttributes = function ( ) { + AWDLoader.prototype.parseUserAttributes = function ( ) { // skip for now - this._ptr = this.readU32() + this._ptr; - return null; - }; - - - AWDLoader.prototype.parseAttrValue = function ( type, len ) { - - var elem_len; - var read_func; - - switch (type) { - case AWD_FIELD_INT8: - elem_len = 1; - read_func = this.readI8; - break; - case AWD_FIELD_INT16: - elem_len = 2; - read_func = this.readI16; - break; - case AWD_FIELD_INT32: - elem_len = 4; - read_func = this.readI32; - break; - case AWD_FIELD_BOOL: - case AWD_FIELD_UINT8: - elem_len = 1; - read_func = this.readU8; - break; - case AWD_FIELD_UINT16: - elem_len = 2; - read_func = this.readU16; - break; - case AWD_FIELD_UINT32: - case AWD_FIELD_BADDR: - elem_len = 4; - read_func = this.readU32; - break; - case AWD_FIELD_FLOAT32: - elem_len = 4; - read_func = this.readF32; - break; - case AWD_FIELD_FLOAT64: - elem_len = 8; - read_func = this.readF64; - break; - case AWD_FIELD_VECTOR2x1: - case AWD_FIELD_VECTOR3x1: - case AWD_FIELD_VECTOR4x1: - case AWD_FIELD_MTX3x2: - case AWD_FIELD_MTX3x3: - case AWD_FIELD_MTX4x3: - case AWD_FIELD_MTX4x4: - elem_len = 8; - read_func = this.readF64; - break; - } - - if (elem_len < len) { - var list; - var num_read; - var num_elems; - - list = []; - num_read = 0; - num_elems = len / elem_len; - - while (num_read < num_elems) { - list.push(read_func.call( this ) ); - num_read ++; - } - - return list; - } - else { - return read_func.call( this ); - } - - } - - - AWDLoader.prototype.readU8 = function () { - return this._data.getUint8( this._ptr ++ ); - } - AWDLoader.prototype.readI8 = function () { - return this._data.getInt8( this._ptr ++ ); - } - - AWDLoader.prototype.readU16 = function () { - var a = this._data.getUint16( this._ptr, littleEndian ); - this._ptr += 2; - return a; - } - AWDLoader.prototype.readI16 = function () { - var a = this._data.getInt16( this._ptr, littleEndian ); - this._ptr += 2; - return a; - } - - AWDLoader.prototype.readU32 = function () { - var a = this._data.getUint32( this._ptr, littleEndian ); - this._ptr += 4; - return a; - } - AWDLoader.prototype.readI32 = function () { - var a = this._data.getInt32( this._ptr, littleEndian ); - this._ptr += 4; - return a; - } - AWDLoader.prototype.readF32 = function () { - var a = this._data.getFloat32( this._ptr, littleEndian ); - this._ptr += 4; - return a; - } - AWDLoader.prototype.readF64 = function () { - var a = this._data.getFloat64( this._ptr, littleEndian ); - this._ptr += 8; - return a; - } + this._ptr = this.readU32() + this._ptr; + return null; + }; + + + AWDLoader.prototype.parseAttrValue = function ( type, len ) { + + var elem_len; + var read_func; + + switch (type) { + case AWD_FIELD_INT8: + elem_len = 1; + read_func = this.readI8; + break; + case AWD_FIELD_INT16: + elem_len = 2; + read_func = this.readI16; + break; + case AWD_FIELD_INT32: + elem_len = 4; + read_func = this.readI32; + break; + case AWD_FIELD_BOOL: + case AWD_FIELD_UINT8: + elem_len = 1; + read_func = this.readU8; + break; + case AWD_FIELD_UINT16: + elem_len = 2; + read_func = this.readU16; + break; + case AWD_FIELD_UINT32: + case AWD_FIELD_BADDR: + elem_len = 4; + read_func = this.readU32; + break; + case AWD_FIELD_FLOAT32: + elem_len = 4; + read_func = this.readF32; + break; + case AWD_FIELD_FLOAT64: + elem_len = 8; + read_func = this.readF64; + break; + case AWD_FIELD_VECTOR2x1: + case AWD_FIELD_VECTOR3x1: + case AWD_FIELD_VECTOR4x1: + case AWD_FIELD_MTX3x2: + case AWD_FIELD_MTX3x3: + case AWD_FIELD_MTX4x3: + case AWD_FIELD_MTX4x4: + elem_len = 8; + read_func = this.readF64; + break; + } + + if (elem_len < len) { + var list; + var num_read; + var num_elems; + + list = []; + num_read = 0; + num_elems = len / elem_len; + + while (num_read < num_elems) { + list.push(read_func.call( this ) ); + num_read ++; + } + + return list; + } + else { + return read_func.call( this ); + } + + } + + + AWDLoader.prototype.readU8 = function () { + return this._data.getUint8( this._ptr ++ ); + } + AWDLoader.prototype.readI8 = function () { + return this._data.getInt8( this._ptr ++ ); + } + + AWDLoader.prototype.readU16 = function () { + var a = this._data.getUint16( this._ptr, littleEndian ); + this._ptr += 2; + return a; + } + AWDLoader.prototype.readI16 = function () { + var a = this._data.getInt16( this._ptr, littleEndian ); + this._ptr += 2; + return a; + } + + AWDLoader.prototype.readU32 = function () { + var a = this._data.getUint32( this._ptr, littleEndian ); + this._ptr += 4; + return a; + } + AWDLoader.prototype.readI32 = function () { + var a = this._data.getInt32( this._ptr, littleEndian ); + this._ptr += 4; + return a; + } + AWDLoader.prototype.readF32 = function () { + var a = this._data.getFloat32( this._ptr, littleEndian ); + this._ptr += 4; + return a; + } + AWDLoader.prototype.readF64 = function () { + var a = this._data.getFloat64( this._ptr, littleEndian ); + this._ptr += 8; + return a; + } /** @@ -1159,41 +1159,41 @@ THREE.AWDLoader = (function () { * @param {Array.} bytes UTF-8 byte array. * @return {string} 16-bit Unicode string. */ - AWDLoader.prototype.readUTF = function () { - var len = this.readU16(); + AWDLoader.prototype.readUTF = function () { + var len = this.readU16(); - return this.readUTFBytes( len ); - }; + return this.readUTFBytes( len ); + }; /** * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode. * @param {Array.} bytes UTF-8 byte array. * @return {string} 16-bit Unicode string. */ - AWDLoader.prototype.readUTFBytes = function ( len ) { + AWDLoader.prototype.readUTFBytes = function ( len ) { // TODO(user): Use native implementations if/when available - var out = [], c = 0; - - while ( out.length < len ) { - var c1 = this._data.getUint8( this._ptr ++, littleEndian ); - if (c1 < 128) { - out[c ++] = String.fromCharCode(c1); - } else if (c1 > 191 && c1 < 224) { - var c2 = this._data.getUint8( this._ptr ++, littleEndian ); - out[c ++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); - } else { - var c2 = this._data.getUint8( this._ptr ++, littleEndian ); - var c3 = this._data.getUint8( this._ptr ++, littleEndian ); - out[c ++] = String.fromCharCode( + var out = [], c = 0; + + while ( out.length < len ) { + var c1 = this._data.getUint8( this._ptr ++, littleEndian ); + if (c1 < 128) { + out[c ++] = String.fromCharCode(c1); + } else if (c1 > 191 && c1 < 224) { + var c2 = this._data.getUint8( this._ptr ++, littleEndian ); + out[c ++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); + } else { + var c2 = this._data.getUint8( this._ptr ++, littleEndian ); + var c3 = this._data.getUint8( this._ptr ++, littleEndian ); + out[c ++] = String.fromCharCode( (c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63 ); - } - } - return out.join(''); - }; + } + } + return out.join(''); + }; @@ -1203,24 +1203,24 @@ THREE.AWDLoader = (function () { - AWDProperties = function() {} + AWDProperties = function() {} - AWDProperties.prototype = { + AWDProperties.prototype = { set : function(key, value) { - this[key] = value; + this[key] = value; }, get : function(key, fallback) { - if ( this.hasOwnProperty(key) ) + if ( this.hasOwnProperty(key) ) return this[key]; else return fallback; } } - return AWDLoader; + return AWDLoader; })(); diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index 1d0f43d00747e6..324475d5651926 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -735,7 +735,7 @@ THREE.ColladaLoader = function () { // move vertices to bind shape for ( i = 0; i < geometry.vertices.length; i ++ ) { - geometry.vertices[i].applyMatrix4( skinController.skin.bindShapeMatrix ); + geometry.vertices[i].applyMatrix4( skinController.skin.bindShapeMatrix ); } var skinIndices = []; @@ -1343,17 +1343,17 @@ THREE.ColladaLoader = function () { function getLibraryNode( id ) { - var nodes = COLLADA.querySelectorAll('library_nodes node'); + var nodes = COLLADA.querySelectorAll('library_nodes node'); - for ( var i = 0; i < nodes.length; i ++ ) { + for ( var i = 0; i < nodes.length; i ++ ) { - var attObj = nodes[i].attributes.getNamedItem('id'); - if ( attObj && attObj.value === id ) { - return nodes[i]; - } - } + var attObj = nodes[i].attributes.getNamedItem('id'); + if ( attObj && attObj.value === id ) { + return nodes[i]; + } + } - return undefined; + return undefined; }; @@ -3365,35 +3365,35 @@ THREE.ColladaLoader = function () { //for (var i = 0; i < this.accessor.params.length; i++) { - var param = this.accessor.params[ 0 ]; + var param = this.accessor.params[ 0 ]; //console.log(param.name + " " + param.type); - switch ( param.type ) { + switch ( param.type ) { - case 'IDREF': - case 'Name': case 'name': - case 'float': + case 'IDREF': + case 'Name': case 'name': + case 'float': - return this.data; + return this.data; - case 'float4x4': + case 'float4x4': - for ( var j = 0; j < this.data.length; j += 16 ) { + for ( var j = 0; j < this.data.length; j += 16 ) { - var s = this.data.slice( j, j + 16 ); - var m = getConvertedMat4( s ); - result.push( m ); - } + var s = this.data.slice( j, j + 16 ); + var m = getConvertedMat4( s ); + result.push( m ); + } - break; + break; - default: + default: - console.log( 'ColladaLoader: Source: Read dont know how to read ' + param.type + '.' ); - break; + console.log( 'ColladaLoader: Source: Read dont know how to read ' + param.type + '.' ); + break; - } + } //} diff --git a/examples/js/loaders/PVRLoader.js b/examples/js/loaders/PVRLoader.js index b840351fa6d579..71fd264a85ded1 100644 --- a/examples/js/loaders/PVRLoader.js +++ b/examples/js/loaders/PVRLoader.js @@ -77,16 +77,16 @@ THREE.PVRLoader._parseV3 = function ( pvrDatas ) { } pvrDatas.dataPtr = 52 + metaLen; - pvrDatas.bpp = bpp; - pvrDatas.format = format; - pvrDatas.width = width; - pvrDatas.height = height; - pvrDatas.numSurfaces = numFaces; - pvrDatas.numMipmaps = numMipmaps; + pvrDatas.bpp = bpp; + pvrDatas.format = format; + pvrDatas.width = width; + pvrDatas.height = height; + pvrDatas.numSurfaces = numFaces; + pvrDatas.numMipmaps = numMipmaps; - pvrDatas.isCubemap = (numFaces === 6); + pvrDatas.isCubemap = (numFaces === 6); - return THREE.PVRLoader._extract( pvrDatas ); + return THREE.PVRLoader._extract( pvrDatas ); }; THREE.PVRLoader._parseV2 = function ( pvrDatas ) { @@ -133,18 +133,18 @@ THREE.PVRLoader._parseV2 = function ( pvrDatas ) { pvrDatas.dataPtr = headerLength; - pvrDatas.bpp = bpp; - pvrDatas.format = format; - pvrDatas.width = width; - pvrDatas.height = height; - pvrDatas.numSurfaces = numSurfs; - pvrDatas.numMipmaps = numMipmaps + 1; + pvrDatas.bpp = bpp; + pvrDatas.format = format; + pvrDatas.width = width; + pvrDatas.height = height; + pvrDatas.numSurfaces = numSurfs; + pvrDatas.numMipmaps = numMipmaps + 1; // guess cubemap type seems tricky in v2 // it juste a pvr containing 6 surface (no explicit cubemap type) - pvrDatas.isCubemap = (numSurfs === 6); + pvrDatas.isCubemap = (numSurfs === 6); - return THREE.PVRLoader._extract( pvrDatas ); + return THREE.PVRLoader._extract( pvrDatas ); }; diff --git a/examples/js/loaders/RGBELoader.js b/examples/js/loaders/RGBELoader.js index d638c89b6bf957..9d0e210bb6c635 100644 --- a/examples/js/loaders/RGBELoader.js +++ b/examples/js/loaders/RGBELoader.js @@ -30,11 +30,11 @@ THREE.RGBELoader.prototype._parser = function( buffer ) { rgbe_error = function(rgbe_error_code, msg) { switch (rgbe_error_code) { case rgbe_read_error: console.error("THREE.RGBELoader Read Error: " + (msg||'')); - break; + break; case rgbe_write_error: console.error("THREE.RGBELoader Write Error: " + (msg||'')); - break; + break; case rgbe_format_error: console.error("THREE.RGBELoader Bad File Format: " + (msg||'')); - break; + break; default: case rgbe_memory_error: console.error("THREE.RGBELoader: Error: " + (msg||'')); } diff --git a/examples/js/loaders/STLLoader.js b/examples/js/loaders/STLLoader.js index e317002dac550d..71bb4add69c9bd 100644 --- a/examples/js/loaders/STLLoader.js +++ b/examples/js/loaders/STLLoader.js @@ -110,15 +110,15 @@ THREE.STLLoader.prototype = { (reader.getUint8(index + 4) == 0x52 /*'R'*/) && (reader.getUint8(index + 5) == 0x3D /*'='*/)) { - hasColors = true; - colors = new Float32Array( faces * 3 * 3); + hasColors = true; + colors = new Float32Array( faces * 3 * 3); - defaultR = reader.getUint8(index + 6) / 255; - defaultG = reader.getUint8(index + 7) / 255; - defaultB = reader.getUint8(index + 8) / 255; - alpha = reader.getUint8(index + 9) / 255; - } + defaultR = reader.getUint8(index + 6) / 255; + defaultG = reader.getUint8(index + 7) / 255; + defaultB = reader.getUint8(index + 8) / 255; + alpha = reader.getUint8(index + 9) / 255; } + } var dataOffset = 84; var faceLength = 12 * 4 + 2; diff --git a/examples/js/loaders/TGALoader.js b/examples/js/loaders/TGALoader.js index cd9d2dfc3a975e..7df35c066e7f68 100644 --- a/examples/js/loaders/TGALoader.js +++ b/examples/js/loaders/TGALoader.js @@ -154,8 +154,8 @@ THREE.TGALoader.prototype._parser = function ( buffer ) { pixel_total, palettes; - pixel_size = header.pixel_size >> 3; - pixel_total = header.width * header.height * pixel_size; + pixel_size = header.pixel_size >> 3; + pixel_total = header.width * header.height * pixel_size; // Read palettes if ( use_pal ) { @@ -178,12 +178,12 @@ THREE.TGALoader.prototype._parser = function ( buffer ) { if (c & 0x80) { // Bind pixel tmp array for (i = 0; i < pixel_size; ++ i) { - pixels[i] = data[offset ++]; + pixels[i] = data[offset ++]; } // Copy pixel array for (i = 0; i < count; ++ i) { - pixel_data.set(pixels, shift + i * pixel_size); + pixel_data.set(pixels, shift + i * pixel_size); } shift += pixel_size * count; @@ -192,7 +192,7 @@ THREE.TGALoader.prototype._parser = function ( buffer ) { // Raw pixels. count *= pixel_size; for (i = 0; i < count; ++ i) { - pixel_data[shift + i] = data[offset ++]; + pixel_data[shift + i] = data[offset ++]; } shift += count; } @@ -214,7 +214,7 @@ THREE.TGALoader.prototype._parser = function ( buffer ) { var colormap = palettes; var color, i = 0, x, y; - var width = header.width; + var width = header.width; for (y = y_start; y !== y_end; y += y_step) { for (x = x_start; x !== x_end; x += x_step, i ++) { diff --git a/examples/js/loaders/UTF8Loader.js b/examples/js/loaders/UTF8Loader.js index 483c1e6a460965..6e9e9e9257f8db 100644 --- a/examples/js/loaders/UTF8Loader.js +++ b/examples/js/loaders/UTF8Loader.js @@ -94,12 +94,12 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray } - geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); - geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); - geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) ); + geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) ); + geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); + geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); + geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) ); - geometry.offsets.push( { start: 0, count: indices.length, index: 0 } ); + geometry.offsets.push( { start: 0, count: indices.length, index: 0 } ); geometry.computeBoundingSphere(); @@ -158,17 +158,17 @@ THREE.UTF8Loader.prototype.decompressAttribsInner_ = function ( str, inputStart, output, outputStart, stride, decodeOffset, decodeScale ) { - var prev = 0; + var prev = 0; - for ( var j = inputStart; j < inputEnd; j ++ ) { + for ( var j = inputStart; j < inputEnd; j ++ ) { - var code = str.charCodeAt( j ); - prev += ( code >> 1 ) ^ ( -( code & 1 ) ); + var code = str.charCodeAt( j ); + prev += ( code >> 1 ) ^ ( -( code & 1 ) ); - output[ outputStart ] = decodeScale * ( prev + decodeOffset ); - outputStart += stride; + output[ outputStart ] = decodeScale * ( prev + decodeOffset ); + outputStart += stride; - } + } }; @@ -177,52 +177,52 @@ THREE.UTF8Loader.prototype.decompressIndices_ = function( str, inputStart, numIn var highest = 0; - for ( var i = 0; i < numIndices; i ++ ) { + for ( var i = 0; i < numIndices; i ++ ) { - var code = str.charCodeAt( inputStart ++ ); + var code = str.charCodeAt( inputStart ++ ); - output[ outputStart ++ ] = highest - code; + output[ outputStart ++ ] = highest - code; - if ( code === 0 ) { + if ( code === 0 ) { - highest ++; + highest ++; - } + } - } + } }; THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBoxen, decodeOffsets, decodeScales ) { - var numFloats = 6 * numBBoxen; + var numFloats = 6 * numBBoxen; - var inputEnd = inputStart + numFloats; - var outputStart = 0; + var inputEnd = inputStart + numFloats; + var outputStart = 0; - var bboxen = new Float32Array( numFloats ); + var bboxen = new Float32Array( numFloats ); - for ( var i = inputStart; i < inputEnd; i += 6 ) { + for ( var i = inputStart; i < inputEnd; i += 6 ) { - var minX = str.charCodeAt(i + 0) + decodeOffsets[0]; - var minY = str.charCodeAt(i + 1) + decodeOffsets[1]; - var minZ = str.charCodeAt(i + 2) + decodeOffsets[2]; + var minX = str.charCodeAt(i + 0) + decodeOffsets[0]; + var minY = str.charCodeAt(i + 1) + decodeOffsets[1]; + var minZ = str.charCodeAt(i + 2) + decodeOffsets[2]; - var radiusX = (str.charCodeAt(i + 3) + 1) >> 1; - var radiusY = (str.charCodeAt(i + 4) + 1) >> 1; - var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1; + var radiusX = (str.charCodeAt(i + 3) + 1) >> 1; + var radiusY = (str.charCodeAt(i + 4) + 1) >> 1; + var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1; - bboxen[ outputStart ++ ] = decodeScales[0] * (minX + radiusX); - bboxen[ outputStart ++ ] = decodeScales[1] * (minY + radiusY); - bboxen[ outputStart ++ ] = decodeScales[2] * (minZ + radiusZ); + bboxen[ outputStart ++ ] = decodeScales[0] * (minX + radiusX); + bboxen[ outputStart ++ ] = decodeScales[1] * (minY + radiusY); + bboxen[ outputStart ++ ] = decodeScales[2] * (minZ + radiusZ); - bboxen[ outputStart ++ ] = decodeScales[0] * radiusX; - bboxen[ outputStart ++ ] = decodeScales[1] * radiusY; - bboxen[ outputStart ++ ] = decodeScales[2] * radiusZ; + bboxen[ outputStart ++ ] = decodeScales[0] * radiusX; + bboxen[ outputStart ++ ] = decodeScales[1] * radiusY; + bboxen[ outputStart ++ ] = decodeScales[2] * radiusZ; - } + } - return bboxen; + return bboxen; }; @@ -230,67 +230,67 @@ THREE.UTF8Loader.prototype.decompressMesh = function ( str, meshParams, decodeP // Extract conversion parameters from attribArrays. - var stride = decodeParams.decodeScales.length; + var stride = decodeParams.decodeScales.length; - var decodeOffsets = decodeParams.decodeOffsets; - var decodeScales = decodeParams.decodeScales; + var decodeOffsets = decodeParams.decodeOffsets; + var decodeScales = decodeParams.decodeScales; - var attribStart = meshParams.attribRange[0]; - var numVerts = meshParams.attribRange[1]; + var attribStart = meshParams.attribRange[0]; + var numVerts = meshParams.attribRange[1]; // Decode attributes. - var inputOffset = attribStart; - var attribsOut = new Float32Array( stride * numVerts ); + var inputOffset = attribStart; + var attribsOut = new Float32Array( stride * numVerts ); - for (var j = 0; j < stride; j ++ ) { + for (var j = 0; j < stride; j ++ ) { - var end = inputOffset + numVerts; + var end = inputOffset + numVerts; var decodeScale = decodeScales[j]; - if ( decodeScale ) { + if ( decodeScale ) { // Assume if decodeScale is never set, simply ignore the // attribute. - this.decompressAttribsInner_( str, inputOffset, end, + this.decompressAttribsInner_( str, inputOffset, end, attribsOut, j, stride, decodeOffsets[j], decodeScale ); - } + } - inputOffset = end; + inputOffset = end; - } + } - var indexStart = meshParams.indexRange[ 0 ]; - var numIndices = 3 * meshParams.indexRange[ 1 ]; + var indexStart = meshParams.indexRange[ 0 ]; + var numIndices = 3 * meshParams.indexRange[ 1 ]; - var indicesOut = new Uint16Array( numIndices ); + var indicesOut = new Uint16Array( numIndices ); - this.decompressIndices_( str, inputOffset, numIndices, indicesOut, 0 ); + this.decompressIndices_( str, inputOffset, numIndices, indicesOut, 0 ); // Decode bboxen. - var bboxen = undefined; - var bboxOffset = meshParams.bboxes; + var bboxen = undefined; + var bboxOffset = meshParams.bboxes; - if ( bboxOffset ) { + if ( bboxOffset ) { - bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales ); - } + bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales ); + } - callback( name, idx, attribsOut, indicesOut, bboxen, meshParams ); + callback( name, idx, attribsOut, indicesOut, bboxen, meshParams ); }; THREE.UTF8Loader.prototype.copyAttrib = function ( stride, attribsOutFixed, lastAttrib, index ) { - for ( var j = 0; j < stride; j ++ ) { + for ( var j = 0; j < stride; j ++ ) { - lastAttrib[ j ] = attribsOutFixed[ stride * index + j ]; + lastAttrib[ j ] = attribsOutFixed[ stride * index + j ]; - } + } }; @@ -298,343 +298,343 @@ THREE.UTF8Loader.prototype.decodeAttrib2 = function ( str, stride, decodeOffsets numVerts, attribsOut, attribsOutFixed, lastAttrib, index ) { - for ( var j = 0; j < 5; j ++ ) { + for ( var j = 0; j < 5; j ++ ) { - var code = str.charCodeAt( deltaStart + numVerts * j + index ); - var delta = ( code >> 1) ^ (-(code & 1)); + var code = str.charCodeAt( deltaStart + numVerts * j + index ); + var delta = ( code >> 1) ^ (-(code & 1)); - lastAttrib[ j ] += delta; - attribsOutFixed[ stride * index + j ] = lastAttrib[ j ]; - attribsOut[ stride * index + j ] = decodeScales[ j ] * ( lastAttrib[ j ] + decodeOffsets[ j ] ); - } + lastAttrib[ j ] += delta; + attribsOutFixed[ stride * index + j ] = lastAttrib[ j ]; + attribsOut[ stride * index + j ] = decodeScales[ j ] * ( lastAttrib[ j ] + decodeOffsets[ j ] ); + } }; THREE.UTF8Loader.prototype.accumulateNormal = function ( i0, i1, i2, attribsOutFixed, crosses ) { - var p0x = attribsOutFixed[ 8 * i0 ]; - var p0y = attribsOutFixed[ 8 * i0 + 1 ]; - var p0z = attribsOutFixed[ 8 * i0 + 2 ]; + var p0x = attribsOutFixed[ 8 * i0 ]; + var p0y = attribsOutFixed[ 8 * i0 + 1 ]; + var p0z = attribsOutFixed[ 8 * i0 + 2 ]; - var p1x = attribsOutFixed[ 8 * i1 ]; - var p1y = attribsOutFixed[ 8 * i1 + 1 ]; - var p1z = attribsOutFixed[ 8 * i1 + 2 ]; + var p1x = attribsOutFixed[ 8 * i1 ]; + var p1y = attribsOutFixed[ 8 * i1 + 1 ]; + var p1z = attribsOutFixed[ 8 * i1 + 2 ]; - var p2x = attribsOutFixed[ 8 * i2 ]; - var p2y = attribsOutFixed[ 8 * i2 + 1 ]; - var p2z = attribsOutFixed[ 8 * i2 + 2 ]; + var p2x = attribsOutFixed[ 8 * i2 ]; + var p2y = attribsOutFixed[ 8 * i2 + 1 ]; + var p2z = attribsOutFixed[ 8 * i2 + 2 ]; - p1x -= p0x; - p1y -= p0y; - p1z -= p0z; + p1x -= p0x; + p1y -= p0y; + p1z -= p0z; - p2x -= p0x; - p2y -= p0y; - p2z -= p0z; + p2x -= p0x; + p2y -= p0y; + p2z -= p0z; - p0x = p1y * p2z - p1z * p2y; - p0y = p1z * p2x - p1x * p2z; - p0z = p1x * p2y - p1y * p2x; + p0x = p1y * p2z - p1z * p2y; + p0y = p1z * p2x - p1x * p2z; + p0z = p1x * p2y - p1y * p2x; - crosses[ 3 * i0 ] += p0x; - crosses[ 3 * i0 + 1 ] += p0y; - crosses[ 3 * i0 + 2 ] += p0z; + crosses[ 3 * i0 ] += p0x; + crosses[ 3 * i0 + 1 ] += p0y; + crosses[ 3 * i0 + 2 ] += p0z; - crosses[ 3 * i1 ] += p0x; - crosses[ 3 * i1 + 1 ] += p0y; - crosses[ 3 * i1 + 2 ] += p0z; + crosses[ 3 * i1 ] += p0x; + crosses[ 3 * i1 + 1 ] += p0y; + crosses[ 3 * i1 + 2 ] += p0z; - crosses[ 3 * i2 ] += p0x; - crosses[ 3 * i2 + 1 ] += p0y; - crosses[ 3 * i2 + 2 ] += p0z; + crosses[ 3 * i2 ] += p0x; + crosses[ 3 * i2 + 1 ] += p0y; + crosses[ 3 * i2 + 2 ] += p0z; }; THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodeParams, name, idx, callback ) { - var MAX_BACKREF = 96; + var MAX_BACKREF = 96; // Extract conversion parameters from attribArrays. - var stride = decodeParams.decodeScales.length; + var stride = decodeParams.decodeScales.length; var decodeOffsets = decodeParams.decodeOffsets; - var decodeScales = decodeParams.decodeScales; + var decodeScales = decodeParams.decodeScales; - var deltaStart = meshParams.attribRange[ 0 ]; - var numVerts = meshParams.attribRange[ 1 ]; + var deltaStart = meshParams.attribRange[ 0 ]; + var numVerts = meshParams.attribRange[ 1 ]; - var codeStart = meshParams.codeRange[ 0 ]; - var codeLength = meshParams.codeRange[ 1 ]; + var codeStart = meshParams.codeRange[ 0 ]; + var codeLength = meshParams.codeRange[ 1 ]; - var numIndices = 3 * meshParams.codeRange[ 2 ]; + var numIndices = 3 * meshParams.codeRange[ 2 ]; - var indicesOut = new Uint16Array( numIndices ); + var indicesOut = new Uint16Array( numIndices ); - var crosses = new Int32Array( 3 * numVerts ); + var crosses = new Int32Array( 3 * numVerts ); - var lastAttrib = new Uint16Array( stride ); + var lastAttrib = new Uint16Array( stride ); - var attribsOutFixed = new Uint16Array( stride * numVerts ); - var attribsOut = new Float32Array( stride * numVerts ); + var attribsOutFixed = new Uint16Array( stride * numVerts ); + var attribsOut = new Float32Array( stride * numVerts ); - var highest = 0; - var outputStart = 0; + var highest = 0; + var outputStart = 0; - for ( var i = 0; i < numIndices; i += 3 ) { + for ( var i = 0; i < numIndices; i += 3 ) { - var code = str.charCodeAt( codeStart ++ ); + var code = str.charCodeAt( codeStart ++ ); - var max_backref = Math.min( i, MAX_BACKREF ); + var max_backref = Math.min( i, MAX_BACKREF ); - if ( code < max_backref ) { + if ( code < max_backref ) { // Parallelogram - var winding = code % 3; - var backref = i - ( code - winding ); - var i0, i1, i2; + var winding = code % 3; + var backref = i - ( code - winding ); + var i0, i1, i2; - switch ( winding ) { + switch ( winding ) { - case 0: + case 0: - i0 = indicesOut[ backref + 2 ]; - i1 = indicesOut[ backref + 1 ]; - i2 = indicesOut[ backref + 0 ]; - break; + i0 = indicesOut[ backref + 2 ]; + i1 = indicesOut[ backref + 1 ]; + i2 = indicesOut[ backref + 0 ]; + break; - case 1: + case 1: - i0 = indicesOut[ backref + 0 ]; - i1 = indicesOut[ backref + 2 ]; - i2 = indicesOut[ backref + 1 ]; - break; + i0 = indicesOut[ backref + 0 ]; + i1 = indicesOut[ backref + 2 ]; + i2 = indicesOut[ backref + 1 ]; + break; - case 2: + case 2: - i0 = indicesOut[ backref + 1 ]; - i1 = indicesOut[ backref + 0 ]; - i2 = indicesOut[ backref + 2 ]; - break; + i0 = indicesOut[ backref + 1 ]; + i1 = indicesOut[ backref + 0 ]; + i2 = indicesOut[ backref + 2 ]; + break; - } + } - indicesOut[ outputStart ++ ] = i0; - indicesOut[ outputStart ++ ] = i1; + indicesOut[ outputStart ++ ] = i0; + indicesOut[ outputStart ++ ] = i1; - code = str.charCodeAt( codeStart ++ ); + code = str.charCodeAt( codeStart ++ ); - var index = highest - code; - indicesOut[ outputStart ++ ] = index; + var index = highest - code; + indicesOut[ outputStart ++ ] = index; - if ( code === 0 ) { + if ( code === 0 ) { - for (var j = 0; j < 5; j ++ ) { + for (var j = 0; j < 5; j ++ ) { - var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest ); + var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest ); - var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) + + var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) + attribsOutFixed[stride * i0 + j] + attribsOutFixed[stride * i1 + j] - attribsOutFixed[stride * i2 + j]; - lastAttrib[j] = prediction; + lastAttrib[j] = prediction; - attribsOutFixed[ stride * highest + j ] = prediction; - attribsOut[ stride * highest + j ] = decodeScales[ j ] * ( prediction + decodeOffsets[ j ] ); + attribsOutFixed[ stride * highest + j ] = prediction; + attribsOut[ stride * highest + j ] = decodeScales[ j ] * ( prediction + decodeOffsets[ j ] ); - } + } - highest ++; + highest ++; - } else { + } else { - this.copyAttrib( stride, attribsOutFixed, lastAttrib, index ); + this.copyAttrib( stride, attribsOutFixed, lastAttrib, index ); - } + } - this.accumulateNormal( i0, i1, index, attribsOutFixed, crosses ); + this.accumulateNormal( i0, i1, index, attribsOutFixed, crosses ); - } else { + } else { // Simple - var index0 = highest - ( code - max_backref ); + var index0 = highest - ( code - max_backref ); - indicesOut[ outputStart ++ ] = index0; + indicesOut[ outputStart ++ ] = index0; - if ( code === max_backref ) { + if ( code === max_backref ) { - this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart, + this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart, numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ ); - } else { + } else { - this.copyAttrib(stride, attribsOutFixed, lastAttrib, index0); + this.copyAttrib(stride, attribsOutFixed, lastAttrib, index0); - } + } - code = str.charCodeAt( codeStart ++ ); + code = str.charCodeAt( codeStart ++ ); - var index1 = highest - code; - indicesOut[ outputStart ++ ] = index1; + var index1 = highest - code; + indicesOut[ outputStart ++ ] = index1; - if ( code === 0 ) { + if ( code === 0 ) { - this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart, + this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart, numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ ); - } else { + } else { - this.copyAttrib( stride, attribsOutFixed, lastAttrib, index1 ); + this.copyAttrib( stride, attribsOutFixed, lastAttrib, index1 ); - } + } - code = str.charCodeAt( codeStart ++ ); + code = str.charCodeAt( codeStart ++ ); - var index2 = highest - code; - indicesOut[ outputStart ++ ] = index2; + var index2 = highest - code; + indicesOut[ outputStart ++ ] = index2; - if ( code === 0 ) { + if ( code === 0 ) { - for ( var j = 0; j < 5; j ++ ) { + for ( var j = 0; j < 5; j ++ ) { - lastAttrib[ j ] = ( attribsOutFixed[ stride * index0 + j ] + attribsOutFixed[ stride * index1 + j ] ) / 2; + lastAttrib[ j ] = ( attribsOutFixed[ stride * index0 + j ] + attribsOutFixed[ stride * index1 + j ] ) / 2; - } + } - this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart, + this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart, numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ ); - } else { + } else { - this.copyAttrib( stride, attribsOutFixed, lastAttrib, index2 ); + this.copyAttrib( stride, attribsOutFixed, lastAttrib, index2 ); - } + } - this.accumulateNormal( index0, index1, index2, attribsOutFixed, crosses ); + this.accumulateNormal( index0, index1, index2, attribsOutFixed, crosses ); - } + } - } + } - for ( var i = 0; i < numVerts; i ++ ) { + for ( var i = 0; i < numVerts; i ++ ) { - var nx = crosses[ 3 * i ]; - var ny = crosses[ 3 * i + 1 ]; - var nz = crosses[ 3 * i + 2 ]; + var nx = crosses[ 3 * i ]; + var ny = crosses[ 3 * i + 1 ]; + var nz = crosses[ 3 * i + 2 ]; - var norm = 511.0 / Math.sqrt( nx * nx + ny * ny + nz * nz ); + var norm = 511.0 / Math.sqrt( nx * nx + ny * ny + nz * nz ); - var cx = str.charCodeAt( deltaStart + 5 * numVerts + i ); - var cy = str.charCodeAt( deltaStart + 6 * numVerts + i ); - var cz = str.charCodeAt( deltaStart + 7 * numVerts + i ); + var cx = str.charCodeAt( deltaStart + 5 * numVerts + i ); + var cy = str.charCodeAt( deltaStart + 6 * numVerts + i ); + var cz = str.charCodeAt( deltaStart + 7 * numVerts + i ); - attribsOut[ stride * i + 5 ] = norm * nx + ((cx >> 1) ^ (-(cx & 1))); - attribsOut[ stride * i + 6 ] = norm * ny + ((cy >> 1) ^ (-(cy & 1))); - attribsOut[ stride * i + 7 ] = norm * nz + ((cz >> 1) ^ (-(cz & 1))); - } + attribsOut[ stride * i + 5 ] = norm * nx + ((cx >> 1) ^ (-(cx & 1))); + attribsOut[ stride * i + 6 ] = norm * ny + ((cy >> 1) ^ (-(cy & 1))); + attribsOut[ stride * i + 7 ] = norm * nz + ((cz >> 1) ^ (-(cz & 1))); + } - callback( name, idx, attribsOut, indicesOut, undefined, meshParams ); + callback( name, idx, attribsOut, indicesOut, undefined, meshParams ); }; THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, decodeParams, callback ) { - var loader = this; - var idx = 0; + var loader = this; + var idx = 0; - function onprogress( req, e ) { + function onprogress( req, e ) { - while ( idx < meshEntry.length ) { + while ( idx < meshEntry.length ) { - var meshParams = meshEntry[ idx ]; - var indexRange = meshParams.indexRange; + var meshParams = meshEntry[ idx ]; + var indexRange = meshParams.indexRange; - if ( indexRange ) { + if ( indexRange ) { - var meshEnd = indexRange[ 0 ] + 3 * indexRange[ 1 ]; + var meshEnd = indexRange[ 0 ] + 3 * indexRange[ 1 ]; - if ( req.responseText.length < meshEnd ) break; + if ( req.responseText.length < meshEnd ) break; - loader.decompressMesh( req.responseText, meshParams, decodeParams, name, idx, callback ); + loader.decompressMesh( req.responseText, meshParams, decodeParams, name, idx, callback ); - } else { + } else { - var codeRange = meshParams.codeRange; - var meshEnd = codeRange[ 0 ] + codeRange[ 1 ]; + var codeRange = meshParams.codeRange; + var meshEnd = codeRange[ 0 ] + codeRange[ 1 ]; - if ( req.responseText.length < meshEnd ) break; + if ( req.responseText.length < meshEnd ) break; - loader.decompressMesh2( req.responseText, meshParams, decodeParams, name, idx, callback ); - } + loader.decompressMesh2( req.responseText, meshParams, decodeParams, name, idx, callback ); + } - ++ idx; + ++ idx; - } + } - }; + }; - getHttpRequest( path, function( req, e ) { + getHttpRequest( path, function( req, e ) { - if ( req.status === 200 || req.status === 0 ) { + if ( req.status === 200 || req.status === 0 ) { - onprogress( req, e ); + onprogress( req, e ); - } + } // TODO: handle errors. - }, onprogress ); + }, onprogress ); }; THREE.UTF8Loader.prototype.downloadMeshes = function ( path, meshUrlMap, decodeParams, callback ) { - for ( var url in meshUrlMap ) { + for ( var url in meshUrlMap ) { - var meshEntry = meshUrlMap[url]; - this.downloadMesh( path + url, url, meshEntry, decodeParams, callback ); + var meshEntry = meshUrlMap[url]; + this.downloadMesh( path + url, url, meshEntry, decodeParams, callback ); - } + } }; THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadModelInfo, allDoneCallback ) { var nCompletedUrls = 0; - var nExpectedUrls = 0; + var nExpectedUrls = 0; - var expectedMeshesPerUrl = {}; - var decodedMeshesPerUrl = {}; + var expectedMeshesPerUrl = {}; + var decodedMeshesPerUrl = {}; var modelParts = {}; var meshUrlMap = loadModelInfo.urls; - for ( var url in meshUrlMap ) { + for ( var url in meshUrlMap ) { - expectedMeshesPerUrl[ url ] = meshUrlMap[ url ].length; - decodedMeshesPerUrl[ url ] = 0; + expectedMeshesPerUrl[ url ] = meshUrlMap[ url ].length; + decodedMeshesPerUrl[ url ] = 0; nExpectedUrls ++; - modelParts[ url ] = new THREE.Object3D(); + modelParts[ url ] = new THREE.Object3D(); - } + } - var model = new THREE.Object3D(); + var model = new THREE.Object3D(); // Prepare materials first... - var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options ); - materialCreator.setMaterials( loadModelInfo.materials ); + var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options ); + materialCreator.setMaterials( loadModelInfo.materials ); - materialCreator.preload(); + materialCreator.preload(); // Create callback for creating mesh parts @@ -652,32 +652,32 @@ THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadM // meshParams contains the material info var geometry = bufferGeometryCreator.create( attribArray, indexArray ); - var material = materialCreator.create( meshParams.material ); + var material = materialCreator.create( meshParams.material ); var mesh = new THREE.Mesh( geometry, material ); - modelParts[ name ].add( mesh ); + modelParts[ name ].add( mesh ); //model.add(new THREE.Mesh(geometry, material)); - decodedMeshesPerUrl[ name ] ++; + decodedMeshesPerUrl[ name ] ++; - if ( decodedMeshesPerUrl[ name ] === expectedMeshesPerUrl[ name ] ) { + if ( decodedMeshesPerUrl[ name ] === expectedMeshesPerUrl[ name ] ) { - nCompletedUrls ++; + nCompletedUrls ++; - model.add( modelParts[ name ] ); + model.add( modelParts[ name ] ); - if ( nCompletedUrls === nExpectedUrls ) { + if ( nCompletedUrls === nExpectedUrls ) { // ALL DONE!!! - allDoneCallback( model ); + allDoneCallback( model ); - } + } - } + } - }; + }; return meshCallback; @@ -685,61 +685,61 @@ THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadM THREE.UTF8Loader.prototype.downloadModel = function ( geometryBase, materialBase, model, callback ) { - var meshCallback = this.createMeshCallback( materialBase, model, callback ); - this.downloadMeshes( geometryBase, model.urls, model.decodeParams, meshCallback ); + var meshCallback = this.createMeshCallback( materialBase, model, callback ); + this.downloadMeshes( geometryBase, model.urls, model.decodeParams, meshCallback ); }; THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, callback, options ) { - getJsonRequest( jsonUrl, function( loaded ) { + getJsonRequest( jsonUrl, function( loaded ) { - if ( ! loaded.decodeParams ) { + if ( ! loaded.decodeParams ) { - if ( options && options.decodeParams ) { + if ( options && options.decodeParams ) { - loaded.decodeParams = options.decodeParams; + loaded.decodeParams = options.decodeParams; - } else { + } else { - loaded.decodeParams = DEFAULT_DECODE_PARAMS; + loaded.decodeParams = DEFAULT_DECODE_PARAMS; - } + } - } + } - loaded.options = options; + loaded.options = options; - var geometryBase = jsonUrl.substr( 0, jsonUrl.lastIndexOf( "/" ) + 1 ); - var materialBase = geometryBase; + var geometryBase = jsonUrl.substr( 0, jsonUrl.lastIndexOf( "/" ) + 1 ); + var materialBase = geometryBase; - if ( options && options.geometryBase ) { + if ( options && options.geometryBase ) { - geometryBase = options.geometryBase; + geometryBase = options.geometryBase; - if ( geometryBase.charAt( geometryBase.length - 1 ) !== "/" ) { + if ( geometryBase.charAt( geometryBase.length - 1 ) !== "/" ) { - geometryBase = geometryBase + "/"; + geometryBase = geometryBase + "/"; - } + } - } + } - if ( options && options.materialBase ) { + if ( options && options.materialBase ) { - materialBase = options.materialBase; + materialBase = options.materialBase; - if ( materialBase.charAt( materialBase.length - 1 ) !== "/" ) { + if ( materialBase.charAt( materialBase.length - 1 ) !== "/" ) { - materialBase = materialBase + "/"; + materialBase = materialBase + "/"; - } + } - } + } - this.downloadModel( geometryBase, materialBase, loaded, callback ); + this.downloadModel( geometryBase, materialBase, loaded, callback ); - }.bind( this ) ); + }.bind( this ) ); }; @@ -747,23 +747,23 @@ THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, callback, opt function getHttpRequest( url, onload, opt_onprogress ) { - var LISTENERS = { + var LISTENERS = { load: function( e ) { onload( req, e ); }, progress: function( e ) { opt_onprogress( req, e ); } }; - var req = new XMLHttpRequest(); - addListeners( req, LISTENERS ); + var req = new XMLHttpRequest(); + addListeners( req, LISTENERS ); - req.open( 'GET', url, true ); - req.send( null ); + req.open( 'GET', url, true ); + req.send( null ); } function getJsonRequest( url, onjson ) { - getHttpRequest( url, + getHttpRequest( url, function( e ) { onjson( JSON.parse( e.responseText ) ); }, function() {} ); @@ -773,9 +773,9 @@ function addListeners( dom, listeners ) { // TODO: handle event capture, object binding. - for ( var key in listeners ) { + for ( var key in listeners ) { - dom.addEventListener( key, listeners[ key ] ); + dom.addEventListener( key, listeners[ key ] ); - } + } } diff --git a/examples/js/loaders/VRMLLoader.js b/examples/js/loaders/VRMLLoader.js index bf67886d4c56da..526434e7b7481e 100644 --- a/examples/js/loaders/VRMLLoader.js +++ b/examples/js/loaders/VRMLLoader.js @@ -260,7 +260,7 @@ THREE.VRMLLoader.prototype = { // end of current face if (parts[ind] === "-1") { if (index.length > 0) { - this.indexes.push(index); + this.indexes.push(index); } // start new one diff --git a/examples/js/loaders/ctm/ctm.js b/examples/js/loaders/ctm/ctm.js index df5c1f6f7d7a6d..f1f2a5277d5875 100755 --- a/examples/js/loaders/ctm/ctm.js +++ b/examples/js/loaders/ctm/ctm.js @@ -46,552 +46,552 @@ CTM.Flags = { }; CTM.File = function(stream) { - this.load(stream); + this.load(stream); }; CTM.File.prototype.load = function(stream) { - this.header = new CTM.FileHeader(stream); + this.header = new CTM.FileHeader(stream); - this.body = new CTM.FileBody(this.header); + this.body = new CTM.FileBody(this.header); - this.getReader().read(stream, this.body); + this.getReader().read(stream, this.body); }; CTM.File.prototype.getReader = function() { - var reader; + var reader; - switch (this.header.compressionMethod){ - case CTM.CompressionMethod.RAW: - reader = new CTM.ReaderRAW(); - break; - case CTM.CompressionMethod.MG1: - reader = new CTM.ReaderMG1(); - break; - case CTM.CompressionMethod.MG2: - reader = new CTM.ReaderMG2(); - break; - } + switch (this.header.compressionMethod){ + case CTM.CompressionMethod.RAW: + reader = new CTM.ReaderRAW(); + break; + case CTM.CompressionMethod.MG1: + reader = new CTM.ReaderMG1(); + break; + case CTM.CompressionMethod.MG2: + reader = new CTM.ReaderMG2(); + break; + } - return reader; + return reader; }; CTM.FileHeader = function(stream) { - stream.readInt32(); //magic "OCTM" - this.fileFormat = stream.readInt32(); - this.compressionMethod = stream.readInt32(); - this.vertexCount = stream.readInt32(); - this.triangleCount = stream.readInt32(); - this.uvMapCount = stream.readInt32(); - this.attrMapCount = stream.readInt32(); - this.flags = stream.readInt32(); - this.comment = stream.readString(); + stream.readInt32(); //magic "OCTM" + this.fileFormat = stream.readInt32(); + this.compressionMethod = stream.readInt32(); + this.vertexCount = stream.readInt32(); + this.triangleCount = stream.readInt32(); + this.uvMapCount = stream.readInt32(); + this.attrMapCount = stream.readInt32(); + this.flags = stream.readInt32(); + this.comment = stream.readString(); }; CTM.FileHeader.prototype.hasNormals = function() { - return this.flags & CTM.Flags.NORMALS; + return this.flags & CTM.Flags.NORMALS; }; CTM.FileBody = function(header) { - var i = header.triangleCount * 3, + var i = header.triangleCount * 3, v = header.vertexCount * 3, n = header.hasNormals() ? header.vertexCount * 3 : 0, u = header.vertexCount * 2, a = header.vertexCount * 4, j = 0; - var data = new ArrayBuffer( + var data = new ArrayBuffer( (i + v + n + (u * header.uvMapCount) + (a * header.attrMapCount) ) * 4); - this.indices = new Uint32Array(data, 0, i); + this.indices = new Uint32Array(data, 0, i); - this.vertices = new Float32Array(data, i * 4, v); + this.vertices = new Float32Array(data, i * 4, v); - if ( header.hasNormals() ) { - this.normals = new Float32Array(data, (i + v) * 4, n); - } + if ( header.hasNormals() ) { + this.normals = new Float32Array(data, (i + v) * 4, n); + } - if (header.uvMapCount) { - this.uvMaps = []; - for (j = 0; j < header.uvMapCount; ++ j) { - this.uvMaps[j] = { uv: new Float32Array(data, + if (header.uvMapCount) { + this.uvMaps = []; + for (j = 0; j < header.uvMapCount; ++ j) { + this.uvMaps[j] = { uv: new Float32Array(data, (i + v + n + (j * u) ) * 4, u) }; - } - } + } + } - if (header.attrMapCount) { - this.attrMaps = []; - for (j = 0; j < header.attrMapCount; ++ j) { - this.attrMaps[j] = { attr: new Float32Array(data, + if (header.attrMapCount) { + this.attrMaps = []; + for (j = 0; j < header.attrMapCount; ++ j) { + this.attrMaps[j] = { attr: new Float32Array(data, (i + v + n + (u * header.uvMapCount) + (j * a) ) * 4, a) }; - } - } + } + } }; CTM.FileMG2Header = function(stream) { - stream.readInt32(); //magic "MG2H" - this.vertexPrecision = stream.readFloat32(); - this.normalPrecision = stream.readFloat32(); - this.lowerBoundx = stream.readFloat32(); - this.lowerBoundy = stream.readFloat32(); - this.lowerBoundz = stream.readFloat32(); - this.higherBoundx = stream.readFloat32(); - this.higherBoundy = stream.readFloat32(); - this.higherBoundz = stream.readFloat32(); - this.divx = stream.readInt32(); - this.divy = stream.readInt32(); - this.divz = stream.readInt32(); + stream.readInt32(); //magic "MG2H" + this.vertexPrecision = stream.readFloat32(); + this.normalPrecision = stream.readFloat32(); + this.lowerBoundx = stream.readFloat32(); + this.lowerBoundy = stream.readFloat32(); + this.lowerBoundz = stream.readFloat32(); + this.higherBoundx = stream.readFloat32(); + this.higherBoundy = stream.readFloat32(); + this.higherBoundz = stream.readFloat32(); + this.divx = stream.readInt32(); + this.divy = stream.readInt32(); + this.divz = stream.readInt32(); - this.sizex = (this.higherBoundx - this.lowerBoundx) / this.divx; - this.sizey = (this.higherBoundy - this.lowerBoundy) / this.divy; - this.sizez = (this.higherBoundz - this.lowerBoundz) / this.divz; + this.sizex = (this.higherBoundx - this.lowerBoundx) / this.divx; + this.sizey = (this.higherBoundy - this.lowerBoundy) / this.divy; + this.sizez = (this.higherBoundz - this.lowerBoundz) / this.divz; }; CTM.ReaderRAW = function() { }; CTM.ReaderRAW.prototype.read = function(stream, body) { - this.readIndices(stream, body.indices); - this.readVertices(stream, body.vertices); + this.readIndices(stream, body.indices); + this.readVertices(stream, body.vertices); - if (body.normals) { - this.readNormals(stream, body.normals); - } - if (body.uvMaps) { - this.readUVMaps(stream, body.uvMaps); - } - if (body.attrMaps) { - this.readAttrMaps(stream, body.attrMaps); - } + if (body.normals) { + this.readNormals(stream, body.normals); + } + if (body.uvMaps) { + this.readUVMaps(stream, body.uvMaps); + } + if (body.attrMaps) { + this.readAttrMaps(stream, body.attrMaps); + } }; CTM.ReaderRAW.prototype.readIndices = function(stream, indices) { - stream.readInt32(); //magic "INDX" - stream.readArrayInt32(indices); + stream.readInt32(); //magic "INDX" + stream.readArrayInt32(indices); }; CTM.ReaderRAW.prototype.readVertices = function(stream, vertices) { - stream.readInt32(); //magic "VERT" - stream.readArrayFloat32(vertices); + stream.readInt32(); //magic "VERT" + stream.readArrayFloat32(vertices); }; CTM.ReaderRAW.prototype.readNormals = function(stream, normals) { - stream.readInt32(); //magic "NORM" - stream.readArrayFloat32(normals); + stream.readInt32(); //magic "NORM" + stream.readArrayFloat32(normals); }; CTM.ReaderRAW.prototype.readUVMaps = function(stream, uvMaps) { - var i = 0; - for (; i < uvMaps.length; ++ i) { - stream.readInt32(); //magic "TEXC" + var i = 0; + for (; i < uvMaps.length; ++ i) { + stream.readInt32(); //magic "TEXC" - uvMaps[i].name = stream.readString(); - uvMaps[i].filename = stream.readString(); - stream.readArrayFloat32(uvMaps[i].uv); - } + uvMaps[i].name = stream.readString(); + uvMaps[i].filename = stream.readString(); + stream.readArrayFloat32(uvMaps[i].uv); + } }; CTM.ReaderRAW.prototype.readAttrMaps = function(stream, attrMaps) { - var i = 0; - for (; i < attrMaps.length; ++ i) { - stream.readInt32(); //magic "ATTR" + var i = 0; + for (; i < attrMaps.length; ++ i) { + stream.readInt32(); //magic "ATTR" - attrMaps[i].name = stream.readString(); - stream.readArrayFloat32(attrMaps[i].attr); - } + attrMaps[i].name = stream.readString(); + stream.readArrayFloat32(attrMaps[i].attr); + } }; CTM.ReaderMG1 = function() { }; CTM.ReaderMG1.prototype.read = function(stream, body) { - this.readIndices(stream, body.indices); - this.readVertices(stream, body.vertices); + this.readIndices(stream, body.indices); + this.readVertices(stream, body.vertices); - if (body.normals) { - this.readNormals(stream, body.normals); - } - if (body.uvMaps) { - this.readUVMaps(stream, body.uvMaps); - } - if (body.attrMaps) { - this.readAttrMaps(stream, body.attrMaps); - } + if (body.normals) { + this.readNormals(stream, body.normals); + } + if (body.uvMaps) { + this.readUVMaps(stream, body.uvMaps); + } + if (body.attrMaps) { + this.readAttrMaps(stream, body.attrMaps); + } }; CTM.ReaderMG1.prototype.readIndices = function(stream, indices) { - stream.readInt32(); //magic "INDX" - stream.readInt32(); //packed size + stream.readInt32(); //magic "INDX" + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(indices, 3); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(indices, 3); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - CTM.restoreIndices(indices, indices.length); + CTM.restoreIndices(indices, indices.length); }; CTM.ReaderMG1.prototype.readVertices = function(stream, vertices) { - stream.readInt32(); //magic "VERT" - stream.readInt32(); //packed size + stream.readInt32(); //magic "VERT" + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(vertices, 1); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(vertices, 1); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); }; CTM.ReaderMG1.prototype.readNormals = function(stream, normals) { - stream.readInt32(); //magic "NORM" - stream.readInt32(); //packed size + stream.readInt32(); //magic "NORM" + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(normals, 3); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(normals, 3); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); }; CTM.ReaderMG1.prototype.readUVMaps = function(stream, uvMaps) { - var i = 0; - for (; i < uvMaps.length; ++ i) { - stream.readInt32(); //magic "TEXC" + var i = 0; + for (; i < uvMaps.length; ++ i) { + stream.readInt32(); //magic "TEXC" - uvMaps[i].name = stream.readString(); - uvMaps[i].filename = stream.readString(); + uvMaps[i].name = stream.readString(); + uvMaps[i].filename = stream.readString(); - stream.readInt32(); //packed size + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - } + var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + } }; CTM.ReaderMG1.prototype.readAttrMaps = function(stream, attrMaps) { - var i = 0; - for (; i < attrMaps.length; ++ i) { - stream.readInt32(); //magic "ATTR" + var i = 0; + for (; i < attrMaps.length; ++ i) { + stream.readInt32(); //magic "ATTR" - attrMaps[i].name = stream.readString(); + attrMaps[i].name = stream.readString(); - stream.readInt32(); //packed size + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - } + var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + } }; CTM.ReaderMG2 = function() { }; CTM.ReaderMG2.prototype.read = function(stream, body) { - this.MG2Header = new CTM.FileMG2Header(stream); + this.MG2Header = new CTM.FileMG2Header(stream); - this.readVertices(stream, body.vertices); - this.readIndices(stream, body.indices); + this.readVertices(stream, body.vertices); + this.readIndices(stream, body.indices); - if (body.normals) { - this.readNormals(stream, body); - } - if (body.uvMaps) { - this.readUVMaps(stream, body.uvMaps); - } - if (body.attrMaps) { - this.readAttrMaps(stream, body.attrMaps); - } + if (body.normals) { + this.readNormals(stream, body); + } + if (body.uvMaps) { + this.readUVMaps(stream, body.uvMaps); + } + if (body.attrMaps) { + this.readAttrMaps(stream, body.attrMaps); + } }; CTM.ReaderMG2.prototype.readVertices = function(stream, vertices) { - stream.readInt32(); //magic "VERT" - stream.readInt32(); //packed size + stream.readInt32(); //magic "VERT" + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(vertices, 3); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(vertices, 3); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - var gridIndices = this.readGridIndices(stream, vertices); + var gridIndices = this.readGridIndices(stream, vertices); - CTM.restoreVertices(vertices, this.MG2Header, gridIndices, this.MG2Header.vertexPrecision); + CTM.restoreVertices(vertices, this.MG2Header, gridIndices, this.MG2Header.vertexPrecision); }; CTM.ReaderMG2.prototype.readGridIndices = function(stream, vertices) { - stream.readInt32(); //magic "GIDX" - stream.readInt32(); //packed size + stream.readInt32(); //magic "GIDX" + stream.readInt32(); //packed size - var gridIndices = new Uint32Array(vertices.length / 3); + var gridIndices = new Uint32Array(vertices.length / 3); - var interleaved = new CTM.InterleavedStream(gridIndices, 1); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(gridIndices, 1); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - CTM.restoreGridIndices(gridIndices, gridIndices.length); + CTM.restoreGridIndices(gridIndices, gridIndices.length); - return gridIndices; + return gridIndices; }; CTM.ReaderMG2.prototype.readIndices = function(stream, indices) { - stream.readInt32(); //magic "INDX" - stream.readInt32(); //packed size + stream.readInt32(); //magic "INDX" + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(indices, 3); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(indices, 3); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - CTM.restoreIndices(indices, indices.length); + CTM.restoreIndices(indices, indices.length); }; CTM.ReaderMG2.prototype.readNormals = function(stream, body) { - stream.readInt32(); //magic "NORM" - stream.readInt32(); //packed size + stream.readInt32(); //magic "NORM" + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(body.normals, 3); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(body.normals, 3); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - var smooth = CTM.calcSmoothNormals(body.indices, body.vertices); + var smooth = CTM.calcSmoothNormals(body.indices, body.vertices); - CTM.restoreNormals(body.normals, smooth, this.MG2Header.normalPrecision); + CTM.restoreNormals(body.normals, smooth, this.MG2Header.normalPrecision); }; CTM.ReaderMG2.prototype.readUVMaps = function(stream, uvMaps) { - var i = 0; - for (; i < uvMaps.length; ++ i) { - stream.readInt32(); //magic "TEXC" + var i = 0; + for (; i < uvMaps.length; ++ i) { + stream.readInt32(); //magic "TEXC" - uvMaps[i].name = stream.readString(); - uvMaps[i].filename = stream.readString(); + uvMaps[i].name = stream.readString(); + uvMaps[i].filename = stream.readString(); - var precision = stream.readFloat32(); + var precision = stream.readFloat32(); - stream.readInt32(); //packed size + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - CTM.restoreMap(uvMaps[i].uv, 2, precision); - } + CTM.restoreMap(uvMaps[i].uv, 2, precision); + } }; CTM.ReaderMG2.prototype.readAttrMaps = function(stream, attrMaps) { - var i = 0; - for (; i < attrMaps.length; ++ i) { - stream.readInt32(); //magic "ATTR" + var i = 0; + for (; i < attrMaps.length; ++ i) { + stream.readInt32(); //magic "ATTR" - attrMaps[i].name = stream.readString(); + attrMaps[i].name = stream.readString(); - var precision = stream.readFloat32(); + var precision = stream.readFloat32(); - stream.readInt32(); //packed size + stream.readInt32(); //packed size - var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4); - LZMA.decompress(stream, stream, interleaved, interleaved.data.length); + var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4); + LZMA.decompress(stream, stream, interleaved, interleaved.data.length); - CTM.restoreMap(attrMaps[i].attr, 4, precision); - } + CTM.restoreMap(attrMaps[i].attr, 4, precision); + } }; CTM.restoreIndices = function(indices, len) { - var i = 3; - if (len > 0) { - indices[2] += indices[0]; - indices[1] += indices[0]; - } - for (; i < len; i += 3) { - indices[i] += indices[i - 3]; + var i = 3; + if (len > 0) { + indices[2] += indices[0]; + indices[1] += indices[0]; + } + for (; i < len; i += 3) { + indices[i] += indices[i - 3]; - if (indices[i] === indices[i - 3]) { - indices[i + 1] += indices[i - 2]; - }else { - indices[i + 1] += indices[i]; - } + if (indices[i] === indices[i - 3]) { + indices[i + 1] += indices[i - 2]; + }else { + indices[i + 1] += indices[i]; + } - indices[i + 2] += indices[i]; - } + indices[i + 2] += indices[i]; + } }; CTM.restoreGridIndices = function(gridIndices, len) { - var i = 1; - for (; i < len; ++ i) { - gridIndices[i] += gridIndices[i - 1]; - } + var i = 1; + for (; i < len; ++ i) { + gridIndices[i] += gridIndices[i - 1]; + } }; CTM.restoreVertices = function(vertices, grid, gridIndices, precision) { - var gridIdx, delta, x, y, z, + var gridIdx, delta, x, y, z, intVertices = new Uint32Array(vertices.buffer, vertices.byteOffset, vertices.length), ydiv = grid.divx, zdiv = ydiv * grid.divy, prevGridIdx = 0x7fffffff, prevDelta = 0, i = 0, j = 0, len = gridIndices.length; - for (; i < len; j += 3) { - x = gridIdx = gridIndices[i ++]; + for (; i < len; j += 3) { + x = gridIdx = gridIndices[i ++]; - z = ~~(x / zdiv); - x -= ~~(z * zdiv); - y = ~~(x / ydiv); - x -= ~~(y * ydiv); + z = ~~(x / zdiv); + x -= ~~(z * zdiv); + y = ~~(x / ydiv); + x -= ~~(y * ydiv); - delta = intVertices[j]; - if (gridIdx === prevGridIdx) { - delta += prevDelta; - } + delta = intVertices[j]; + if (gridIdx === prevGridIdx) { + delta += prevDelta; + } - vertices[j] = grid.lowerBoundx + + vertices[j] = grid.lowerBoundx + x * grid.sizex + precision * delta; - vertices[j + 1] = grid.lowerBoundy + + vertices[j + 1] = grid.lowerBoundy + y * grid.sizey + precision * intVertices[j + 1]; - vertices[j + 2] = grid.lowerBoundz + + vertices[j + 2] = grid.lowerBoundz + z * grid.sizez + precision * intVertices[j + 2]; - prevGridIdx = gridIdx; - prevDelta = delta; - } + prevGridIdx = gridIdx; + prevDelta = delta; + } }; CTM.restoreNormals = function(normals, smooth, precision) { - var ro, phi, theta, sinPhi, + var ro, phi, theta, sinPhi, nx, ny, nz, by, bz, len, intNormals = new Uint32Array(normals.buffer, normals.byteOffset, normals.length), i = 0, k = normals.length, PI_DIV_2 = 3.141592653589793238462643 * 0.5; - for (; i < k; i += 3) { - ro = intNormals[i] * precision; - phi = intNormals[i + 1]; + for (; i < k; i += 3) { + ro = intNormals[i] * precision; + phi = intNormals[i + 1]; - if (phi === 0) { - normals[i] = smooth[i] * ro; - normals[i + 1] = smooth[i + 1] * ro; - normals[i + 2] = smooth[i + 2] * ro; - }else { + if (phi === 0) { + normals[i] = smooth[i] * ro; + normals[i + 1] = smooth[i + 1] * ro; + normals[i + 2] = smooth[i + 2] * ro; + }else { - if (phi <= 4) { - theta = (intNormals[i + 2] - 2) * PI_DIV_2; - }else { - theta = ( (intNormals[i + 2] * 4 / phi) - 2) * PI_DIV_2; - } + if (phi <= 4) { + theta = (intNormals[i + 2] - 2) * PI_DIV_2; + }else { + theta = ( (intNormals[i + 2] * 4 / phi) - 2) * PI_DIV_2; + } - phi *= precision * PI_DIV_2; - sinPhi = ro * Math.sin(phi); + phi *= precision * PI_DIV_2; + sinPhi = ro * Math.sin(phi); - nx = sinPhi * Math.cos(theta); - ny = sinPhi * Math.sin(theta); - nz = ro * Math.cos(phi); + nx = sinPhi * Math.cos(theta); + ny = sinPhi * Math.sin(theta); + nz = ro * Math.cos(phi); - bz = smooth[i + 1]; - by = smooth[i] - smooth[i + 2]; + bz = smooth[i + 1]; + by = smooth[i] - smooth[i + 2]; - len = Math.sqrt(2 * bz * bz + by * by); - if (len > 1e-20) { - by /= len; - bz /= len; - } + len = Math.sqrt(2 * bz * bz + by * by); + if (len > 1e-20) { + by /= len; + bz /= len; + } - normals[i] = smooth[i] * nz + + normals[i] = smooth[i] * nz + (smooth[i + 1] * bz - smooth[i + 2] * by) * ny - bz * nx; - normals[i + 1] = smooth[i + 1] * nz - + normals[i + 1] = smooth[i + 1] * nz - (smooth[i + 2] + smooth[i] ) * bz * ny + by * nx; - normals[i + 2] = smooth[i + 2] * nz + + normals[i + 2] = smooth[i + 2] * nz + (smooth[i] * by + smooth[i + 1] * bz) * ny + bz * nx; - } - } + } + } }; CTM.restoreMap = function(map, count, precision) { - var delta, value, + var delta, value, intMap = new Uint32Array(map.buffer, map.byteOffset, map.length), i = 0, j, len = map.length; - for (; i < count; ++ i) { - delta = 0; + for (; i < count; ++ i) { + delta = 0; - for (j = i; j < len; j += count) { - value = intMap[j]; + for (j = i; j < len; j += count) { + value = intMap[j]; - delta += value & 1 ? -( (value + 1) >> 1) : value >> 1; + delta += value & 1 ? -( (value + 1) >> 1) : value >> 1; - map[j] = delta * precision; - } - } + map[j] = delta * precision; + } + } }; CTM.calcSmoothNormals = function(indices, vertices) { - var smooth = new Float32Array(vertices.length), + var smooth = new Float32Array(vertices.length), indx, indy, indz, nx, ny, nz, v1x, v1y, v1z, v2x, v2y, v2z, len, i, k; - for (i = 0, k = indices.length; i < k;) { - indx = indices[i ++] * 3; - indy = indices[i ++] * 3; - indz = indices[i ++] * 3; - - v1x = vertices[indy] - vertices[indx]; - v2x = vertices[indz] - vertices[indx]; - v1y = vertices[indy + 1] - vertices[indx + 1]; - v2y = vertices[indz + 1] - vertices[indx + 1]; - v1z = vertices[indy + 2] - vertices[indx + 2]; - v2z = vertices[indz + 2] - vertices[indx + 2]; + for (i = 0, k = indices.length; i < k;) { + indx = indices[i ++] * 3; + indy = indices[i ++] * 3; + indz = indices[i ++] * 3; + + v1x = vertices[indy] - vertices[indx]; + v2x = vertices[indz] - vertices[indx]; + v1y = vertices[indy + 1] - vertices[indx + 1]; + v2y = vertices[indz + 1] - vertices[indx + 1]; + v1z = vertices[indy + 2] - vertices[indx + 2]; + v2z = vertices[indz + 2] - vertices[indx + 2]; - nx = v1y * v2z - v1z * v2y; - ny = v1z * v2x - v1x * v2z; - nz = v1x * v2y - v1y * v2x; + nx = v1y * v2z - v1z * v2y; + ny = v1z * v2x - v1x * v2z; + nz = v1x * v2y - v1y * v2x; - len = Math.sqrt(nx * nx + ny * ny + nz * nz); - if (len > 1e-10) { - nx /= len; - ny /= len; - nz /= len; - } + len = Math.sqrt(nx * nx + ny * ny + nz * nz); + if (len > 1e-10) { + nx /= len; + ny /= len; + nz /= len; + } - smooth[indx] += nx; - smooth[indx + 1] += ny; - smooth[indx + 2] += nz; - smooth[indy] += nx; - smooth[indy + 1] += ny; - smooth[indy + 2] += nz; - smooth[indz] += nx; - smooth[indz + 1] += ny; - smooth[indz + 2] += nz; - } - - for (i = 0, k = smooth.length; i < k; i += 3) { - len = Math.sqrt(smooth[i] * smooth[i] + + smooth[indx] += nx; + smooth[indx + 1] += ny; + smooth[indx + 2] += nz; + smooth[indy] += nx; + smooth[indy + 1] += ny; + smooth[indy + 2] += nz; + smooth[indz] += nx; + smooth[indz + 1] += ny; + smooth[indz + 2] += nz; + } + + for (i = 0, k = smooth.length; i < k; i += 3) { + len = Math.sqrt(smooth[i] * smooth[i] + smooth[i + 1] * smooth[i + 1] + smooth[i + 2] * smooth[i + 2]); - if (len > 1e-10) { - smooth[i] /= len; - smooth[i + 1] /= len; - smooth[i + 2] /= len; - } - } + if (len > 1e-10) { + smooth[i] /= len; + smooth[i + 1] /= len; + smooth[i + 2] /= len; + } + } - return smooth; + return smooth; }; CTM.isLittleEndian = (function() { - var buffer = new ArrayBuffer(2), + var buffer = new ArrayBuffer(2), bytes = new Uint8Array(buffer), ints = new Uint16Array(buffer); - bytes[0] = 1; + bytes[0] = 1; - return ints[0] === 1; + return ints[0] === 1; }()); CTM.InterleavedStream = function(data, count) { - this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); - this.offset = CTM.isLittleEndian ? 3 : 0; - this.count = count * 4; - this.len = this.data.length; + this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); + this.offset = CTM.isLittleEndian ? 3 : 0; + this.count = count * 4; + this.len = this.data.length; }; CTM.InterleavedStream.prototype.writeByte = function(value) { - this.data[this.offset] = value; + this.data[this.offset] = value; - this.offset += this.count; - if (this.offset >= this.len) { + this.offset += this.count; + if (this.offset >= this.len) { - this.offset -= this.len - 4; - if (this.offset >= this.count) { + this.offset -= this.len - 4; + if (this.offset >= this.count) { - this.offset -= this.count + (CTM.isLittleEndian ? 1 : -1); - } - } + this.offset -= this.count + (CTM.isLittleEndian ? 1 : -1); + } + } }; CTM.Stream = function(data) { - this.data = data; - this.offset = 0; + this.data = data; + this.offset = 0; }; CTM.Stream.prototype.TWO_POW_MINUS23 = Math.pow(2, -23); @@ -599,63 +599,63 @@ CTM.Stream.prototype.TWO_POW_MINUS23 = Math.pow(2, -23); CTM.Stream.prototype.TWO_POW_MINUS126 = Math.pow(2, -126); CTM.Stream.prototype.readByte = function() { - return this.data[this.offset ++] & 0xff; + return this.data[this.offset ++] & 0xff; }; CTM.Stream.prototype.readInt32 = function() { - var i = this.readByte(); - i |= this.readByte() << 8; - i |= this.readByte() << 16; - return i | (this.readByte() << 24); + var i = this.readByte(); + i |= this.readByte() << 8; + i |= this.readByte() << 16; + return i | (this.readByte() << 24); }; CTM.Stream.prototype.readFloat32 = function() { - var m = this.readByte(); - m += this.readByte() << 8; + var m = this.readByte(); + m += this.readByte() << 8; - var b1 = this.readByte(); - var b2 = this.readByte(); + var b1 = this.readByte(); + var b2 = this.readByte(); - m += (b1 & 0x7f) << 16; - var e = ( (b2 & 0x7f) << 1) | ( (b1 & 0x80) >>> 7); - var s = b2 & 0x80 ? -1 : 1; + m += (b1 & 0x7f) << 16; + var e = ( (b2 & 0x7f) << 1) | ( (b1 & 0x80) >>> 7); + var s = b2 & 0x80 ? -1 : 1; - if (e === 255) { - return m !== 0 ? NaN : s * Infinity; - } - if (e > 0) { - return s * (1 + (m * this.TWO_POW_MINUS23) ) * Math.pow(2, e - 127); - } - if (m !== 0) { - return s * m * this.TWO_POW_MINUS126; - } - return s * 0; + if (e === 255) { + return m !== 0 ? NaN : s * Infinity; + } + if (e > 0) { + return s * (1 + (m * this.TWO_POW_MINUS23) ) * Math.pow(2, e - 127); + } + if (m !== 0) { + return s * m * this.TWO_POW_MINUS126; + } + return s * 0; }; CTM.Stream.prototype.readString = function() { - var len = this.readInt32(); + var len = this.readInt32(); - this.offset += len; + this.offset += len; - return String.fromCharCode.apply(null, this.data.subarray(this.offset - len, this.offset)); + return String.fromCharCode.apply(null, this.data.subarray(this.offset - len, this.offset)); }; CTM.Stream.prototype.readArrayInt32 = function(array) { - var i = 0, len = array.length; + var i = 0, len = array.length; - while (i < len) { - array[i ++] = this.readInt32(); - } + while (i < len) { + array[i ++] = this.readInt32(); + } - return array; + return array; }; CTM.Stream.prototype.readArrayFloat32 = function(array) { - var i = 0, len = array.length; + var i = 0, len = array.length; - while (i < len) { - array[i ++] = this.readFloat32(); - } + while (i < len) { + array[i ++] = this.readFloat32(); + } - return array; + return array; }; diff --git a/examples/js/loaders/ctm/lzma.js b/examples/js/loaders/ctm/lzma.js index e2e83dee80ee64..9960f2592fd4b8 100644 --- a/examples/js/loaders/ctm/lzma.js +++ b/examples/js/loaders/ctm/lzma.js @@ -9,509 +9,509 @@ if ( typeof module === 'object' ) { } LZMA.OutWindow = function() { - this._windowSize = 0; + this._windowSize = 0; }; LZMA.OutWindow.prototype.create = function(windowSize) { - if ( (!this._buffer) || (this._windowSize !== windowSize) ) { - this._buffer = []; - } - this._windowSize = windowSize; - this._pos = 0; - this._streamPos = 0; + if ( (!this._buffer) || (this._windowSize !== windowSize) ) { + this._buffer = []; + } + this._windowSize = windowSize; + this._pos = 0; + this._streamPos = 0; }; LZMA.OutWindow.prototype.flush = function() { - var size = this._pos - this._streamPos; - if (size !== 0) { - while (size --) { - this._stream.writeByte(this._buffer[this._streamPos ++]); - } - if (this._pos >= this._windowSize) { - this._pos = 0; - } - this._streamPos = this._pos; - } + var size = this._pos - this._streamPos; + if (size !== 0) { + while (size --) { + this._stream.writeByte(this._buffer[this._streamPos ++]); + } + if (this._pos >= this._windowSize) { + this._pos = 0; + } + this._streamPos = this._pos; + } }; LZMA.OutWindow.prototype.releaseStream = function() { - this.flush(); - this._stream = null; + this.flush(); + this._stream = null; }; LZMA.OutWindow.prototype.setStream = function(stream) { - this.releaseStream(); - this._stream = stream; + this.releaseStream(); + this._stream = stream; }; LZMA.OutWindow.prototype.init = function(solid) { - if (!solid) { - this._streamPos = 0; - this._pos = 0; - } + if (!solid) { + this._streamPos = 0; + this._pos = 0; + } }; LZMA.OutWindow.prototype.copyBlock = function(distance, len) { - var pos = this._pos - distance - 1; - if (pos < 0) { - pos += this._windowSize; - } - while (len --) { - if (pos >= this._windowSize) { - pos = 0; - } - this._buffer[this._pos ++] = this._buffer[pos ++]; - if (this._pos >= this._windowSize) { - this.flush(); - } - } + var pos = this._pos - distance - 1; + if (pos < 0) { + pos += this._windowSize; + } + while (len --) { + if (pos >= this._windowSize) { + pos = 0; + } + this._buffer[this._pos ++] = this._buffer[pos ++]; + if (this._pos >= this._windowSize) { + this.flush(); + } + } }; LZMA.OutWindow.prototype.putByte = function(b) { - this._buffer[this._pos ++] = b; - if (this._pos >= this._windowSize) { - this.flush(); - } + this._buffer[this._pos ++] = b; + if (this._pos >= this._windowSize) { + this.flush(); + } }; LZMA.OutWindow.prototype.getByte = function(distance) { - var pos = this._pos - distance - 1; - if (pos < 0) { - pos += this._windowSize; - } - return this._buffer[pos]; + var pos = this._pos - distance - 1; + if (pos < 0) { + pos += this._windowSize; + } + return this._buffer[pos]; }; LZMA.RangeDecoder = function() { }; LZMA.RangeDecoder.prototype.setStream = function(stream) { - this._stream = stream; + this._stream = stream; }; LZMA.RangeDecoder.prototype.releaseStream = function() { - this._stream = null; + this._stream = null; }; LZMA.RangeDecoder.prototype.init = function() { - var i = 5; + var i = 5; - this._code = 0; - this._range = -1; + this._code = 0; + this._range = -1; - while (i --) { - this._code = (this._code << 8) | this._stream.readByte(); - } + while (i --) { + this._code = (this._code << 8) | this._stream.readByte(); + } }; LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits) { - var result = 0, i = numTotalBits, t; + var result = 0, i = numTotalBits, t; - while (i --) { - this._range >>>= 1; - t = (this._code - this._range) >>> 31; - this._code -= this._range & (t - 1); - result = (result << 1) | (1 - t); + while (i --) { + this._range >>>= 1; + t = (this._code - this._range) >>> 31; + this._code -= this._range & (t - 1); + result = (result << 1) | (1 - t); - if ( (this._range & 0xff000000) === 0) { - this._code = (this._code << 8) | this._stream.readByte(); - this._range <<= 8; - } - } + if ( (this._range & 0xff000000) === 0) { + this._code = (this._code << 8) | this._stream.readByte(); + this._range <<= 8; + } + } - return result; + return result; }; LZMA.RangeDecoder.prototype.decodeBit = function(probs, index) { - var prob = probs[index], + var prob = probs[index], newBound = (this._range >>> 11) * prob; - if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ) { - this._range = newBound; - probs[index] += (2048 - prob) >>> 5; - if ( (this._range & 0xff000000) === 0) { - this._code = (this._code << 8) | this._stream.readByte(); - this._range <<= 8; - } - return 0; - } - - this._range -= newBound; - this._code -= newBound; - probs[index] -= prob >>> 5; - if ( (this._range & 0xff000000) === 0) { - this._code = (this._code << 8) | this._stream.readByte(); - this._range <<= 8; - } - return 1; + if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ) { + this._range = newBound; + probs[index] += (2048 - prob) >>> 5; + if ( (this._range & 0xff000000) === 0) { + this._code = (this._code << 8) | this._stream.readByte(); + this._range <<= 8; + } + return 0; + } + + this._range -= newBound; + this._code -= newBound; + probs[index] -= prob >>> 5; + if ( (this._range & 0xff000000) === 0) { + this._code = (this._code << 8) | this._stream.readByte(); + this._range <<= 8; + } + return 1; }; LZMA.initBitModels = function(probs, len) { - while (len --) { - probs[len] = 1024; - } + while (len --) { + probs[len] = 1024; + } }; LZMA.BitTreeDecoder = function(numBitLevels) { - this._models = []; - this._numBitLevels = numBitLevels; + this._models = []; + this._numBitLevels = numBitLevels; }; LZMA.BitTreeDecoder.prototype.init = function() { - LZMA.initBitModels(this._models, 1 << this._numBitLevels); + LZMA.initBitModels(this._models, 1 << this._numBitLevels); }; LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder) { - var m = 1, i = this._numBitLevels; + var m = 1, i = this._numBitLevels; - while (i --) { - m = (m << 1) | rangeDecoder.decodeBit(this._models, m); - } - return m - (1 << this._numBitLevels); + while (i --) { + m = (m << 1) | rangeDecoder.decodeBit(this._models, m); + } + return m - (1 << this._numBitLevels); }; LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder) { - var m = 1, symbol = 0, i = 0, bit; + var m = 1, symbol = 0, i = 0, bit; - for (; i < this._numBitLevels; ++ i) { - bit = rangeDecoder.decodeBit(this._models, m); - m = (m << 1) | bit; - symbol |= bit << i; - } - return symbol; + for (; i < this._numBitLevels; ++ i) { + bit = rangeDecoder.decodeBit(this._models, m); + m = (m << 1) | bit; + symbol |= bit << i; + } + return symbol; }; LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels) { - var m = 1, symbol = 0, i = 0, bit; + var m = 1, symbol = 0, i = 0, bit; - for (; i < numBitLevels; ++ i) { - bit = rangeDecoder.decodeBit(models, startIndex + m); - m = (m << 1) | bit; - symbol |= bit << i; - } - return symbol; + for (; i < numBitLevels; ++ i) { + bit = rangeDecoder.decodeBit(models, startIndex + m); + m = (m << 1) | bit; + symbol |= bit << i; + } + return symbol; }; LZMA.LenDecoder = function() { - this._choice = []; - this._lowCoder = []; - this._midCoder = []; - this._highCoder = new LZMA.BitTreeDecoder(8); - this._numPosStates = 0; + this._choice = []; + this._lowCoder = []; + this._midCoder = []; + this._highCoder = new LZMA.BitTreeDecoder(8); + this._numPosStates = 0; }; LZMA.LenDecoder.prototype.create = function(numPosStates) { - for (; this._numPosStates < numPosStates; ++ this._numPosStates) { - this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3); - this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3); - } + for (; this._numPosStates < numPosStates; ++ this._numPosStates) { + this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3); + this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3); + } }; LZMA.LenDecoder.prototype.init = function() { - var i = this._numPosStates; - LZMA.initBitModels(this._choice, 2); - while (i --) { - this._lowCoder[i].init(); - this._midCoder[i].init(); - } - this._highCoder.init(); + var i = this._numPosStates; + LZMA.initBitModels(this._choice, 2); + while (i --) { + this._lowCoder[i].init(); + this._midCoder[i].init(); + } + this._highCoder.init(); }; LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState) { - if (rangeDecoder.decodeBit(this._choice, 0) === 0) { - return this._lowCoder[posState].decode(rangeDecoder); - } - if (rangeDecoder.decodeBit(this._choice, 1) === 0) { - return 8 + this._midCoder[posState].decode(rangeDecoder); - } - return 16 + this._highCoder.decode(rangeDecoder); + if (rangeDecoder.decodeBit(this._choice, 0) === 0) { + return this._lowCoder[posState].decode(rangeDecoder); + } + if (rangeDecoder.decodeBit(this._choice, 1) === 0) { + return 8 + this._midCoder[posState].decode(rangeDecoder); + } + return 16 + this._highCoder.decode(rangeDecoder); }; LZMA.Decoder2 = function() { - this._decoders = []; + this._decoders = []; }; LZMA.Decoder2.prototype.init = function() { - LZMA.initBitModels(this._decoders, 0x300); + LZMA.initBitModels(this._decoders, 0x300); }; LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder) { - var symbol = 1; + var symbol = 1; - do { - symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol); - }while (symbol < 0x100); + do { + symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol); + }while (symbol < 0x100); - return symbol & 0xff; + return symbol & 0xff; }; LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte) { - var symbol = 1, matchBit, bit; + var symbol = 1, matchBit, bit; - do { - matchBit = (matchByte >> 7) & 1; - matchByte <<= 1; - bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol); - symbol = (symbol << 1) | bit; - if (matchBit !== bit) { - while (symbol < 0x100) { - symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol); - } - break; - } - }while (symbol < 0x100); + do { + matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol); + symbol = (symbol << 1) | bit; + if (matchBit !== bit) { + while (symbol < 0x100) { + symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol); + } + break; + } + }while (symbol < 0x100); - return symbol & 0xff; + return symbol & 0xff; }; LZMA.LiteralDecoder = function() { }; LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits) { - var i; + var i; - if (this._coders + if (this._coders && (this._numPrevBits === numPrevBits) && (this._numPosBits === numPosBits) ) { - return; - } - this._numPosBits = numPosBits; - this._posMask = (1 << numPosBits) - 1; - this._numPrevBits = numPrevBits; + return; + } + this._numPosBits = numPosBits; + this._posMask = (1 << numPosBits) - 1; + this._numPrevBits = numPrevBits; - this._coders = []; + this._coders = []; - i = 1 << (this._numPrevBits + this._numPosBits); - while (i --) { - this._coders[i] = new LZMA.Decoder2(); - } + i = 1 << (this._numPrevBits + this._numPosBits); + while (i --) { + this._coders[i] = new LZMA.Decoder2(); + } }; LZMA.LiteralDecoder.prototype.init = function() { - var i = 1 << (this._numPrevBits + this._numPosBits); - while (i --) { - this._coders[i].init(); - } + var i = 1 << (this._numPrevBits + this._numPosBits); + while (i --) { + this._coders[i].init(); + } }; LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte) { - return this._coders[( (pos & this._posMask) << this._numPrevBits) + return this._coders[( (pos & this._posMask) << this._numPrevBits) + ( (prevByte & 0xff) >>> (8 - this._numPrevBits) )]; }; LZMA.Decoder = function() { - this._outWindow = new LZMA.OutWindow(); - this._rangeDecoder = new LZMA.RangeDecoder(); - this._isMatchDecoders = []; - this._isRepDecoders = []; - this._isRepG0Decoders = []; - this._isRepG1Decoders = []; - this._isRepG2Decoders = []; - this._isRep0LongDecoders = []; - this._posSlotDecoder = []; - this._posDecoders = []; - this._posAlignDecoder = new LZMA.BitTreeDecoder(4); - this._lenDecoder = new LZMA.LenDecoder(); - this._repLenDecoder = new LZMA.LenDecoder(); - this._literalDecoder = new LZMA.LiteralDecoder(); - this._dictionarySize = -1; - this._dictionarySizeCheck = -1; - - this._posSlotDecoder[0] = new LZMA.BitTreeDecoder(6); - this._posSlotDecoder[1] = new LZMA.BitTreeDecoder(6); - this._posSlotDecoder[2] = new LZMA.BitTreeDecoder(6); - this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6); + this._outWindow = new LZMA.OutWindow(); + this._rangeDecoder = new LZMA.RangeDecoder(); + this._isMatchDecoders = []; + this._isRepDecoders = []; + this._isRepG0Decoders = []; + this._isRepG1Decoders = []; + this._isRepG2Decoders = []; + this._isRep0LongDecoders = []; + this._posSlotDecoder = []; + this._posDecoders = []; + this._posAlignDecoder = new LZMA.BitTreeDecoder(4); + this._lenDecoder = new LZMA.LenDecoder(); + this._repLenDecoder = new LZMA.LenDecoder(); + this._literalDecoder = new LZMA.LiteralDecoder(); + this._dictionarySize = -1; + this._dictionarySizeCheck = -1; + + this._posSlotDecoder[0] = new LZMA.BitTreeDecoder(6); + this._posSlotDecoder[1] = new LZMA.BitTreeDecoder(6); + this._posSlotDecoder[2] = new LZMA.BitTreeDecoder(6); + this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6); }; LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize) { - if (dictionarySize < 0) { - return false; - } - if (this._dictionarySize !== dictionarySize) { - this._dictionarySize = dictionarySize; - this._dictionarySizeCheck = Math.max(this._dictionarySize, 1); - this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) ); - } - return true; + if (dictionarySize < 0) { + return false; + } + if (this._dictionarySize !== dictionarySize) { + this._dictionarySize = dictionarySize; + this._dictionarySizeCheck = Math.max(this._dictionarySize, 1); + this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) ); + } + return true; }; LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb) { - var numPosStates = 1 << pb; + var numPosStates = 1 << pb; - if (lc > 8 || lp > 4 || pb > 4) { - return false; - } + if (lc > 8 || lp > 4 || pb > 4) { + return false; + } - this._literalDecoder.create(lp, lc); + this._literalDecoder.create(lp, lc); - this._lenDecoder.create(numPosStates); - this._repLenDecoder.create(numPosStates); - this._posStateMask = numPosStates - 1; + this._lenDecoder.create(numPosStates); + this._repLenDecoder.create(numPosStates); + this._posStateMask = numPosStates - 1; - return true; + return true; }; LZMA.Decoder.prototype.init = function() { - var i = 4; + var i = 4; - this._outWindow.init(false); + this._outWindow.init(false); - LZMA.initBitModels(this._isMatchDecoders, 192); - LZMA.initBitModels(this._isRep0LongDecoders, 192); - LZMA.initBitModels(this._isRepDecoders, 12); - LZMA.initBitModels(this._isRepG0Decoders, 12); - LZMA.initBitModels(this._isRepG1Decoders, 12); - LZMA.initBitModels(this._isRepG2Decoders, 12); - LZMA.initBitModels(this._posDecoders, 114); + LZMA.initBitModels(this._isMatchDecoders, 192); + LZMA.initBitModels(this._isRep0LongDecoders, 192); + LZMA.initBitModels(this._isRepDecoders, 12); + LZMA.initBitModels(this._isRepG0Decoders, 12); + LZMA.initBitModels(this._isRepG1Decoders, 12); + LZMA.initBitModels(this._isRepG2Decoders, 12); + LZMA.initBitModels(this._posDecoders, 114); - this._literalDecoder.init(); + this._literalDecoder.init(); - while (i --) { - this._posSlotDecoder[i].init(); - } + while (i --) { + this._posSlotDecoder[i].init(); + } - this._lenDecoder.init(); - this._repLenDecoder.init(); - this._posAlignDecoder.init(); - this._rangeDecoder.init(); + this._lenDecoder.init(); + this._repLenDecoder.init(); + this._posAlignDecoder.init(); + this._rangeDecoder.init(); }; LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize) { - var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0, + var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0, posState, decoder2, len, distance, posSlot, numDirectBits; - this._rangeDecoder.setStream(inStream); - this._outWindow.setStream(outStream); - - this.init(); - - while (outSize < 0 || nowPos64 < outSize) { - posState = nowPos64 & this._posStateMask; - - if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0) { - decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte); - - if (state >= 7) { - prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) ); - }else { - prevByte = decoder2.decodeNormal(this._rangeDecoder); - } - this._outWindow.putByte(prevByte); - - state = state < 4 ? 0 : state - (state < 10 ? 3 : 6); - - }else { - - if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1) { - len = 0; - if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0) { - if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0) { - state = state < 7 ? 9 : 11; - len = 1; - } - }else { - if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0) { - distance = rep1; - }else { - if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0) { - distance = rep2; - }else { - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - if (len === 0) { - len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState); - state = state < 7 ? 8 : 11; - } - }else { - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - - len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState); - state = state < 7 ? 7 : 10; - - posSlot = this._posSlotDecoder[len <= 5 ? len - 2 : 3].decode(this._rangeDecoder); - if (posSlot >= 4) { - - numDirectBits = (posSlot >> 1) - 1; - rep0 = (2 | (posSlot & 1) ) << numDirectBits; - - if (posSlot < 14) { - rep0 += LZMA.reverseDecode2(this._posDecoders, + this._rangeDecoder.setStream(inStream); + this._outWindow.setStream(outStream); + + this.init(); + + while (outSize < 0 || nowPos64 < outSize) { + posState = nowPos64 & this._posStateMask; + + if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0) { + decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte); + + if (state >= 7) { + prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) ); + }else { + prevByte = decoder2.decodeNormal(this._rangeDecoder); + } + this._outWindow.putByte(prevByte); + + state = state < 4 ? 0 : state - (state < 10 ? 3 : 6); + + }else { + + if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1) { + len = 0; + if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0) { + if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0) { + state = state < 7 ? 9 : 11; + len = 1; + } + }else { + if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0) { + distance = rep1; + }else { + if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0) { + distance = rep2; + }else { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + if (len === 0) { + len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState); + state = state < 7 ? 8 : 11; + } + }else { + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + + len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState); + state = state < 7 ? 7 : 10; + + posSlot = this._posSlotDecoder[len <= 5 ? len - 2 : 3].decode(this._rangeDecoder); + if (posSlot >= 4) { + + numDirectBits = (posSlot >> 1) - 1; + rep0 = (2 | (posSlot & 1) ) << numDirectBits; + + if (posSlot < 14) { + rep0 += LZMA.reverseDecode2(this._posDecoders, rep0 - posSlot - 1, this._rangeDecoder, numDirectBits); - }else { - rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4; - rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder); - if (rep0 < 0) { - if (rep0 === -1) { - break; - } - return false; - } - } - }else { - rep0 = posSlot; - } - } - - if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck) { - return false; - } - - this._outWindow.copyBlock(rep0, len); - nowPos64 += len; - prevByte = this._outWindow.getByte(0); - } - } - - this._outWindow.flush(); - this._outWindow.releaseStream(); - this._rangeDecoder.releaseStream(); - - return true; + }else { + rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4; + rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder); + if (rep0 < 0) { + if (rep0 === -1) { + break; + } + return false; + } + } + }else { + rep0 = posSlot; + } + } + + if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck) { + return false; + } + + this._outWindow.copyBlock(rep0, len); + nowPos64 += len; + prevByte = this._outWindow.getByte(0); + } + } + + this._outWindow.flush(); + this._outWindow.releaseStream(); + this._rangeDecoder.releaseStream(); + + return true; }; LZMA.Decoder.prototype.setDecoderProperties = function(properties) { - var value, lc, lp, pb, dictionarySize; + var value, lc, lp, pb, dictionarySize; - if (properties.size < 5) { - return false; - } + if (properties.size < 5) { + return false; + } - value = properties.readByte(); - lc = value % 9; - value = ~~(value / 9); - lp = value % 5; - pb = ~~(value / 5); + value = properties.readByte(); + lc = value % 9; + value = ~~(value / 9); + lp = value % 5; + pb = ~~(value / 5); - if ( !this.setLcLpPb(lc, lp, pb) ) { - return false; - } + if ( !this.setLcLpPb(lc, lp, pb) ) { + return false; + } - dictionarySize = properties.readByte(); - dictionarySize |= properties.readByte() << 8; - dictionarySize |= properties.readByte() << 16; - dictionarySize += properties.readByte() * 16777216; + dictionarySize = properties.readByte(); + dictionarySize |= properties.readByte() << 8; + dictionarySize |= properties.readByte() << 16; + dictionarySize += properties.readByte() * 16777216; - return this.setDictionarySize(dictionarySize); + return this.setDictionarySize(dictionarySize); }; LZMA.decompress = function(properties, inStream, outStream, outSize) { - var decoder = new LZMA.Decoder(); + var decoder = new LZMA.Decoder(); - if ( !decoder.setDecoderProperties(properties) ) { - throw "Incorrect stream properties"; - } + if ( !decoder.setDecoderProperties(properties) ) { + throw "Incorrect stream properties"; + } - if ( !decoder.decode(inStream, outStream, outSize) ) { - throw "Error in data stream"; - } + if ( !decoder.decode(inStream, outStream, outSize) ) { + throw "Error in data stream"; + } - return true; + return true; }; diff --git a/examples/js/loaders/deprecated/SceneLoader.js b/examples/js/loaders/deprecated/SceneLoader.js index aa163f5ae9d65b..93447f7a73d466 100644 --- a/examples/js/loaders/deprecated/SceneLoader.js +++ b/examples/js/loaders/deprecated/SceneLoader.js @@ -430,7 +430,7 @@ THREE.SceneLoader.prototype = { } else if ( objJSON.target ) { - camera.lookAt( new THREE.Vector3().fromArray( objJSON.target ) ); + camera.lookAt( new THREE.Vector3().fromArray( objJSON.target ) ); } diff --git a/examples/js/loaders/gltf/glTF-parser.js b/examples/js/loaders/gltf/glTF-parser.js index ed53d2a380fc7a..30476f7b291b00 100755 --- a/examples/js/loaders/gltf/glTF-parser.js +++ b/examples/js/loaders/gltf/glTF-parser.js @@ -49,35 +49,35 @@ */ var global = window; (function (root, factory) { - if (typeof exports === 'object') { + if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. - factory(module.exports); - } else if (typeof define === 'function' && define.amd) { + factory(module.exports); + } else if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. - define([], function () { - return factory(root); - }); - } else { + define([], function () { + return factory(root); + }); + } else { // Browser globals - factory(root); - } + factory(root); + } }(this, function (root) { - "use strict"; + "use strict"; - var categoriesDepsOrder = [ "buffers", "bufferViews", "images", "videos", "samplers", "textures", "shaders", "programs", "techniques", "materials", "accessors", "meshes", "cameras", "lights", "skins", "nodes", "scenes", "animations" ]; + var categoriesDepsOrder = [ "buffers", "bufferViews", "images", "videos", "samplers", "textures", "shaders", "programs", "techniques", "materials", "accessors", "meshes", "cameras", "lights", "skins", "nodes", "scenes", "animations" ]; - var glTFParser = Object.create(Object.prototype, { + var glTFParser = Object.create(Object.prototype, { _rootDescription: { value: null, writable: true }, rootDescription: { set: function(value) { - this._rootDescription = value; + this._rootDescription = value; }, get: function() { - return this._rootDescription; + return this._rootDescription; } }, @@ -86,34 +86,34 @@ var global = window; //detect absolute path following the same protocol than window.location _isAbsolutePath: { value: function(path) { - var isAbsolutePathRegExp = new RegExp("^" + window.location.protocol, "i"); + var isAbsolutePathRegExp = new RegExp("^" + window.location.protocol, "i"); - return path.match(isAbsolutePathRegExp) ? true : false; + return path.match(isAbsolutePathRegExp) ? true : false; } }, resolvePathIfNeeded: { value: function(path) { - if (this._isAbsolutePath(path)) { - return path; - } + if (this._isAbsolutePath(path)) { + return path; + } - return this.baseURL + path; + return this.baseURL + path; } }, _resolvePathsForCategories: { value: function(categories) { - categories.forEach( function(category) { - var descriptions = this.json[category]; - if (descriptions) { - var descriptionKeys = Object.keys(descriptions); - descriptionKeys.forEach( function(descriptionKey) { - var description = descriptions[descriptionKey]; - description.path = this.resolvePathIfNeeded(description.path); - }, this); - } - }, this); + categories.forEach( function(category) { + var descriptions = this.json[category]; + if (descriptions) { + var descriptionKeys = Object.keys(descriptions); + descriptionKeys.forEach( function(descriptionKey) { + var description = descriptions[descriptionKey]; + description.path = this.resolvePathIfNeeded(description.path); + }, this); + } + }, this); } }, @@ -125,13 +125,13 @@ var global = window; json: { enumerable: true, get: function() { - return this._json; + return this._json; }, set: function(value) { - if (this._json !== value) { - this._json = value; - this._resolvePathsForCategories([ "buffers", "shaders", "images", "videos" ]); - } + if (this._json !== value) { + this._json = value; + this._resolvePathsForCategories([ "buffers", "shaders", "images", "videos" ]); + } } }, @@ -142,60 +142,60 @@ var global = window; getEntryDescription: { value: function (entryID, entryType) { - var entries = null; + var entries = null; - var category = entryType; - entries = this.rootDescription[category]; - if (!entries) { - console.log("ERROR:CANNOT find expected category named:" + category); - return null; - } + var category = entryType; + entries = this.rootDescription[category]; + if (!entries) { + console.log("ERROR:CANNOT find expected category named:" + category); + return null; + } - return entries ? entries[entryID] : null; + return entries ? entries[entryID] : null; } }, _stepToNextCategory: { value: function() { - this._state.categoryIndex = this.getNextCategoryIndex(this._state.categoryIndex + 1); - if (this._state.categoryIndex !== -1) { - this._state.categoryState.index = 0; - return true; - } + this._state.categoryIndex = this.getNextCategoryIndex(this._state.categoryIndex + 1); + if (this._state.categoryIndex !== -1) { + this._state.categoryState.index = 0; + return true; + } - return false; + return false; } }, _stepToNextDescription: { enumerable: false, value: function() { - var categoryState = this._state.categoryState; - var keys = categoryState.keys; - if (!keys) { - console.log("INCONSISTENCY ERROR"); - return false; - } - - categoryState.index ++; - categoryState.keys = null; - if (categoryState.index >= keys.length) { - return this._stepToNextCategory(); - } - return false; + var categoryState = this._state.categoryState; + var keys = categoryState.keys; + if (!keys) { + console.log("INCONSISTENCY ERROR"); + return false; + } + + categoryState.index ++; + categoryState.keys = null; + if (categoryState.index >= keys.length) { + return this._stepToNextCategory(); + } + return false; } }, hasCategory: { value: function(category) { - return this.rootDescription[category] ? true : false; + return this.rootDescription[category] ? true : false; } }, _handleState: { value: function() { - var methodForType = { + var methodForType = { "buffers" : this.handleBuffer, "bufferViews" : this.handleBufferView, "shaders" : this.handleShader, @@ -217,46 +217,46 @@ var global = window; }; - var success = true; - while (this._state.categoryIndex !== -1) { - var category = categoriesDepsOrder[this._state.categoryIndex]; - var categoryState = this._state.categoryState; - var keys = categoryState.keys; - if (!keys) { - categoryState.keys = keys = Object.keys(this.rootDescription[category]); - if (keys) { - if (keys.length == 0) { - this._stepToNextDescription(); - continue; - } - } - } - - var type = category; - var entryID = keys[categoryState.index]; - var description = this.getEntryDescription(entryID, type); - if (!description) { - if (this.handleError) { - this.handleError("INCONSISTENCY ERROR: no description found for entry " + entryID); - success = false; - break; - } - } else { - - if (methodForType[type]) { - if (methodForType[type].call(this, entryID, description, this._state.userInfo) === false) { - success = false; - break; - } - } - - this._stepToNextDescription(); - } - } - - if (this.handleLoadCompleted) { - this.handleLoadCompleted(success); - } + var success = true; + while (this._state.categoryIndex !== -1) { + var category = categoriesDepsOrder[this._state.categoryIndex]; + var categoryState = this._state.categoryState; + var keys = categoryState.keys; + if (!keys) { + categoryState.keys = keys = Object.keys(this.rootDescription[category]); + if (keys) { + if (keys.length == 0) { + this._stepToNextDescription(); + continue; + } + } + } + + var type = category; + var entryID = keys[categoryState.index]; + var description = this.getEntryDescription(entryID, type); + if (!description) { + if (this.handleError) { + this.handleError("INCONSISTENCY ERROR: no description found for entry " + entryID); + success = false; + break; + } + } else { + + if (methodForType[type]) { + if (methodForType[type].call(this, entryID, description, this._state.userInfo) === false) { + success = false; + break; + } + } + + this._stepToNextDescription(); + } + } + + if (this.handleLoadCompleted) { + this.handleLoadCompleted(success); + } } }, @@ -264,40 +264,40 @@ var global = window; _loadJSONIfNeeded: { enumerable: true, value: function(callback) { - var self = this; + var self = this; //FIXME: handle error - if (!this._json) { - var jsonPath = this._path; - var i = jsonPath.lastIndexOf("/"); - this.baseURL = (i !== 0) ? jsonPath.substring(0, i + 1) : ''; - var jsonfile = new XMLHttpRequest(); - jsonfile.open("GET", jsonPath, true); - jsonfile.addEventListener( 'load', function ( event ) { - self.json = JSON.parse(jsonfile.responseText); - if (callback) { - callback(self.json); - } - }, false ); - jsonfile.send(null); - } else { - if (callback) { - callback(this.json); - } - } + if (!this._json) { + var jsonPath = this._path; + var i = jsonPath.lastIndexOf("/"); + this.baseURL = (i !== 0) ? jsonPath.substring(0, i + 1) : ''; + var jsonfile = new XMLHttpRequest(); + jsonfile.open("GET", jsonPath, true); + jsonfile.addEventListener( 'load', function ( event ) { + self.json = JSON.parse(jsonfile.responseText); + if (callback) { + callback(self.json); + } + }, false ); + jsonfile.send(null); + } else { + if (callback) { + callback(this.json); + } + } } }, /* load JSON and assign it as description to the reader */ _buildLoader: { value: function(callback) { - var self = this; - function JSONReady(json) { - self.rootDescription = json; - if (callback) + var self = this; + function JSONReady(json) { + self.rootDescription = json; + if (callback) callback(this); - } + } - this._loadJSONIfNeeded(JSONReady); + this._loadJSONIfNeeded(JSONReady); } }, @@ -305,51 +305,51 @@ var global = window; _getEntryType: { value: function(entryID) { - var rootKeys = categoriesDepsOrder; - for (var i = 0 ; i < rootKeys.length ; i ++) { - var rootValues = this.rootDescription[rootKeys[i]]; - if (rootValues) { - return rootKeys[i]; - } - } - return null; + var rootKeys = categoriesDepsOrder; + for (var i = 0 ; i < rootKeys.length ; i ++) { + var rootValues = this.rootDescription[rootKeys[i]]; + if (rootValues) { + return rootKeys[i]; + } + } + return null; } }, getNextCategoryIndex: { value: function(currentIndex) { - for (var i = currentIndex ; i < categoriesDepsOrder.length ; i ++) { - if (this.hasCategory(categoriesDepsOrder[i])) { - return i; - } - } + for (var i = currentIndex ; i < categoriesDepsOrder.length ; i ++) { + if (this.hasCategory(categoriesDepsOrder[i])) { + return i; + } + } - return -1; + return -1; } }, load: { enumerable: true, value: function(userInfo, options) { - var self = this; - this._buildLoader(function loaderReady(reader) { - var startCategory = self.getNextCategoryIndex.call(self, 0); - if (startCategory !== -1) { - self._state = { "userInfo" : userInfo, + var self = this; + this._buildLoader(function loaderReady(reader) { + var startCategory = self.getNextCategoryIndex.call(self, 0); + if (startCategory !== -1) { + self._state = { "userInfo" : userInfo, "options" : options, "categoryIndex" : startCategory, "categoryState" : { "index" : "0" } }; - self._handleState(); - } - }); + self._handleState(); + } + }); } }, initWithPath: { value: function(path) { - this._path = path; - this._json = null; - return this; + this._path = path; + this._json = null; + return this; } }, @@ -359,30 +359,30 @@ var global = window; //to be invoked by subclass, so that ids can be ensured to not overlap loaderContext: { value: function() { - if (typeof this._knownURLs[this._path] === "undefined") { - this._knownURLs[this._path] = Object.keys(this._knownURLs).length; - } - return "__" + this._knownURLs[this._path]; + if (typeof this._knownURLs[this._path] === "undefined") { + this._knownURLs[this._path] = Object.keys(this._knownURLs).length; + } + return "__" + this._knownURLs[this._path]; } }, initWithJSON: { value: function(json, baseURL) { - this.json = json; - this.baseURL = baseURL; - if (!baseURL) { - console.log("WARNING: no base URL passed to Reader:initWithJSON"); - } - return this; + this.json = json; + this.baseURL = baseURL; + if (!baseURL) { + console.log("WARNING: no base URL passed to Reader:initWithJSON"); + } + return this; } } }); - if (root) { - root.glTFParser = glTFParser; - } + if (root) { + root.glTFParser = glTFParser; + } - return glTFParser; + return glTFParser; })); diff --git a/examples/js/loaders/gltf/glTFLoader.js b/examples/js/loaders/gltf/glTFLoader.js index 10d397f9dd0eb4..ff429405bf823a 100644 --- a/examples/js/loaders/gltf/glTFLoader.js +++ b/examples/js/loaders/gltf/glTFLoader.js @@ -4,16 +4,16 @@ THREE.glTFLoader = function (showStatus) { - this.meshesRequested = 0; - this.meshesLoaded = 0; - this.pendingMeshes = []; - this.animationsRequested = 0; - this.animationsLoaded = 0; - this.animations = []; - this.shadersRequested = 0; - this.shadersLoaded = 0; - this.shaders = {}; - THREE.Loader.call( this, showStatus ); + this.meshesRequested = 0; + this.meshesLoaded = 0; + this.pendingMeshes = []; + this.animationsRequested = 0; + this.animationsLoaded = 0; + this.animations = []; + this.shadersRequested = 0; + this.shadersLoaded = 0; + this.shaders = {}; + THREE.Loader.call( this, showStatus ); } THREE.glTFLoader.prototype = Object.create( THREE.Loader.prototype ); @@ -24,490 +24,490 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var theLoader = this; // Utilities - function RgbArraytoHex(colorArray) { - if (!colorArray) return 0xFFFFFFFF; - var r = Math.floor(colorArray[0] * 255), + function RgbArraytoHex(colorArray) { + if (!colorArray) return 0xFFFFFFFF; + var r = Math.floor(colorArray[0] * 255), g = Math.floor(colorArray[1] * 255), b = Math.floor(colorArray[2] * 255), a = 255; - var color = (a << 24) + (r << 16) + (g << 8) + b; + var color = (a << 24) + (r << 16) + (g << 8) + b; - return color; - } + return color; + } - function convertAxisAngleToQuaternion(rotations, count) + function convertAxisAngleToQuaternion(rotations, count) { - var q = new THREE.Quaternion; - var axis = new THREE.Vector3; - var euler = new THREE.Vector3; + var q = new THREE.Quaternion; + var axis = new THREE.Vector3; + var euler = new THREE.Vector3; - var i; - for (i = 0; i < count; i ++) { - axis.set(rotations[i * 4], rotations[i * 4 + 1], + var i; + for (i = 0; i < count; i ++) { + axis.set(rotations[i * 4], rotations[i * 4 + 1], rotations[i * 4 + 2]).normalize(); - var angle = rotations[i * 4 + 3]; - q.setFromAxisAngle(axis, angle); - rotations[i * 4] = q.x; - rotations[i * 4 + 1] = q.y; - rotations[i * 4 + 2] = q.z; - rotations[i * 4 + 3] = q.w; - } - } + var angle = rotations[i * 4 + 3]; + q.setFromAxisAngle(axis, angle); + rotations[i * 4] = q.x; + rotations[i * 4 + 1] = q.y; + rotations[i * 4 + 2] = q.z; + rotations[i * 4 + 3] = q.w; + } + } - function componentsPerElementForGLType(glType) { - switch (glType) { - case WebGLRenderingContext.FLOAT : - case WebGLRenderingContext.UNSIGNED_BYTE : - case WebGLRenderingContext.UNSIGNED_SHORT : - return 1; - case WebGLRenderingContext.FLOAT_VEC2 : - return 2; - case WebGLRenderingContext.FLOAT_VEC3 : - return 3; - case WebGLRenderingContext.FLOAT_VEC4 : - return 4; - case WebGLRenderingContext.FLOAT_MAT4 : - return 16; - default: - return null; - } - } + function componentsPerElementForGLType(glType) { + switch (glType) { + case WebGLRenderingContext.FLOAT : + case WebGLRenderingContext.UNSIGNED_BYTE : + case WebGLRenderingContext.UNSIGNED_SHORT : + return 1; + case WebGLRenderingContext.FLOAT_VEC2 : + return 2; + case WebGLRenderingContext.FLOAT_VEC3 : + return 3; + case WebGLRenderingContext.FLOAT_VEC4 : + return 4; + case WebGLRenderingContext.FLOAT_MAT4 : + return 16; + default: + return null; + } + } - function LoadTexture(src) { - if (!src) { return null; } - return THREE.ImageUtils.loadTexture(src); - } + function LoadTexture(src) { + if (!src) { return null; } + return THREE.ImageUtils.loadTexture(src); + } // Geometry processing - var ClassicGeometry = function() { + var ClassicGeometry = function() { - this.geometry = new THREE.BufferGeometry; + this.geometry = new THREE.BufferGeometry; - this.totalAttributes = 0; - this.loadedAttributes = 0; - this.indicesLoaded = false; - this.finished = false; + this.totalAttributes = 0; + this.loadedAttributes = 0; + this.indicesLoaded = false; + this.finished = false; - this.onload = null; + this.onload = null; - this.uvs = null; - this.indexArray = null; - }; + this.uvs = null; + this.indexArray = null; + }; - ClassicGeometry.prototype.constructor = ClassicGeometry; + ClassicGeometry.prototype.constructor = ClassicGeometry; - ClassicGeometry.prototype.buildBufferGeometry = function() { + ClassicGeometry.prototype.buildBufferGeometry = function() { // Build indexed mesh - var geometry = this.geometry; + var geometry = this.geometry; - geometry.addAttribute( 'index', new THREE.BufferAttribute( this.indexArray, 1 ) ); - geometry.addDrawCall( 0, this.indexArray.length, 0 ); + geometry.addAttribute( 'index', new THREE.BufferAttribute( this.indexArray, 1 ) ); + geometry.addDrawCall( 0, this.indexArray.length, 0 ); - geometry.computeBoundingSphere(); - } + geometry.computeBoundingSphere(); + } - ClassicGeometry.prototype.checkFinished = function() { - if (this.indexArray && this.loadedAttributes === this.totalAttributes) { + ClassicGeometry.prototype.checkFinished = function() { + if (this.indexArray && this.loadedAttributes === this.totalAttributes) { - this.buildBufferGeometry(); + this.buildBufferGeometry(); - this.finished = true; + this.finished = true; - if (this.onload) { - this.onload(); - } - } - }; + if (this.onload) { + this.onload(); + } + } + }; // Delegate for processing index buffers - var IndicesDelegate = function() {}; + var IndicesDelegate = function() {}; - IndicesDelegate.prototype.handleError = function(errorCode, info) { + IndicesDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(IndicesDelegate):" + errorCode + ":" + info); - }; - - IndicesDelegate.prototype.convert = function(resource, ctx) { - return new Uint16Array(resource, 0, ctx.indices.count); - }; - - IndicesDelegate.prototype.resourceAvailable = function(glResource, ctx) { - var geometry = ctx.geometry; - geometry.indexArray = glResource; - geometry.checkFinished(); - return true; - }; - - var indicesDelegate = new IndicesDelegate(); - - var IndicesContext = function(indices, geometry) { - this.indices = indices; - this.geometry = geometry; - }; + console.log("ERROR(IndicesDelegate):" + errorCode + ":" + info); + }; + + IndicesDelegate.prototype.convert = function(resource, ctx) { + return new Uint16Array(resource, 0, ctx.indices.count); + }; + + IndicesDelegate.prototype.resourceAvailable = function(glResource, ctx) { + var geometry = ctx.geometry; + geometry.indexArray = glResource; + geometry.checkFinished(); + return true; + }; + + var indicesDelegate = new IndicesDelegate(); + + var IndicesContext = function(indices, geometry) { + this.indices = indices; + this.geometry = geometry; + }; // Delegate for processing vertex attribute buffers - var VertexAttributeDelegate = function() {}; + var VertexAttributeDelegate = function() {}; - VertexAttributeDelegate.prototype.handleError = function(errorCode, info) { + VertexAttributeDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(VertexAttributeDelegate):" + errorCode + ":" + info); - }; + console.log("ERROR(VertexAttributeDelegate):" + errorCode + ":" + info); + }; - VertexAttributeDelegate.prototype.convert = function(resource, ctx) { - return resource; - }; + VertexAttributeDelegate.prototype.convert = function(resource, ctx) { + return resource; + }; - VertexAttributeDelegate.prototype.arrayResourceAvailable = function(glResource, ctx) { - var geom = ctx.geometry; - var attribute = ctx.attribute; - var semantic = ctx.semantic; - var floatArray; - var i, l; + VertexAttributeDelegate.prototype.arrayResourceAvailable = function(glResource, ctx) { + var geom = ctx.geometry; + var attribute = ctx.attribute; + var semantic = ctx.semantic; + var floatArray; + var i, l; //FIXME: Float32 is assumed here, but should be checked. - if (semantic == "POSITION") { + if (semantic == "POSITION") { // TODO: Should be easy to take strides into account here - floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); - for (i = 0, l = floatArray.length; i < l; i += 3) { - geom.geometry.vertices.push( new THREE.Vector3( floatArray[i], floatArray[i + 1], floatArray[i + 2] ) ); - } - } else if (semantic == "NORMAL") { - geom.geometry.normals = []; - floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); - for (i = 0, l = floatArray.length; i < l; i += 3) { - geom.geometry.normals.push( new THREE.Vector3( floatArray[i], floatArray[i + 1], floatArray[i + 2] ) ); - } - } else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) { - geom.uvs = []; - floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); - for (i = 0, l = floatArray.length; i < l; i += 2) { - geom.uvs.push( new THREE.Vector2( floatArray[i], 1.0 - floatArray[i + 1] ) ); - } - } + floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); + for (i = 0, l = floatArray.length; i < l; i += 3) { + geom.geometry.vertices.push( new THREE.Vector3( floatArray[i], floatArray[i + 1], floatArray[i + 2] ) ); + } + } else if (semantic == "NORMAL") { + geom.geometry.normals = []; + floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); + for (i = 0, l = floatArray.length; i < l; i += 3) { + geom.geometry.normals.push( new THREE.Vector3( floatArray[i], floatArray[i + 1], floatArray[i + 2] ) ); + } + } else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) { + geom.uvs = []; + floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); + for (i = 0, l = floatArray.length; i < l; i += 2) { + geom.uvs.push( new THREE.Vector2( floatArray[i], 1.0 - floatArray[i + 1] ) ); + } + } else if (semantic == "WEIGHT") { - nComponents = componentsPerElementForGLType(attribute.type); - floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); - for (i = 0, l = floatArray.length; i < l; i += 4) { - geom.geometry.skinWeights.push( new THREE.Vector4( floatArray[i], floatArray[i + 1], floatArray[i + 2], floatArray[i + 3] ) ); - } + nComponents = componentsPerElementForGLType(attribute.type); + floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); + for (i = 0, l = floatArray.length; i < l; i += 4) { + geom.geometry.skinWeights.push( new THREE.Vector4( floatArray[i], floatArray[i + 1], floatArray[i + 2], floatArray[i + 3] ) ); + } } else if (semantic == "JOINT") { - nComponents = componentsPerElementForGLType(attribute.type); - floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); - for (i = 0, l = floatArray.length; i < l; i += 4) { - geom.geometry.skinIndices.push( new THREE.Vector4( floatArray[i], floatArray[i + 1], floatArray[i + 2], floatArray[i + 3] ) ); - } + nComponents = componentsPerElementForGLType(attribute.type); + floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); + for (i = 0, l = floatArray.length; i < l; i += 4) { + geom.geometry.skinIndices.push( new THREE.Vector4( floatArray[i], floatArray[i + 1], floatArray[i + 2], floatArray[i + 3] ) ); + } } - } + } - VertexAttributeDelegate.prototype.bufferResourceAvailable = function(glResource, ctx) { - var geom = ctx.geometry; - var attribute = ctx.attribute; - var semantic = ctx.semantic; - var floatArray; - var i, l; - var nComponents; + VertexAttributeDelegate.prototype.bufferResourceAvailable = function(glResource, ctx) { + var geom = ctx.geometry; + var attribute = ctx.attribute; + var semantic = ctx.semantic; + var floatArray; + var i, l; + var nComponents; //FIXME: Float32 is assumed here, but should be checked. - if (semantic == "POSITION") { + if (semantic == "POSITION") { // TODO: Should be easy to take strides into account here - floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); - geom.geometry.addAttribute( 'position', new THREE.BufferAttribute( floatArray, 3 ) ); - } else if (semantic == "NORMAL") { - floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); - geom.geometry.addAttribute( 'normal', new THREE.BufferAttribute( floatArray, 3 ) ); - } else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) { + floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); + geom.geometry.addAttribute( 'position', new THREE.BufferAttribute( floatArray, 3 ) ); + } else if (semantic == "NORMAL") { + floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type)); + geom.geometry.addAttribute( 'normal', new THREE.BufferAttribute( floatArray, 3 ) ); + } else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) { - nComponents = componentsPerElementForGLType(attribute.type); - floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); + nComponents = componentsPerElementForGLType(attribute.type); + floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); // N.B.: flip Y value... should we just set texture.flipY everywhere? - for (i = 0; i < floatArray.length / 2; i ++) { - floatArray[i * 2 + 1] = 1.0 - floatArray[i * 2 + 1]; - } - geom.geometry.addAttribute( 'uv', new THREE.BufferAttribute( floatArray, nComponents ) ); - } + for (i = 0; i < floatArray.length / 2; i ++) { + floatArray[i * 2 + 1] = 1.0 - floatArray[i * 2 + 1]; + } + geom.geometry.addAttribute( 'uv', new THREE.BufferAttribute( floatArray, nComponents ) ); + } else if (semantic == "WEIGHT") { - nComponents = componentsPerElementForGLType(attribute.type); - floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); - geom.geometry.addAttribute( 'skinWeight', new THREE.BufferAttribute( floatArray, nComponents ) ); + nComponents = componentsPerElementForGLType(attribute.type); + floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); + geom.geometry.addAttribute( 'skinWeight', new THREE.BufferAttribute( floatArray, nComponents ) ); } else if (semantic == "JOINT") { - nComponents = componentsPerElementForGLType(attribute.type); - floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); - geom.geometry.addAttribute( 'skinIndex', new THREE.BufferAttribute( floatArray, nComponents ) ); + nComponents = componentsPerElementForGLType(attribute.type); + floatArray = new Float32Array(glResource, 0, attribute.count * nComponents); + geom.geometry.addAttribute( 'skinIndex', new THREE.BufferAttribute( floatArray, nComponents ) ); } - } + } - VertexAttributeDelegate.prototype.resourceAvailable = function(glResource, ctx) { + VertexAttributeDelegate.prototype.resourceAvailable = function(glResource, ctx) { - this.bufferResourceAvailable(glResource, ctx); + this.bufferResourceAvailable(glResource, ctx); - var geom = ctx.geometry; - geom.loadedAttributes ++; - geom.checkFinished(); - return true; - }; - - var vertexAttributeDelegate = new VertexAttributeDelegate(); - - var VertexAttributeContext = function(attribute, semantic, geometry) { - this.attribute = attribute; - this.semantic = semantic; - this.geometry = geometry; - }; - - var Mesh = function() { - this.primitives = []; - this.materialsPending = []; - this.loadedGeometry = 0; - this.onCompleteCallbacks = []; - }; - - Mesh.prototype.addPrimitive = function(geometry, material) { + var geom = ctx.geometry; + geom.loadedAttributes ++; + geom.checkFinished(); + return true; + }; + + var vertexAttributeDelegate = new VertexAttributeDelegate(); + + var VertexAttributeContext = function(attribute, semantic, geometry) { + this.attribute = attribute; + this.semantic = semantic; + this.geometry = geometry; + }; + + var Mesh = function() { + this.primitives = []; + this.materialsPending = []; + this.loadedGeometry = 0; + this.onCompleteCallbacks = []; + }; + + Mesh.prototype.addPrimitive = function(geometry, material) { - var self = this; - geometry.onload = function() { - self.loadedGeometry ++; - self.checkComplete(); - }; + var self = this; + geometry.onload = function() { + self.loadedGeometry ++; + self.checkComplete(); + }; - this.primitives.push({ + this.primitives.push({ geometry: geometry, material: material, mesh: null }); - }; - - Mesh.prototype.onComplete = function(callback) { - this.onCompleteCallbacks.push(callback); - this.checkComplete(); - }; - - Mesh.prototype.checkComplete = function() { - var self = this; - if (this.onCompleteCallbacks.length && this.primitives.length == this.loadedGeometry) { - this.onCompleteCallbacks.forEach(function(callback) { - callback(self); - }); - this.onCompleteCallbacks = []; - } - }; + }; + + Mesh.prototype.onComplete = function(callback) { + this.onCompleteCallbacks.push(callback); + this.checkComplete(); + }; + + Mesh.prototype.checkComplete = function() { + var self = this; + if (this.onCompleteCallbacks.length && this.primitives.length == this.loadedGeometry) { + this.onCompleteCallbacks.forEach(function(callback) { + callback(self); + }); + this.onCompleteCallbacks = []; + } + }; - Mesh.prototype.attachToNode = function(threeNode) { + Mesh.prototype.attachToNode = function(threeNode) { // Assumes that the geometry is complete - this.primitives.forEach(function(primitive) { + this.primitives.forEach(function(primitive) { /*if(!primitive.mesh) { primitive.mesh = new THREE.Mesh(primitive.geometry, primitive.material); }*/ - var material = primitive.material; - if (!(material instanceof THREE.Material)) { - material = theLoader.createShaderMaterial(material); - } - - var threeMesh = new THREE.Mesh(primitive.geometry.geometry, material); - threeMesh.castShadow = true; - threeNode.add(threeMesh); - }); - }; + var material = primitive.material; + if (!(material instanceof THREE.Material)) { + material = theLoader.createShaderMaterial(material); + } + + var threeMesh = new THREE.Mesh(primitive.geometry.geometry, material); + threeMesh.castShadow = true; + threeNode.add(threeMesh); + }); + }; // Delayed-loaded material - var Material = function(params) { - this.params = params; - }; + var Material = function(params) { + this.params = params; + }; // Delegate for processing animation parameter buffers - var AnimationParameterDelegate = function() {}; + var AnimationParameterDelegate = function() {}; - AnimationParameterDelegate.prototype.handleError = function(errorCode, info) { + AnimationParameterDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(AnimationParameterDelegate):" + errorCode + ":" + info); - }; - - AnimationParameterDelegate.prototype.convert = function(resource, ctx) { - var parameter = ctx.parameter; - - var glResource = null; - switch (parameter.type) { - case WebGLRenderingContext.FLOAT : - case WebGLRenderingContext.FLOAT_VEC2 : - case WebGLRenderingContext.FLOAT_VEC3 : - case WebGLRenderingContext.FLOAT_VEC4 : - glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type)); - break; - default: - break; - } + console.log("ERROR(AnimationParameterDelegate):" + errorCode + ":" + info); + }; + + AnimationParameterDelegate.prototype.convert = function(resource, ctx) { + var parameter = ctx.parameter; + + var glResource = null; + switch (parameter.type) { + case WebGLRenderingContext.FLOAT : + case WebGLRenderingContext.FLOAT_VEC2 : + case WebGLRenderingContext.FLOAT_VEC3 : + case WebGLRenderingContext.FLOAT_VEC4 : + glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type)); + break; + default: + break; + } - return glResource; - }; + return glResource; + }; - AnimationParameterDelegate.prototype.resourceAvailable = function(glResource, ctx) { - var animation = ctx.animation; - var parameter = ctx.parameter; - parameter.data = glResource; - animation.handleParameterLoaded(parameter); - return true; - }; + AnimationParameterDelegate.prototype.resourceAvailable = function(glResource, ctx) { + var animation = ctx.animation; + var parameter = ctx.parameter; + parameter.data = glResource; + animation.handleParameterLoaded(parameter); + return true; + }; - var animationParameterDelegate = new AnimationParameterDelegate(); + var animationParameterDelegate = new AnimationParameterDelegate(); - var AnimationParameterContext = function(parameter, animation) { - this.parameter = parameter; - this.animation = animation; - }; + var AnimationParameterContext = function(parameter, animation) { + this.parameter = parameter; + this.animation = animation; + }; // Animations - var Animation = function() { + var Animation = function() { // create Three.js keyframe here - this.totalParameters = 0; - this.loadedParameters = 0; - this.parameters = {}; - this.finishedLoading = false; - this.onload = null; + this.totalParameters = 0; + this.loadedParameters = 0; + this.parameters = {}; + this.finishedLoading = false; + this.onload = null; - }; + }; - Animation.prototype.constructor = Animation; + Animation.prototype.constructor = Animation; - Animation.prototype.handleParameterLoaded = function(parameter) { - this.parameters[parameter.name] = parameter; - this.loadedParameters ++; - this.checkFinished(); - }; + Animation.prototype.handleParameterLoaded = function(parameter) { + this.parameters[parameter.name] = parameter; + this.loadedParameters ++; + this.checkFinished(); + }; - Animation.prototype.checkFinished = function() { - if (this.loadedParameters === this.totalParameters) { + Animation.prototype.checkFinished = function() { + if (this.loadedParameters === this.totalParameters) { // Build animation - this.finishedLoading = true; + this.finishedLoading = true; - if (this.onload) { - this.onload(); - } - } - }; + if (this.onload) { + this.onload(); + } + } + }; // Delegate for processing inverse bind matrices buffer - var InverseBindMatricesDelegate = function() {}; + var InverseBindMatricesDelegate = function() {}; - InverseBindMatricesDelegate.prototype.handleError = function(errorCode, info) { + InverseBindMatricesDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(InverseBindMatricesDelegate):" + errorCode + ":" + info); - }; - - InverseBindMatricesDelegate.prototype.convert = function(resource, ctx) { - var parameter = ctx.parameter; - - var glResource = null; - switch (parameter.type) { - case WebGLRenderingContext.FLOAT_MAT4 : - glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type)); - break; - default: - break; - } + console.log("ERROR(InverseBindMatricesDelegate):" + errorCode + ":" + info); + }; + + InverseBindMatricesDelegate.prototype.convert = function(resource, ctx) { + var parameter = ctx.parameter; + + var glResource = null; + switch (parameter.type) { + case WebGLRenderingContext.FLOAT_MAT4 : + glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type)); + break; + default: + break; + } - return glResource; - }; + return glResource; + }; - InverseBindMatricesDelegate.prototype.resourceAvailable = function(glResource, ctx) { - var skin = ctx.skin; - skin.inverseBindMatrices = glResource; - return true; - }; + InverseBindMatricesDelegate.prototype.resourceAvailable = function(glResource, ctx) { + var skin = ctx.skin; + skin.inverseBindMatrices = glResource; + return true; + }; - var inverseBindMatricesDelegate = new InverseBindMatricesDelegate(); + var inverseBindMatricesDelegate = new InverseBindMatricesDelegate(); - var InverseBindMatricesContext = function(param, skin) { - this.parameter = param; - this.skin = skin; - }; + var InverseBindMatricesContext = function(param, skin) { + this.parameter = param; + this.skin = skin; + }; // Delegate for processing shaders from external files - var ShaderDelegate = function() {}; + var ShaderDelegate = function() {}; - ShaderDelegate.prototype.handleError = function(errorCode, info) { + ShaderDelegate.prototype.handleError = function(errorCode, info) { // FIXME: report error - console.log("ERROR(ShaderDelegate):" + errorCode + ":" + info); - }; + console.log("ERROR(ShaderDelegate):" + errorCode + ":" + info); + }; - ShaderDelegate.prototype.convert = function(resource, ctx) { - return resource; - } + ShaderDelegate.prototype.convert = function(resource, ctx) { + return resource; + } - ShaderDelegate.prototype.resourceAvailable = function(data, ctx) { - theLoader.shadersLoaded ++; - theLoader.shaders[ctx.id] = data; - return true; - }; - - var shaderDelegate = new ShaderDelegate(); - - var ShaderContext = function(id, path) { - this.id = id; - this.path = path; - }; + ShaderDelegate.prototype.resourceAvailable = function(data, ctx) { + theLoader.shadersLoaded ++; + theLoader.shaders[ctx.id] = data; + return true; + }; + + var shaderDelegate = new ShaderDelegate(); + + var ShaderContext = function(id, path) { + this.id = id; + this.path = path; + }; // Resource management - var ResourceEntry = function(entryID, object, description) { - this.entryID = entryID; - this.object = object; - this.description = description; - }; + var ResourceEntry = function(entryID, object, description) { + this.entryID = entryID; + this.object = object; + this.description = description; + }; - var Resources = function() { - this._entries = {}; - }; + var Resources = function() { + this._entries = {}; + }; - Resources.prototype.setEntry = function(entryID, object, description) { - if (!entryID) { - console.error("No EntryID provided, cannot store", description); - return; - } + Resources.prototype.setEntry = function(entryID, object, description) { + if (!entryID) { + console.error("No EntryID provided, cannot store", description); + return; + } - if (this._entries[entryID]) { - console.warn("entry[" + entryID + "] is being overwritten"); - } + if (this._entries[entryID]) { + console.warn("entry[" + entryID + "] is being overwritten"); + } - this._entries[entryID] = new ResourceEntry(entryID, object, description ); - }; + this._entries[entryID] = new ResourceEntry(entryID, object, description ); + }; - Resources.prototype.getEntry = function(entryID) { - return this._entries[entryID]; - }; + Resources.prototype.getEntry = function(entryID) { + return this._entries[entryID]; + }; - Resources.prototype.clearEntries = function() { - this._entries = {}; - }; + Resources.prototype.clearEntries = function() { + this._entries = {}; + }; - LoadDelegate = function() { + LoadDelegate = function() { } - LoadDelegate.prototype.loadCompleted = function(callback, obj) { - callback.call(Window, obj); - } + LoadDelegate.prototype.loadCompleted = function(callback, obj) { + callback.call(Window, obj); + } // Loader - var ThreeGLTFLoader = Object.create(glTFParser, { + var ThreeGLTFLoader = Object.create(glTFParser, { load: { enumerable: true, value: function(userInfo, options) { - this.resources = new Resources(); - this.cameras = []; - this.lights = []; - this.animations = []; - this.joints = {}; - this.skeltons = {}; - THREE.GLTFLoaderUtils.init(); - glTFParser.load.call(this, userInfo, options); + this.resources = new Resources(); + this.cameras = []; + this.lights = []; + this.animations = []; + this.joints = {}; + this.skeltons = {}; + THREE.GLTFLoaderUtils.init(); + glTFParser.load.call(this, userInfo, options); } }, @@ -533,73 +533,73 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { handleBuffer: { value: function(entryID, description, userInfo) { - this.resources.setEntry(entryID, null, description); - description.type = "ArrayBuffer"; - return true; + this.resources.setEntry(entryID, null, description); + description.type = "ArrayBuffer"; + return true; } }, handleBufferView: { value: function(entryID, description, userInfo) { - this.resources.setEntry(entryID, null, description); + this.resources.setEntry(entryID, null, description); - var buffer = this.resources.getEntry(description.buffer); - description.type = "ArrayBufferView"; + var buffer = this.resources.getEntry(description.buffer); + description.type = "ArrayBufferView"; - var bufferViewEntry = this.resources.getEntry(entryID); - bufferViewEntry.buffer = buffer; - return true; + var bufferViewEntry = this.resources.getEntry(entryID); + bufferViewEntry.buffer = buffer; + return true; } }, handleShader: { value: function(entryID, description, userInfo) { - this.resources.setEntry(entryID, null, description); - var shaderRequest = { + this.resources.setEntry(entryID, null, description); + var shaderRequest = { id : entryID, path : description.path, }; - var shaderContext = new ShaderContext(entryID, description.path); + var shaderContext = new ShaderContext(entryID, description.path); - theLoader.shadersRequested ++; - THREE.GLTFLoaderUtils.getFile(shaderRequest, shaderDelegate, shaderContext); + theLoader.shadersRequested ++; + THREE.GLTFLoaderUtils.getFile(shaderRequest, shaderDelegate, shaderContext); - return true; + return true; } }, handleProgram: { value: function(entryID, description, userInfo) { - this.resources.setEntry(entryID, null, description); - return true; + this.resources.setEntry(entryID, null, description); + return true; } }, handleTechnique: { value: function(entryID, description, userInfo) { - this.resources.setEntry(entryID, null, description); - return true; + this.resources.setEntry(entryID, null, description); + return true; } }, createShaderMaterial : { value: function(material) { - var fragmentShader = theLoader.shaders[material.params.fragmentShader]; - if (!fragmentShader) { - console.log("ERROR: Missing fragment shader definition:", material.params.fragmentShader); - return new THREE.MeshPhongMaterial; - } + var fragmentShader = theLoader.shaders[material.params.fragmentShader]; + if (!fragmentShader) { + console.log("ERROR: Missing fragment shader definition:", material.params.fragmentShader); + return new THREE.MeshPhongMaterial; + } - var vertexShader = theLoader.shaders[material.params.vertexShader]; - if (!fragmentShader) { - console.log("ERROR: Missing vertex shader definition:", material.params.vertexShader); - return new THREE.MeshPhongMaterial; - } + var vertexShader = theLoader.shaders[material.params.vertexShader]; + if (!fragmentShader) { + console.log("ERROR: Missing vertex shader definition:", material.params.vertexShader); + return new THREE.MeshPhongMaterial; + } - var uniforms = {}; - var shaderMaterial = new THREE.ShaderMaterial( { + var uniforms = {}; + var shaderMaterial = new THREE.ShaderMaterial( { fragmentShader: fragmentShader, vertexShader: vertexShader, @@ -607,195 +607,195 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { } ); - return new THREE.MeshPhongMaterial(material.params); + return new THREE.MeshPhongMaterial(material.params); } }, createShaderParams : { value: function(materialId, values, params, instanceProgram) { - var program = this.resources.getEntry(instanceProgram.program); + var program = this.resources.getEntry(instanceProgram.program); - if (program) { - params.fragmentShader = program.description.fragmentShader; - params.vertexShader = program.description.vertexShader; - params.attributes = instanceProgram.attributes; - params.uniforms = instanceProgram.uniforms; - } + if (program) { + params.fragmentShader = program.description.fragmentShader; + params.vertexShader = program.description.vertexShader; + params.attributes = instanceProgram.attributes; + params.uniforms = instanceProgram.uniforms; + } } }, threeJSMaterialType : { value: function(materialId, technique, values, params) { - var materialType = THREE.MeshPhongMaterial; - var defaultPass = null; - if (technique && technique.description && technique.description.passes) + var materialType = THREE.MeshPhongMaterial; + var defaultPass = null; + if (technique && technique.description && technique.description.passes) defaultPass = technique.description.passes.defaultPass; - if (defaultPass) { - if (defaultPass.details && defaultPass.details.commonProfile) { - var profile = technique.description.passes.defaultPass.details.commonProfile; - if (profile) + if (defaultPass) { + if (defaultPass.details && defaultPass.details.commonProfile) { + var profile = technique.description.passes.defaultPass.details.commonProfile; + if (profile) { - switch (profile.lightingModel) + switch (profile.lightingModel) { - case 'Blinn' : - case 'Phong' : - materialType = THREE.MeshPhongMaterial; - break; + case 'Blinn' : + case 'Phong' : + materialType = THREE.MeshPhongMaterial; + break; - case 'Lambert' : - materialType = THREE.MeshLambertMaterial; - break; + case 'Lambert' : + materialType = THREE.MeshLambertMaterial; + break; - default : - materialType = THREE.MeshBasicMaterial; - break; - } + default : + materialType = THREE.MeshBasicMaterial; + break; + } - if (profile.extras && profile.extras.doubleSided) + if (profile.extras && profile.extras.doubleSided) { - params.side = THREE.DoubleSide; - } - } - } + params.side = THREE.DoubleSide; + } + } + } else if (defaultPass.instanceProgram) { - var instanceProgram = defaultPass.instanceProgram; + var instanceProgram = defaultPass.instanceProgram; - this.createShaderParams(materialId, values, params, instanceProgram); + this.createShaderParams(materialId, values, params, instanceProgram); - var loadshaders = true; + var loadshaders = true; - if (loadshaders) { - materialType = Material; - } + if (loadshaders) { + materialType = Material; + } } - } + } - var texturePath = null; - var textureParams = null; - var diffuse = values.diffuse; - if (diffuse) + var texturePath = null; + var textureParams = null; + var diffuse = values.diffuse; + if (diffuse) { - var texture = diffuse; - if (texture) { - var textureEntry = this.resources.getEntry(texture); - if (textureEntry) { - { - var imageEntry = this.resources.getEntry(textureEntry.description.source); - if (imageEntry) { - texturePath = imageEntry.description.path; - } + var texture = diffuse; + if (texture) { + var textureEntry = this.resources.getEntry(texture); + if (textureEntry) { + { + var imageEntry = this.resources.getEntry(textureEntry.description.source); + if (imageEntry) { + texturePath = imageEntry.description.path; + } - var samplerEntry = this.resources.getEntry(textureEntry.description.sampler); - if (samplerEntry) { - textureParams = samplerEntry.description; - } - } - } - } - } - - var texture = LoadTexture(texturePath); - if (texture && textureParams) { + var samplerEntry = this.resources.getEntry(textureEntry.description.sampler); + if (samplerEntry) { + textureParams = samplerEntry.description; + } + } + } + } + } + + var texture = LoadTexture(texturePath); + if (texture && textureParams) { - if (textureParams.wrapS == WebGLRenderingContext.REPEAT) + if (textureParams.wrapS == WebGLRenderingContext.REPEAT) texture.wrapS = THREE.RepeatWrapping; - if (textureParams.wrapT == WebGLRenderingContext.REPEAT) + if (textureParams.wrapT == WebGLRenderingContext.REPEAT) texture.wrapT = THREE.RepeatWrapping; - if (textureParams.magFilter == WebGLRenderingContext.LINEAR) + if (textureParams.magFilter == WebGLRenderingContext.LINEAR) texture.magFilter = THREE.LinearFilter; // if (textureParams.minFilter == "LINEAR") // texture.minFilter = THREE.LinearFilter; - params.map = texture; - } + params.map = texture; + } - var envMapPath = null; - var envMapParams = null; - var reflective = values.reflective; - if (reflective) + var envMapPath = null; + var envMapParams = null; + var reflective = values.reflective; + if (reflective) { - var texture = reflective; - if (texture) { - var textureEntry = this.resources.getEntry(texture); - if (textureEntry) { - { - var imageEntry = this.resources.getEntry(textureEntry.description.source); - if (imageEntry) { - envMapPath = imageEntry.description.path; - } + var texture = reflective; + if (texture) { + var textureEntry = this.resources.getEntry(texture); + if (textureEntry) { + { + var imageEntry = this.resources.getEntry(textureEntry.description.source); + if (imageEntry) { + envMapPath = imageEntry.description.path; + } - var samplerEntry = this.resources.getEntry(textureEntry.description.sampler); - if (samplerEntry) { - envMapParams = samplerEntry.description; - } - } - } - } - } - - var texture = LoadTexture(envMapPath); - if (texture && envMapParams) { + var samplerEntry = this.resources.getEntry(textureEntry.description.sampler); + if (samplerEntry) { + envMapParams = samplerEntry.description; + } + } + } + } + } + + var texture = LoadTexture(envMapPath); + if (texture && envMapParams) { - if (envMapParams.wrapS == WebGLRenderingContext.REPEAT) + if (envMapParams.wrapS == WebGLRenderingContext.REPEAT) texture.wrapS = THREE.RepeatWrapping; - if (envMapParams.wrapT == WebGLRenderingContext.REPEAT) + if (envMapParams.wrapT == WebGLRenderingContext.REPEAT) texture.wrapT = THREE.RepeatWrapping; - if (envMapParams.magFilter == WebGLRenderingContext.LINEAR) + if (envMapParams.magFilter == WebGLRenderingContext.LINEAR) texture.magFilter = THREE.LinearFilter; // if (envMapParams.minFilter == WebGLRenderingContext.LINEAR) // texture.minFilter = THREE.LinearFilter; - params.envMap = texture; - } + params.envMap = texture; + } - var shininess = values.shininesss || values.shininess; // N.B.: typo in converter! - if (shininess) + var shininess = values.shininesss || values.shininess; // N.B.: typo in converter! + if (shininess) { - shininess = shininess; - } + shininess = shininess; + } - var diffuseColor = !texturePath ? diffuse : null; - var opacity = 1.0; - if (values.hasOwnProperty("transparency")) + var diffuseColor = !texturePath ? diffuse : null; + var opacity = 1.0; + if (values.hasOwnProperty("transparency")) { - var USE_A_ONE = true; // for now, hack because file format isn't telling us - opacity = USE_A_ONE ? values.transparency : (1.0 - values.transparency); - } + var USE_A_ONE = true; // for now, hack because file format isn't telling us + opacity = USE_A_ONE ? values.transparency : (1.0 - values.transparency); + } // if (diffuseColor) diffuseColor = [0, 1, 0]; - params.color = RgbArraytoHex(diffuseColor); - params.opacity = opacity; - params.transparent = opacity < 1.0; + params.color = RgbArraytoHex(diffuseColor); + params.opacity = opacity; + params.transparent = opacity < 1.0; // hack hack hack - if (texturePath && texturePath.toLowerCase().indexOf(".png") != -1) + if (texturePath && texturePath.toLowerCase().indexOf(".png") != -1) params.transparent = true; - if (!(shininess === undefined)) + if (!(shininess === undefined)) { - params.shininess = shininess; - } + params.shininess = shininess; + } - if (!(values.emission === undefined)) + if (!(values.emission === undefined)) { - params.emissive = RgbArraytoHex(values.emission); - } + params.emissive = RgbArraytoHex(values.emission); + } - if (!(values.specular === undefined)) + if (!(values.specular === undefined)) { - params.specular = RgbArraytoHex(values.specular); - } + params.specular = RgbArraytoHex(values.specular); + } - return materialType; + return materialType; } }, @@ -804,44 +804,44 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { value: function(entryID, description, userInfo) { //this should be rewritten using the meta datas that actually create the shader. //here we will infer what needs to be pass to Three.js by looking inside the technique parameters. - var technique = this.resources.getEntry(description.instanceTechnique.technique); - var materialParams = {}; - var values = description.instanceTechnique.values; + var technique = this.resources.getEntry(description.instanceTechnique.technique); + var materialParams = {}; + var values = description.instanceTechnique.values; - var materialType = this.threeJSMaterialType(entryID, technique, values, materialParams); + var materialType = this.threeJSMaterialType(entryID, technique, values, materialParams); - var material = new materialType(materialParams); + var material = new materialType(materialParams); - this.resources.setEntry(entryID, material, description); + this.resources.setEntry(entryID, material, description); - return true; + return true; } }, handleMesh: { value: function(entryID, description, userInfo) { - var mesh = new Mesh(); - this.resources.setEntry(entryID, mesh, description); - var primitivesDescription = description.primitives; - if (!primitivesDescription) { + var mesh = new Mesh(); + this.resources.setEntry(entryID, mesh, description); + var primitivesDescription = description.primitives; + if (!primitivesDescription) { //FIXME: not implemented in delegate - console.log("MISSING_PRIMITIVES for mesh:" + entryID); - return false; - } + console.log("MISSING_PRIMITIVES for mesh:" + entryID); + return false; + } - for (var i = 0 ; i < primitivesDescription.length ; i ++) { - var primitiveDescription = primitivesDescription[i]; + for (var i = 0 ; i < primitivesDescription.length ; i ++) { + var primitiveDescription = primitivesDescription[i]; - if (primitiveDescription.primitive === WebGLRenderingContext.TRIANGLES) { + if (primitiveDescription.primitive === WebGLRenderingContext.TRIANGLES) { - var geometry = new ClassicGeometry(); - var materialEntry = this.resources.getEntry(primitiveDescription.material); + var geometry = new ClassicGeometry(); + var materialEntry = this.resources.getEntry(primitiveDescription.material); - mesh.addPrimitive(geometry, materialEntry.object); + mesh.addPrimitive(geometry, materialEntry.object); - var indices = this.resources.getEntry(primitiveDescription.indices); - var bufferEntry = this.resources.getEntry(indices.description.bufferView); - var indicesObject = { + var indices = this.resources.getEntry(primitiveDescription.indices); + var bufferEntry = this.resources.getEntry(indices.description.bufferView); + var indicesObject = { bufferView : bufferEntry, byteOffset : indices.description.byteOffset, count : indices.description.count, @@ -849,36 +849,36 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { type : indices.description.type }; - var indicesContext = new IndicesContext(indicesObject, geometry); - var alreadyProcessedIndices = THREE.GLTFLoaderUtils.getBuffer(indicesObject, indicesDelegate, indicesContext); + var indicesContext = new IndicesContext(indicesObject, geometry); + var alreadyProcessedIndices = THREE.GLTFLoaderUtils.getBuffer(indicesObject, indicesDelegate, indicesContext); /*if(alreadyProcessedIndices) { indicesDelegate.resourceAvailable(alreadyProcessedIndices, indicesContext); }*/ // Load Vertex Attributes - var allAttributes = Object.keys(primitiveDescription.attributes); - allAttributes.forEach( function(semantic) { - geometry.totalAttributes ++; - - var attribute; - var attributeID = primitiveDescription.attributes[semantic]; - var attributeEntry = this.resources.getEntry(attributeID); - if (!attributeEntry) { + var allAttributes = Object.keys(primitiveDescription.attributes); + allAttributes.forEach( function(semantic) { + geometry.totalAttributes ++; + + var attribute; + var attributeID = primitiveDescription.attributes[semantic]; + var attributeEntry = this.resources.getEntry(attributeID); + if (!attributeEntry) { //let's just use an anonymous object for the attribute - attribute = description.attributes[attributeID]; - attribute.id = attributeID; - this.resources.setEntry(attributeID, attribute, attribute); + attribute = description.attributes[attributeID]; + attribute.id = attributeID; + this.resources.setEntry(attributeID, attribute, attribute); - var bufferEntry = this.resources.getEntry(attribute.bufferView); - attributeEntry = this.resources.getEntry(attributeID); + var bufferEntry = this.resources.getEntry(attribute.bufferView); + attributeEntry = this.resources.getEntry(attributeID); - } else { - attribute = attributeEntry.object; - attribute.id = attributeID; - var bufferEntry = this.resources.getEntry(attribute.bufferView); - } + } else { + attribute = attributeEntry.object; + attribute.id = attributeID; + var bufferEntry = this.resources.getEntry(attribute.bufferView); + } - var attributeObject = { + var attributeObject = { bufferView : bufferEntry, byteOffset : attribute.byteOffset, byteStride : attribute.byteStride, @@ -889,106 +889,106 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { id : attributeID }; - var attribContext = new VertexAttributeContext(attributeObject, semantic, geometry); + var attribContext = new VertexAttributeContext(attributeObject, semantic, geometry); - var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(attributeObject, vertexAttributeDelegate, attribContext); + var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(attributeObject, vertexAttributeDelegate, attribContext); /*if(alreadyProcessedAttribute) { vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext); }*/ - }, this); - } - } - return true; + }, this); + } + } + return true; } }, handleCamera: { value: function(entryID, description, userInfo) { - var camera; - if (description.type == "perspective") + var camera; + if (description.type == "perspective") { - var znear = description.perspective.znear; - var zfar = description.perspective.zfar; - var yfov = description.perspective.yfov; - var xfov = description.perspective.xfov; - var aspect_ratio = description.perspective.aspect_ratio; + var znear = description.perspective.znear; + var zfar = description.perspective.zfar; + var yfov = description.perspective.yfov; + var xfov = description.perspective.xfov; + var aspect_ratio = description.perspective.aspect_ratio; - if (!aspect_ratio) + if (!aspect_ratio) aspect_ratio = 1; - if (yfov === undefined) + if (yfov === undefined) { - if (xfov) + if (xfov) { // According to COLLADA spec... // aspect_ratio = xfov / yfov - yfov = xfov / aspect_ratio; - } + yfov = xfov / aspect_ratio; + } - } + } - if (yfov) + if (yfov) { - camera = new THREE.PerspectiveCamera(yfov, aspect_ratio, znear, zfar); - } - } + camera = new THREE.PerspectiveCamera(yfov, aspect_ratio, znear, zfar); + } + } else - { - camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, znear, zfar ); - } + { + camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, znear, zfar ); + } - if (camera) + if (camera) { - this.resources.setEntry(entryID, camera, description); - } + this.resources.setEntry(entryID, camera, description); + } - return true; + return true; } }, handleLight: { value: function(entryID, description, userInfo) { - var light = null; - var type = description.type; - if (type && description[type]) + var light = null; + var type = description.type; + if (type && description[type]) { - var lparams = description[type]; - var color = RgbArraytoHex(lparams.color); + var lparams = description[type]; + var color = RgbArraytoHex(lparams.color); - switch (type) { - case "directional" : - light = new THREE.DirectionalLight(color); - light.position.set(0, 0, 1); - break; + switch (type) { + case "directional" : + light = new THREE.DirectionalLight(color); + light.position.set(0, 0, 1); + break; - case "point" : - light = new THREE.PointLight(color); - break; + case "point" : + light = new THREE.PointLight(color); + break; - case "spot " : - light = new THREE.SpotLight(color); - light.position.set(0, 0, 1); - break; + case "spot " : + light = new THREE.SpotLight(color); + light.position.set(0, 0, 1); + break; - case "ambient" : - light = new THREE.AmbientLight(color); - break; - } - } + case "ambient" : + light = new THREE.AmbientLight(color); + break; + } + } - if (light) + if (light) { - this.resources.setEntry(entryID, light, description); - } + this.resources.setEntry(entryID, light, description); + } - return true; + return true; } }, addPendingMesh: { value: function(mesh, threeNode) { - theLoader.pendingMeshes.push({ + theLoader.pendingMeshes.push({ mesh: mesh, node: threeNode }); @@ -998,342 +998,342 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { handleNode: { value: function(entryID, description, userInfo) { - var threeNode = null; + var threeNode = null; if (description.jointId) { - threeNode = new THREE.Bone(); - threeNode.jointId = description.jointId; - this.joints[description.jointId] = entryID; + threeNode = new THREE.Bone(); + threeNode.jointId = description.jointId; + this.joints[description.jointId] = entryID; } else { - threeNode = new THREE.Object3D(); + threeNode = new THREE.Object3D(); } - threeNode.name = description.name; + threeNode.name = description.name; - this.resources.setEntry(entryID, threeNode, description); - - var m = description.matrix; - if (m) { - threeNode.applyMatrix(new THREE.Matrix4().fromArray( m )); - threeNode.matrixAutoUpdate = false; - threeNode.matrixWorldNeedsUpdate = true; - } - else { - var t = description.translation; - var r = description.rotation; - var s = description.scale; + this.resources.setEntry(entryID, threeNode, description); + + var m = description.matrix; + if (m) { + threeNode.applyMatrix(new THREE.Matrix4().fromArray( m )); + threeNode.matrixAutoUpdate = false; + threeNode.matrixWorldNeedsUpdate = true; + } + else { + var t = description.translation; + var r = description.rotation; + var s = description.scale; - var position = t ? new THREE.Vector3(t[0], t[1], t[2]) : + var position = t ? new THREE.Vector3(t[0], t[1], t[2]) : new THREE.Vector3; - if (r) { - convertAxisAngleToQuaternion(r, 1); - } - var rotation = r ? new THREE.Quaternion(r[0], r[1], r[2], r[3]) : + if (r) { + convertAxisAngleToQuaternion(r, 1); + } + var rotation = r ? new THREE.Quaternion(r[0], r[1], r[2], r[3]) : new THREE.Quaternion; - var scale = s ? new THREE.Vector3(s[0], s[1], s[2]) : + var scale = s ? new THREE.Vector3(s[0], s[1], s[2]) : new THREE.Vector3; - var matrix = new THREE.Matrix4; - matrix.compose(position, rotation, scale); - threeNode.matrixAutoUpdate = false; - threeNode.matrixWorldNeedsUpdate = true; - threeNode.applyMatrix(matrix); - } - - var self = this; + var matrix = new THREE.Matrix4; + matrix.compose(position, rotation, scale); + threeNode.matrixAutoUpdate = false; + threeNode.matrixWorldNeedsUpdate = true; + threeNode.applyMatrix(matrix); + } + + var self = this; // Iterate through all node meshes and attach the appropriate objects //FIXME: decision needs to be made between these 2 ways, probably meshes will be discarded. - var meshEntry; - if (description.mesh) { - meshEntry = this.resources.getEntry(description.mesh); - theLoader.meshesRequested ++; - meshEntry.object.onComplete(function(mesh) { - self.addPendingMesh(mesh, threeNode); - theLoader.meshesLoaded ++; - theLoader.checkComplete(); - }); - } - - if (description.meshes) { - description.meshes.forEach( function(meshID) { - meshEntry = this.resources.getEntry(meshID); - theLoader.meshesRequested ++; - meshEntry.object.onComplete(function(mesh) { - self.addPendingMesh(mesh, threeNode); - theLoader.meshesLoaded ++; - theLoader.checkComplete(); - }); - }, this); - } - - if (description.instanceSkin) { - - var skinEntry = this.resources.getEntry(description.instanceSkin.skin); + var meshEntry; + if (description.mesh) { + meshEntry = this.resources.getEntry(description.mesh); + theLoader.meshesRequested ++; + meshEntry.object.onComplete(function(mesh) { + self.addPendingMesh(mesh, threeNode); + theLoader.meshesLoaded ++; + theLoader.checkComplete(); + }); + } + + if (description.meshes) { + description.meshes.forEach( function(meshID) { + meshEntry = this.resources.getEntry(meshID); + theLoader.meshesRequested ++; + meshEntry.object.onComplete(function(mesh) { + self.addPendingMesh(mesh, threeNode); + theLoader.meshesLoaded ++; + theLoader.checkComplete(); + }); + }, this); + } + + if (description.instanceSkin) { + + var skinEntry = this.resources.getEntry(description.instanceSkin.skin); - if (skinEntry) { - - var skin = skinEntry.object; - description.instanceSkin.skin = skin; - threeNode.instanceSkin = description.instanceSkin; - - var sources = description.instanceSkin.sources; - skin.meshes = []; - sources.forEach( function(meshID) { - meshEntry = this.resources.getEntry(meshID); - theLoader.meshesRequested ++; - meshEntry.object.onComplete(function(mesh) { + if (skinEntry) { + + var skin = skinEntry.object; + description.instanceSkin.skin = skin; + threeNode.instanceSkin = description.instanceSkin; + + var sources = description.instanceSkin.sources; + skin.meshes = []; + sources.forEach( function(meshID) { + meshEntry = this.resources.getEntry(meshID); + theLoader.meshesRequested ++; + meshEntry.object.onComplete(function(mesh) { - skin.meshes.push(mesh); - theLoader.meshesLoaded ++; - theLoader.checkComplete(); - }); - }, this); + skin.meshes.push(mesh); + theLoader.meshesLoaded ++; + theLoader.checkComplete(); + }); + }, this); - } - } + } + } - if (description.camera) { - var cameraEntry = this.resources.getEntry(description.camera); - if (cameraEntry) { - threeNode.add(cameraEntry.object); - this.cameras.push(cameraEntry.object); - } - } - - if (description.light) { - var lightEntry = this.resources.getEntry(description.light); - if (lightEntry) { - threeNode.add(lightEntry.object); - this.lights.push(lightEntry.object); - } - } + if (description.camera) { + var cameraEntry = this.resources.getEntry(description.camera); + if (cameraEntry) { + threeNode.add(cameraEntry.object); + this.cameras.push(cameraEntry.object); + } + } + + if (description.light) { + var lightEntry = this.resources.getEntry(description.light); + if (lightEntry) { + threeNode.add(lightEntry.object); + this.lights.push(lightEntry.object); + } + } - return true; + return true; } }, buildNodeHirerachy: { value: function(nodeEntryId, parentThreeNode) { - var nodeEntry = this.resources.getEntry(nodeEntryId); - var threeNode = nodeEntry.object; - parentThreeNode.add(threeNode); - - var children = nodeEntry.description.children; - if (children) { - children.forEach( function(childID) { - this.buildNodeHirerachy(childID, threeNode); - }, this); - } - - return threeNode; + var nodeEntry = this.resources.getEntry(nodeEntryId); + var threeNode = nodeEntry.object; + parentThreeNode.add(threeNode); + + var children = nodeEntry.description.children; + if (children) { + children.forEach( function(childID) { + this.buildNodeHirerachy(childID, threeNode); + }, this); + } + + return threeNode; } }, buildSkin: { value: function(node) { - var skin = node.instanceSkin.skin; - if (skin) { - node.instanceSkin.skeletons.forEach(function(skeleton) { - var nodeEntry = this.resources.getEntry(skeleton); - if (nodeEntry) { + var skin = node.instanceSkin.skin; + if (skin) { + node.instanceSkin.skeletons.forEach(function(skeleton) { + var nodeEntry = this.resources.getEntry(skeleton); + if (nodeEntry) { - var rootSkeleton = nodeEntry.object; + var rootSkeleton = nodeEntry.object; - var dobones = true; + var dobones = true; - var i, len = skin.meshes.length; - for (i = 0; i < len; i ++) { - var mesh = skin.meshes[i]; - var threeMesh = null; - mesh.primitives.forEach(function(primitive) { + var i, len = skin.meshes.length; + for (i = 0; i < len; i ++) { + var mesh = skin.meshes[i]; + var threeMesh = null; + mesh.primitives.forEach(function(primitive) { - var material = primitive.material; - if (!(material instanceof THREE.Material)) { - material = this.createShaderMaterial(material); - } + var material = primitive.material; + if (!(material instanceof THREE.Material)) { + material = this.createShaderMaterial(material); + } - threeMesh = new THREE.SkinnedMesh(primitive.geometry.geometry, material, false); - threeMesh.add(rootSkeleton); + threeMesh = new THREE.SkinnedMesh(primitive.geometry.geometry, material, false); + threeMesh.add(rootSkeleton); - var geometry = primitive.geometry.geometry; - var j; - if (geometry.vertices) { - for ( j = 0; j < geometry.vertices.length; j ++ ) { - geometry.vertices[j].applyMatrix4( skin.bindShapeMatrix ); - } - } + var geometry = primitive.geometry.geometry; + var j; + if (geometry.vertices) { + for ( j = 0; j < geometry.vertices.length; j ++ ) { + geometry.vertices[j].applyMatrix4( skin.bindShapeMatrix ); + } + } else if (geometry.attributes.position) { - var a = geometry.attributes.position.array; - var v = new THREE.Vector3; + var a = geometry.attributes.position.array; + var v = new THREE.Vector3; for ( j = 0; j < a.length / 3; j ++ ) { - v.set(a[j * 3], a[j * 3 + 1], a[j * 3 + 2]); - v.applyMatrix4( skin.bindShapeMatrix ); - a[j * 3] = v.x; - a[j * 3 + 1] = v.y; - a[j * 3 + 2] = v.z; + v.set(a[j * 3], a[j * 3 + 1], a[j * 3 + 2]); + v.applyMatrix4( skin.bindShapeMatrix ); + a[j * 3] = v.x; + a[j * 3 + 1] = v.y; + a[j * 3 + 2] = v.z; } } - if (threeMesh && dobones) { + if (threeMesh && dobones) { - material.skinning = true; + material.skinning = true; - threeMesh.boneInverses = []; - var jointsIds = skin.jointsIds; - var bones = []; - var boneInverses = []; - var i, len = jointsIds.length; - for (i = 0; i < len; i ++) { - var jointId = jointsIds[i]; - var nodeForJoint = this.joints[jointId]; - var joint = this.resources.getEntry(nodeForJoint).object; - if (joint) { + threeMesh.boneInverses = []; + var jointsIds = skin.jointsIds; + var bones = []; + var boneInverses = []; + var i, len = jointsIds.length; + for (i = 0; i < len; i ++) { + var jointId = jointsIds[i]; + var nodeForJoint = this.joints[jointId]; + var joint = this.resources.getEntry(nodeForJoint).object; + if (joint) { - joint.skin = threeMesh; - bones.push(joint); + joint.skin = threeMesh; + bones.push(joint); - var m = skin.inverseBindMatrices; - var mat = new THREE.Matrix4().set( + var m = skin.inverseBindMatrices; + var mat = new THREE.Matrix4().set( m[i * 16 + 0], m[i * 16 + 4], m[i * 16 + 8], m[i * 16 + 12], m[i * 16 + 1], m[i * 16 + 5], m[i * 16 + 9], m[i * 16 + 13], m[i * 16 + 2], m[i * 16 + 6], m[i * 16 + 10], m[i * 16 + 14], m[i * 16 + 3], m[i * 16 + 7], m[i * 16 + 11], m[i * 16 + 15] ); - boneInverses.push(mat); + boneInverses.push(mat); - } else { - console.log("WARNING: jointId:" + jointId + " cannot be found in skeleton:" + skeleton); - } - } + } else { + console.log("WARNING: jointId:" + jointId + " cannot be found in skeleton:" + skeleton); + } + } - threeMesh.bind(new THREE.Skeleton(bones, boneInverses, false)); - } + threeMesh.bind(new THREE.Skeleton(bones, boneInverses, false)); + } - if (threeMesh) { - threeMesh.castShadow = true; - node.add(threeMesh); - } + if (threeMesh) { + threeMesh.castShadow = true; + node.add(threeMesh); + } - }, this); - } + }, this); + } - } + } - }, this); + }, this); - } + } } }, buildSkins: { value: function(node) { - if (node.instanceSkin) + if (node.instanceSkin) this.buildSkin(node); - var children = node.children; - if (children) { - children.forEach( function(child) { - this.buildSkins(child); - }, this); - } + var children = node.children; + if (children) { + children.forEach( function(child) { + this.buildSkins(child); + }, this); + } } }, createMeshAnimations : { value : function(root) { - this.buildSkins(root); + this.buildSkins(root); } }, handleScene: { value: function(entryID, description, userInfo) { - if (!description.nodes) { - console.log("ERROR: invalid file required nodes property is missing from scene"); - return false; - } + if (!description.nodes) { + console.log("ERROR: invalid file required nodes property is missing from scene"); + return false; + } - description.nodes.forEach( function(nodeUID) { - this.buildNodeHirerachy(nodeUID, userInfo.rootObj); - }, this); + description.nodes.forEach( function(nodeUID) { + this.buildNodeHirerachy(nodeUID, userInfo.rootObj); + }, this); - if (this.delegate) { - this.delegate.loadCompleted(userInfo.callback, userInfo.rootObj); - } + if (this.delegate) { + this.delegate.loadCompleted(userInfo.callback, userInfo.rootObj); + } - return true; + return true; } }, handleImage: { value: function(entryID, description, userInfo) { - this.resources.setEntry(entryID, null, description); - return true; + this.resources.setEntry(entryID, null, description); + return true; } }, addNodeAnimationChannel : { value : function(name, channel, interp) { - if (!this.nodeAnimationChannels) + if (!this.nodeAnimationChannels) this.nodeAnimationChannels = {}; - if (!this.nodeAnimationChannels[name]) { - this.nodeAnimationChannels[name] = []; - } + if (!this.nodeAnimationChannels[name]) { + this.nodeAnimationChannels[name] = []; + } - this.nodeAnimationChannels[name].push(interp); + this.nodeAnimationChannels[name].push(interp); }, }, createAnimations : { value : function() { - for (var name in this.nodeAnimationChannels) { - var nodeAnimationChannels = this.nodeAnimationChannels[name]; - var i, len = nodeAnimationChannels.length; + for (var name in this.nodeAnimationChannels) { + var nodeAnimationChannels = this.nodeAnimationChannels[name]; + var i, len = nodeAnimationChannels.length; //console.log(" animation channels for node " + name); //for (i = 0; i < len; i++) { // console.log(nodeAnimationChannels[i]); //} - var anim = new THREE.glTFAnimation(nodeAnimationChannels); - anim.name = "animation_" + name; - this.animations.push(anim); - } + var anim = new THREE.glTFAnimation(nodeAnimationChannels); + anim.name = "animation_" + name; + this.animations.push(anim); + } } }, buildAnimation: { value : function(animation) { - var interps = []; + var interps = []; var i, len = animation.channels.length; for (i = 0; i < len; i ++) { - var channel = animation.channels[i]; - var sampler = animation.samplers[channel.sampler]; - if (sampler) { + var channel = animation.channels[i]; + var sampler = animation.samplers[channel.sampler]; + if (sampler) { - var input = animation.parameters[sampler.input]; - if (input && input.data) { + var input = animation.parameters[sampler.input]; + if (input && input.data) { - var output = animation.parameters[sampler.output]; - if (output && output.data) { + var output = animation.parameters[sampler.output]; + if (output && output.data) { - var target = channel.target; - var node = this.resources.getEntry(target.id); - if (node) { + var target = channel.target; + var node = this.resources.getEntry(target.id); + if (node) { - var path = target.path; + var path = target.path; - if (path == "rotation") + if (path == "rotation") { - convertAxisAngleToQuaternion(output.data, output.count); - } + convertAxisAngleToQuaternion(output.data, output.count); + } - var interp = { + var interp = { keys : input.data, values : output.data, count : input.count, @@ -1342,12 +1342,12 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { type : sampler.interpolation }; - this.addNodeAnimationChannel(target.id, channel, interp); - interps.push(interp); - } - } - } - } + this.addNodeAnimationChannel(target.id, channel, interp); + interps.push(interp); + } + } + } + } } } }, @@ -1355,15 +1355,15 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { handleAnimation: { value: function(entryID, description, userInfo) { - var self = this; + var self = this; theLoader.animationsRequested ++; var animation = new Animation(); - animation.name = entryID; + animation.name = entryID; animation.onload = function() { // self.buildAnimation(animation); - theLoader.animationsLoaded ++; - theLoader.animations.push(animation); - theLoader.checkComplete(); + theLoader.animationsLoaded ++; + theLoader.animations.push(animation); + theLoader.checkComplete(); }; animation.channels = description.channels; @@ -1372,22 +1372,22 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var parameters = description.parameters; if (!parameters) { //FIXME: not implemented in delegate - console.log("MISSING_PARAMETERS for animation:" + entryID); - return false; + console.log("MISSING_PARAMETERS for animation:" + entryID); + return false; } // Load parameter buffers - var params = Object.keys(parameters); - params.forEach( function(param) { + var params = Object.keys(parameters); + params.forEach( function(param) { - animation.totalParameters ++; - var parameter = parameters[param]; - var accessor = this.resources.getEntry(parameter); - if (!accessor) + animation.totalParameters ++; + var parameter = parameters[param]; + var accessor = this.resources.getEntry(parameter); + if (!accessor) debugger; - accessor = accessor.object; - var bufferView = this.resources.getEntry(accessor.bufferView); - var paramObject = { + accessor = accessor.object; + var bufferView = this.resources.getEntry(accessor.bufferView); + var paramObject = { bufferView : bufferView, byteOffset : accessor.byteOffset, count : accessor.count, @@ -1396,13 +1396,13 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { name : param }; - var paramContext = new AnimationParameterContext(paramObject, animation); + var paramContext = new AnimationParameterContext(paramObject, animation); - var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(paramObject, animationParameterDelegate, paramContext); + var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(paramObject, animationParameterDelegate, paramContext); /*if(alreadyProcessedAttribute) { vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext); }*/ - }, this); + }, this); return true; } @@ -1412,7 +1412,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { value: function(entryID, description, userInfo) { // Save attribute entry this.resources.setEntry(entryID, description, description); - return true; + return true; } }, @@ -1420,10 +1420,10 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { value: function(entryID, description, userInfo) { // Save skin entry - var skin = { + var skin = { }; - var m = description.bindShapeMatrix; + var m = description.bindShapeMatrix; skin.bindShapeMatrix = new THREE.Matrix4().fromArray( m ); skin.jointsIds = description.joints; @@ -1431,9 +1431,9 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { skin.inverseBindMatricesDescription = inverseBindMatricesDescription; skin.inverseBindMatricesDescription.id = entryID + "_inverseBindMatrices"; - var bufferEntry = this.resources.getEntry(inverseBindMatricesDescription.bufferView); + var bufferEntry = this.resources.getEntry(inverseBindMatricesDescription.bufferView); - var paramObject = { + var paramObject = { bufferView : bufferEntry, byteOffset : inverseBindMatricesDescription.byteOffset, count : inverseBindMatricesDescription.count, @@ -1444,13 +1444,13 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { var context = new InverseBindMatricesContext(paramObject, skin); - var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(paramObject, inverseBindMatricesDelegate, context); + var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(paramObject, inverseBindMatricesDelegate, context); var bufferView = this.resources.getEntry(skin.inverseBindMatricesDescription.bufferView); skin.inverseBindMatricesDescription.bufferView = bufferView.object; this.resources.setEntry(entryID, skin, description); - return true; + return true; } }, @@ -1458,7 +1458,7 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { value: function(entryID, description, userInfo) { // Save attribute entry this.resources.setEntry(entryID, description, description); - return true; + return true; } }, @@ -1466,15 +1466,15 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { value: function(entryID, description, userInfo) { // Save attribute entry this.resources.setEntry(entryID, null, description); - return true; + return true; } }, handleError: { value: function(msg) { - throw new Error(msg); - return true; + throw new Error(msg); + return true; } }, @@ -1486,10 +1486,10 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { delegate: { enumerable: true, get: function() { - return this._delegate; + return this._delegate; }, set: function(value) { - this._delegate = value; + this._delegate = value; } } }); @@ -1497,26 +1497,26 @@ THREE.glTFLoader.prototype.load = function( url, callback ) { // Loader - var Context = function(rootObj, callback) { - this.rootObj = rootObj; - this.callback = callback; - }; + var Context = function(rootObj, callback) { + this.rootObj = rootObj; + this.callback = callback; + }; - var rootObj = new THREE.Object3D(); + var rootObj = new THREE.Object3D(); - var self = this; + var self = this; - var loader = Object.create(ThreeGLTFLoader); - loader.initWithPath(url); - loader.load(new Context(rootObj, + var loader = Object.create(ThreeGLTFLoader); + loader.initWithPath(url); + loader.load(new Context(rootObj, function(obj) { }), null); - this.loader = loader; - this.callback = callback; - this.rootObj = rootObj; - return rootObj; + this.loader = loader; + this.callback = callback; + this.rootObj = rootObj; + return rootObj; } THREE.glTFLoader.prototype.callLoadedCallback = function() { diff --git a/examples/js/loaders/gltf/glTFLoaderUtils.js b/examples/js/loaders/gltf/glTFLoaderUtils.js index 961fdc946b25cb..1d74148a539e8b 100644 --- a/examples/js/loaders/gltf/glTFLoaderUtils.js +++ b/examples/js/loaders/gltf/glTFLoaderUtils.js @@ -26,8 +26,8 @@ THREE.GLTFLoaderUtils = Object.create(Object, { value: function() { this._streams = {}; this._streamsStatus = {}; - this._resources = {}; - this._resourcesStatus = {}; + this._resources = {}; + this._resourcesStatus = {}; } }, @@ -35,60 +35,60 @@ THREE.GLTFLoaderUtils = Object.create(Object, { _containsResource: { enumerable: false, value: function(resourceID) { - return this._resources[resourceID] ? true : false; + return this._resources[resourceID] ? true : false; } }, _storeResource: { enumerable: false, value: function(resourceID, resource) { - if (!resourceID) { - console.log("ERROR: entry does not contain id, cannot store"); - return; - } + if (!resourceID) { + console.log("ERROR: entry does not contain id, cannot store"); + return; + } - if (this._containsResource[resourceID]) { - console.log("WARNING: resource:" + resourceID + " is already stored, overriding"); - } + if (this._containsResource[resourceID]) { + console.log("WARNING: resource:" + resourceID + " is already stored, overriding"); + } - this._resources[resourceID] = resource; + this._resources[resourceID] = resource; } }, _getResource: { enumerable: false, value: function(resourceID) { - return this._resources[resourceID]; + return this._resources[resourceID]; } }, _loadStream: { value: function(path, type, delegate) { - var self = this; + var self = this; - if (!type) { - delegate.handleError(THREE.GLTFLoaderUtils.INVALID_TYPE, null); - return; - } + if (!type) { + delegate.handleError(THREE.GLTFLoaderUtils.INVALID_TYPE, null); + return; + } - if (!path) { - delegate.handleError(THREE.GLTFLoaderUtils.INVALID_PATH); - return; - } + if (!path) { + delegate.handleError(THREE.GLTFLoaderUtils.INVALID_PATH); + return; + } - var xhr = new XMLHttpRequest(); - xhr.open('GET', path, true); - xhr.responseType = (type === this.ARRAY_BUFFER) ? "arraybuffer" : "text"; + var xhr = new XMLHttpRequest(); + xhr.open('GET', path, true); + xhr.responseType = (type === this.ARRAY_BUFFER) ? "arraybuffer" : "text"; //if this is not specified, 1 "big blob" scenes fails to load. - xhr.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 1970 00:00:00 GMT"); - xhr.addEventListener( 'load', function ( event ) { - delegate.streamAvailable(path, xhr.response); - }, false ); - xhr.addEventListener( 'error', function ( event ) { - delegate.handleError(THREE.GLTFLoaderUtils.XMLHTTPREQUEST_STATUS_ERROR, xhr.status); - }, false ); - xhr.send(null); + xhr.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 1970 00:00:00 GMT"); + xhr.addEventListener( 'load', function ( event ) { + delegate.streamAvailable(path, xhr.response); + }, false ); + xhr.addEventListener( 'error', function ( event ) { + delegate.handleError(THREE.GLTFLoaderUtils.XMLHTTPREQUEST_STATUS_ERROR, xhr.status); + }, false ); + xhr.send(null); } }, @@ -97,86 +97,86 @@ THREE.GLTFLoaderUtils = Object.create(Object, { _handleRequest: { value: function(request) { - var resourceStatus = this._resourcesStatus[request.id]; - if (resourceStatus) + var resourceStatus = this._resourcesStatus[request.id]; + if (resourceStatus) { - this._resourcesStatus[request.id] ++; - } + this._resourcesStatus[request.id] ++; + } else - { - this._resourcesStatus[request.id] = 1; - } + { + this._resourcesStatus[request.id] = 1; + } - var streamStatus = this._streamsStatus[request.path]; - if (streamStatus && streamStatus.status === "loading" ) + var streamStatus = this._streamsStatus[request.path]; + if (streamStatus && streamStatus.status === "loading" ) { - streamStatus.requests.push(request); - return; - } + streamStatus.requests.push(request); + return; + } - this._streamsStatus[request.path] = { status : "loading", requests : [ request ] }; + this._streamsStatus[request.path] = { status : "loading", requests : [ request ] }; - var self = this; - var processResourceDelegate = {}; - - processResourceDelegate.streamAvailable = function(path, res_) { - var streamStatus = self._streamsStatus[path]; - var requests = streamStatus.requests; - requests.forEach( function(req_) { - var subArray = res_.slice(req_.range[0], req_.range[1]); - var convertedResource = req_.delegate.convert(subArray, req_.ctx); - self._storeResource(req_.id, convertedResource); - req_.delegate.resourceAvailable(convertedResource, req_.ctx); - -- self._resourcesStatus[req_.id]; - - }, this); + var self = this; + var processResourceDelegate = {}; + + processResourceDelegate.streamAvailable = function(path, res_) { + var streamStatus = self._streamsStatus[path]; + var requests = streamStatus.requests; + requests.forEach( function(req_) { + var subArray = res_.slice(req_.range[0], req_.range[1]); + var convertedResource = req_.delegate.convert(subArray, req_.ctx); + self._storeResource(req_.id, convertedResource); + req_.delegate.resourceAvailable(convertedResource, req_.ctx); + -- self._resourcesStatus[req_.id]; + + }, this); - delete self._streamsStatus[path]; + delete self._streamsStatus[path]; - }; + }; - processResourceDelegate.handleError = function(errorCode, info) { - request.delegate.handleError(errorCode, info); - } + processResourceDelegate.handleError = function(errorCode, info) { + request.delegate.handleError(errorCode, info); + } - this._loadStream(request.path, request.type, processResourceDelegate); + this._loadStream(request.path, request.type, processResourceDelegate); } }, _elementSizeForGLType: { value: function(glType) { - switch (glType) { - case WebGLRenderingContext.FLOAT : - return Float32Array.BYTES_PER_ELEMENT; - case WebGLRenderingContext.UNSIGNED_BYTE : - return Uint8Array.BYTES_PER_ELEMENT; - case WebGLRenderingContext.UNSIGNED_SHORT : - return Uint16Array.BYTES_PER_ELEMENT; - case WebGLRenderingContext.FLOAT_VEC2 : - return Float32Array.BYTES_PER_ELEMENT * 2; - case WebGLRenderingContext.FLOAT_VEC3 : - return Float32Array.BYTES_PER_ELEMENT * 3; - case WebGLRenderingContext.FLOAT_VEC4 : - return Float32Array.BYTES_PER_ELEMENT * 4; - case WebGLRenderingContext.FLOAT_MAT3 : - return Float32Array.BYTES_PER_ELEMENT * 9; - case WebGLRenderingContext.FLOAT_MAT4 : - return Float32Array.BYTES_PER_ELEMENT * 16; - default: - return null; - } + switch (glType) { + case WebGLRenderingContext.FLOAT : + return Float32Array.BYTES_PER_ELEMENT; + case WebGLRenderingContext.UNSIGNED_BYTE : + return Uint8Array.BYTES_PER_ELEMENT; + case WebGLRenderingContext.UNSIGNED_SHORT : + return Uint16Array.BYTES_PER_ELEMENT; + case WebGLRenderingContext.FLOAT_VEC2 : + return Float32Array.BYTES_PER_ELEMENT * 2; + case WebGLRenderingContext.FLOAT_VEC3 : + return Float32Array.BYTES_PER_ELEMENT * 3; + case WebGLRenderingContext.FLOAT_VEC4 : + return Float32Array.BYTES_PER_ELEMENT * 4; + case WebGLRenderingContext.FLOAT_MAT3 : + return Float32Array.BYTES_PER_ELEMENT * 9; + case WebGLRenderingContext.FLOAT_MAT4 : + return Float32Array.BYTES_PER_ELEMENT * 16; + default: + return null; + } } }, _handleWrappedBufferViewResourceLoading: { value: function(wrappedBufferView, delegate, ctx) { - var bufferView = wrappedBufferView.bufferView; - var buffer = bufferView.buffer; - var byteOffset = wrappedBufferView.byteOffset + bufferView.description.byteOffset; - var range = [ byteOffset, (this._elementSizeForGLType(wrappedBufferView.type) * wrappedBufferView.count) + byteOffset ]; + var bufferView = wrappedBufferView.bufferView; + var buffer = bufferView.buffer; + var byteOffset = wrappedBufferView.byteOffset + bufferView.description.byteOffset; + var range = [ byteOffset, (this._elementSizeForGLType(wrappedBufferView.type) * wrappedBufferView.count) + byteOffset ]; - this._handleRequest({ "id" : wrappedBufferView.id, + this._handleRequest({ "id" : wrappedBufferView.id, "range" : range, "type" : buffer.description.type, "path" : buffer.description.path, @@ -189,14 +189,14 @@ THREE.GLTFLoaderUtils = Object.create(Object, { value: function(wrappedBufferView, delegate, ctx) { - var savedBuffer = this._getResource(wrappedBufferView.id); - if (savedBuffer) { - return savedBuffer; - } else { - this._handleWrappedBufferViewResourceLoading(wrappedBufferView, delegate, ctx); - } + var savedBuffer = this._getResource(wrappedBufferView.id); + if (savedBuffer) { + return savedBuffer; + } else { + this._handleWrappedBufferViewResourceLoading(wrappedBufferView, delegate, ctx); + } - return null; + return null; } }, @@ -204,17 +204,17 @@ THREE.GLTFLoaderUtils = Object.create(Object, { value: function(request, delegate, ctx) { - request.delegate = delegate; - request.ctx = ctx; + request.delegate = delegate; + request.ctx = ctx; - this._handleRequest({ "id" : request.id, + this._handleRequest({ "id" : request.id, "path" : request.path, "range" : [ 0 ], "type" : "text", "delegate" : delegate, "ctx" : ctx }, null); - return null; - } + return null; +} }, }); diff --git a/examples/js/renderers/SVGRenderer.js b/examples/js/renderers/SVGRenderer.js index 031a776c1a2da8..544ddb7006d27c 100644 --- a/examples/js/renderers/SVGRenderer.js +++ b/examples/js/renderers/SVGRenderer.js @@ -215,7 +215,7 @@ THREE.SVGRenderer = function () { var x = _vector3.x * _svgWidthHalf; var y = - _vector3.y * _svgHeightHalf; - var node = object.node; + var node = object.node; node.setAttribute( 'transform', 'translate(' + x + ',' + y + ')' ); _svg.appendChild( node ); diff --git a/examples/js/renderers/SoftwareRenderer.js b/examples/js/renderers/SoftwareRenderer.js index 53501eef0b6f65..f26b2ef817fbdb 100644 --- a/examples/js/renderers/SoftwareRenderer.js +++ b/examples/js/renderers/SoftwareRenderer.js @@ -404,8 +404,8 @@ THREE.SoftwareRenderer = function ( parameters ) { + (material.palette[cIndex + 2] * tdata[tIndex + 2]); if (opaci < 250) { - var backColor = buffer[ colorOffset ] << 24 + buffer[ colorOffset + 1 ] << 16 + buffer[ colorOffset + 2 ] << 8; - foreColor = foreColor * opaci + backColor * (1 - opaci); + var backColor = buffer[ colorOffset ] << 24 + buffer[ colorOffset + 1 ] << 16 + buffer[ colorOffset + 2 ] << 8; + foreColor = foreColor * opaci + backColor * (1 - opaci); } buffer[ colorOffset ] = (foreColor & 0xff0000) >> 16; diff --git a/examples/js/utils/UVsDebug.js b/examples/js/utils/UVsDebug.js index d98f3e9ff47c49..6aa81e9cb1383a 100644 --- a/examples/js/utils/UVsDebug.js +++ b/examples/js/utils/UVsDebug.js @@ -16,104 +16,104 @@ THREE.UVsDebug = function( geometry, size ) { // handles wrapping of uv.x > 1 only - var abc = 'abcd'; + var abc = 'abcd'; - var uv, u, ax, ay; - var i, il, j, jl; - var vnum; + var uv, u, ax, ay; + var i, il, j, jl; + var vnum; - var a = new THREE.Vector2(); - var b = new THREE.Vector2(); + var a = new THREE.Vector2(); + var b = new THREE.Vector2(); - var faces = geometry.faces; - var uvs = geometry.faceVertexUvs[ 0 ]; + var faces = geometry.faces; + var uvs = geometry.faceVertexUvs[ 0 ]; - var canvas = document.createElement( 'canvas' ); - var width = size || 1024; // power of 2 required for wrapping - var height = size || 1024; - canvas.width = width; - canvas.height = height; + var canvas = document.createElement( 'canvas' ); + var width = size || 1024; // power of 2 required for wrapping + var height = size || 1024; + canvas.width = width; + canvas.height = height; - var ctx = canvas.getContext( '2d' ); - ctx.lineWidth = 2; - ctx.strokeStyle = 'rgba( 0, 0, 0, 1.0 )'; - ctx.textAlign = 'center'; + var ctx = canvas.getContext( '2d' ); + ctx.lineWidth = 2; + ctx.strokeStyle = 'rgba( 0, 0, 0, 1.0 )'; + ctx.textAlign = 'center'; // paint background white - ctx.fillStyle = 'rgba( 255, 255, 255, 1.0 )'; - ctx.fillRect( 0, 0, width, height ); + ctx.fillStyle = 'rgba( 255, 255, 255, 1.0 )'; + ctx.fillRect( 0, 0, width, height ); - for ( i = 0, il = uvs.length; i < il; i ++ ) { + for ( i = 0, il = uvs.length; i < il; i ++ ) { - uv = uvs[ i ]; + uv = uvs[ i ]; // draw lines - ctx.beginPath(); + ctx.beginPath(); - a.set( 0, 0 ); + a.set( 0, 0 ); - for ( j = 0, jl = uv.length; j < jl; j ++ ) { + for ( j = 0, jl = uv.length; j < jl; j ++ ) { - u = uv[ j ]; + u = uv[ j ]; - a.x += u.x; - a.y += u.y; + a.x += u.x; + a.y += u.y; - if ( j == 0 ) { + if ( j == 0 ) { - ctx.moveTo( u.x * width, ( 1 - u.y ) * height ); + ctx.moveTo( u.x * width, ( 1 - u.y ) * height ); - } else { + } else { - ctx.lineTo( u.x * width, ( 1 - u.y ) * height ); + ctx.lineTo( u.x * width, ( 1 - u.y ) * height ); - } + } - } + } - ctx.closePath(); - ctx.stroke(); + ctx.closePath(); + ctx.stroke(); - a.divideScalar( jl ); + a.divideScalar( jl ); // label the face number - ctx.font = "12pt Arial bold"; - ctx.fillStyle = 'rgba( 0, 0, 0, 1.0 )'; - ctx.fillText( i, a.x * width, ( 1 - a.y ) * height ); + ctx.font = "12pt Arial bold"; + ctx.fillStyle = 'rgba( 0, 0, 0, 1.0 )'; + ctx.fillText( i, a.x * width, ( 1 - a.y ) * height ); - if ( a.x > 0.95 ) { // wrap x // 0.95 is arbitrary + if ( a.x > 0.95 ) { // wrap x // 0.95 is arbitrary - ctx.fillText( i, ( a.x % 1 ) * width, ( 1 - a.y ) * height ); + ctx.fillText( i, ( a.x % 1 ) * width, ( 1 - a.y ) * height ); - } + } - ctx.font = "8pt Arial bold"; - ctx.fillStyle = 'rgba( 0, 0, 0, 1.0 )'; + ctx.font = "8pt Arial bold"; + ctx.fillStyle = 'rgba( 0, 0, 0, 1.0 )'; // label uv edge orders - for ( j = 0, jl = uv.length; j < jl; j ++ ) { + for ( j = 0, jl = uv.length; j < jl; j ++ ) { - u = uv[ j ]; - b.addVectors( a, u ).divideScalar( 2 ); + u = uv[ j ]; + b.addVectors( a, u ).divideScalar( 2 ); - vnum = faces[ i ][ abc[ j ] ]; - ctx.fillText( abc[ j ] + vnum, b.x * width, ( 1 - b.y ) * height ); + vnum = faces[ i ][ abc[ j ] ]; + ctx.fillText( abc[ j ] + vnum, b.x * width, ( 1 - b.y ) * height ); - if ( b.x > 0.95 ) { // wrap x + if ( b.x > 0.95 ) { // wrap x - ctx.fillText( abc[ j ] + vnum, ( b.x % 1 ) * width, ( 1 - b.y ) * height ); + ctx.fillText( abc[ j ] + vnum, ( b.x % 1 ) * width, ( 1 - b.y ) * height ); - } + } - } + } - } + } - return canvas; + return canvas; } diff --git a/examples/js/wip/benchmark/Geometry4.js b/examples/js/wip/benchmark/Geometry4.js index b9b055abaa607d..b93f05748419ee 100644 --- a/examples/js/wip/benchmark/Geometry4.js +++ b/examples/js/wip/benchmark/Geometry4.js @@ -1,18 +1,18 @@ THREE.Geometry4 = function ( size ) { - THREE.BufferGeometry.call( this ); + THREE.BufferGeometry.call( this ); - var verticesBuffer = new ArrayBuffer( size * 3 * 4 ); - var normalsBuffer = new ArrayBuffer( size * 3 * 4 ); - var uvsBuffer = new ArrayBuffer( size * 2 * 4 ); + var verticesBuffer = new ArrayBuffer( size * 3 * 4 ); + var normalsBuffer = new ArrayBuffer( size * 3 * 4 ); + var uvsBuffer = new ArrayBuffer( size * 2 * 4 ); - this.attributes[ 'position' ] = { array: new Float32Array( verticesBuffer, 0, size * 3 ), itemSize: 3 }; - this.attributes[ 'normal' ] = { array: new Float32Array( normalsBuffer, 0, size * 3 ), itemSize: 3 }; - this.attributes[ 'uv' ] = { array: new Float32Array( uvsBuffer, 0, size * 2 ), itemSize: 2 }; + this.attributes[ 'position' ] = { array: new Float32Array( verticesBuffer, 0, size * 3 ), itemSize: 3 }; + this.attributes[ 'normal' ] = { array: new Float32Array( normalsBuffer, 0, size * 3 ), itemSize: 3 }; + this.attributes[ 'uv' ] = { array: new Float32Array( uvsBuffer, 0, size * 2 ), itemSize: 2 }; - this.vertices = new THREE.VectorArrayProxy( this.attributes[ 'position' ] ); - this.normals = new THREE.VectorArrayProxy( this.attributes[ 'normal' ] ); - this.uvs = new THREE.VectorArrayProxy( this.attributes[ 'uv' ] ); + this.vertices = new THREE.VectorArrayProxy( this.attributes[ 'position' ] ); + this.normals = new THREE.VectorArrayProxy( this.attributes[ 'normal' ] ); + this.uvs = new THREE.VectorArrayProxy( this.attributes[ 'uv' ] ); }; THREE.Geometry4.prototype = Object.create( THREE.BufferGeometry.prototype ); @@ -22,16 +22,16 @@ THREE.VectorArrayProxy = function(attribute) { // Acts as a proxy for an array of vectors, by setting up accessors which return THREE.Vector*Proxy objects - this.attribute = attribute; + this.attribute = attribute; - for (var i = 0, l = this.attribute.array.length / this.attribute.itemSize; i < l; i ++) { + for (var i = 0, l = this.attribute.array.length / this.attribute.itemSize; i < l; i ++) { - Object.defineProperty(this, i, { + Object.defineProperty(this, i, { get: (function(i) { return function() { return this.getValue(i); }})(i), set: (function(i) { return function(v) { return this.setValue(i, v); }})(i), }); - } + } } @@ -39,23 +39,23 @@ THREE.VectorArrayProxy.prototype.getValue = function(i) { // Allocates a new THREE.Vector2Proxy or THREE.Vector3Proxy depending on the itemSize of our attribute - var subarray = this.attribute.array.subarray(i * this.attribute.itemSize, (i + 1) * this.attribute.itemSize); + var subarray = this.attribute.array.subarray(i * this.attribute.itemSize, (i + 1) * this.attribute.itemSize); - switch (this.attribute.itemSize) { + switch (this.attribute.itemSize) { - case 2: - return new THREE.Vector2Proxy(subarray); + case 2: + return new THREE.Vector2Proxy(subarray); - case 3: - return new THREE.Vector3Proxy(subarray); + case 3: + return new THREE.Vector3Proxy(subarray); - } + } } THREE.VectorArrayProxy.prototype.setValue = function(i, v) { - var vec = this[i]; - vec.copy(v); + var vec = this[i]; + vec.copy(v); } @@ -63,7 +63,7 @@ THREE.VectorArrayProxy.prototype.setValue = function(i, v) { THREE.Vector2Proxy = function(subarray) { - this.subarray = subarray; + this.subarray = subarray; } THREE.Vector2Proxy.prototype = Object.create( THREE.Vector2.prototype ); @@ -74,7 +74,7 @@ Object.defineProperty(THREE.Vector2Proxy.prototype, 'y', { get: function() { ret THREE.Vector3Proxy = function(subarray) { - this.subarray = subarray; + this.subarray = subarray; } THREE.Vector3Proxy.prototype = Object.create( THREE.Vector3.prototype ); diff --git a/src/extras/FontUtils.js b/src/extras/FontUtils.js index b3f1e56db8590d..244cc2b04b951f 100644 --- a/src/extras/FontUtils.js +++ b/src/extras/FontUtils.js @@ -182,11 +182,11 @@ THREE.FontUtils = { var t = i2 / divisions; var tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx ); var ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy ); - } + } - } + } - break; + break; case 'b': diff --git a/src/extras/core/Curve.js b/src/extras/core/Curve.js index 5183b2b2a4db01..a40e940f5b6840 100644 --- a/src/extras/core/Curve.js +++ b/src/extras/core/Curve.js @@ -212,17 +212,17 @@ THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) { // we could get finer grain at lengths, or use simple interpolatation between two points var lengthBefore = arcLengths[ i ]; - var lengthAfter = arcLengths[ i + 1 ]; + var lengthAfter = arcLengths[ i + 1 ]; - var segmentLength = lengthAfter - lengthBefore; + var segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points - var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; + var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; // add that fractional amount to t - var t = ( i + segmentFraction ) / ( il - 1 ); + var t = ( i + segmentFraction ) / ( il - 1 ); return t; diff --git a/src/extras/core/Path.js b/src/extras/core/Path.js index 50917c87b9b169..c56c3ea7e84f62 100644 --- a/src/extras/core/Path.js +++ b/src/extras/core/Path.js @@ -375,7 +375,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) { //console.log(points); - break; + break; case THREE.PathActions.ELLIPSE: @@ -413,7 +413,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) { //console.log(points); - break; + break; } // end switch diff --git a/src/extras/geometries/ExtrudeGeometry.js b/src/extras/geometries/ExtrudeGeometry.js index e1e11c7ad16c8b..207e7f60b66596 100644 --- a/src/extras/geometries/ExtrudeGeometry.js +++ b/src/extras/geometries/ExtrudeGeometry.js @@ -605,7 +605,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var uvs = uvgen.generateTopUV( scope, a, b, c ); - scope.faceVertexUvs[ 0 ].push( uvs ); + scope.faceVertexUvs[ 0 ].push( uvs ); } @@ -616,13 +616,13 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { c += shapesOffset; d += shapesOffset; - scope.faces.push( new THREE.Face3( a, b, d, null, null, extrudeMaterial ) ); - scope.faces.push( new THREE.Face3( b, c, d, null, null, extrudeMaterial ) ); + scope.faces.push( new THREE.Face3( a, b, d, null, null, extrudeMaterial ) ); + scope.faces.push( new THREE.Face3( b, c, d, null, null, extrudeMaterial ) ); - var uvs = uvgen.generateSideWallUV( scope, a, b, c, d ); + var uvs = uvgen.generateSideWallUV( scope, a, b, c, d ); - scope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] ); - scope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] ); + scope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] ); + scope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] ); } diff --git a/src/loaders/CompressedTextureLoader.js b/src/loaders/CompressedTextureLoader.js index 3ef59092fb62eb..6eece366653484 100644 --- a/src/loaders/CompressedTextureLoader.js +++ b/src/loaders/CompressedTextureLoader.js @@ -49,7 +49,7 @@ THREE.CompressedTextureLoader.prototype = { if ( loaded === 6 ) { - if (texDatas.mipmapCount == 1) + if (texDatas.mipmapCount == 1) texture.minFilter = THREE.LinearFilter; texture.format = texDatas.format; diff --git a/src/loaders/JSONLoader.js b/src/loaders/JSONLoader.js index ad45150a731bbb..de58c9c5ab7f8d 100644 --- a/src/loaders/JSONLoader.js +++ b/src/loaders/JSONLoader.js @@ -461,7 +461,7 @@ THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - THREE.warn( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + + THREE.warn( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); } diff --git a/src/math/Matrix4.js b/src/math/Matrix4.js index 47068850e766d6..45a35fb81fe64c 100644 --- a/src/math/Matrix4.js +++ b/src/math/Matrix4.js @@ -92,15 +92,15 @@ THREE.Matrix4.prototype = { extractBasis: function ( xAxis, yAxis, zAxis ) { - var te = this.elements; + var te = this.elements; xAxis.set( te[ 0 ], te[ 1 ], te[ 2 ] ); yAxis.set( te[ 4 ], te[ 5 ], te[ 6 ] ); zAxis.set( te[ 8 ], te[ 9 ], te[ 10 ] ); - return this; + return this; - }, + }, makeBasis: function ( xAxis, yAxis, zAxis ) { @@ -111,7 +111,7 @@ THREE.Matrix4.prototype = { 0, 0, 0, 1 ); - return this; + return this; }, diff --git a/src/math/Sphere.js b/src/math/Sphere.js index 0f47f548f7b433..52cff009c94fee 100644 --- a/src/math/Sphere.js +++ b/src/math/Sphere.js @@ -52,7 +52,7 @@ THREE.Sphere.prototype = { return this; - }; + }; }(), diff --git a/src/math/Vector2.js b/src/math/Vector2.js index bfb3841e6847f6..d9fba4218445f9 100644 --- a/src/math/Vector2.js +++ b/src/math/Vector2.js @@ -371,9 +371,9 @@ THREE.Vector2.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - return this; + return this; }, @@ -408,14 +408,14 @@ THREE.Vector2.prototype = { fromAttribute: function ( attribute, index, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - index = index * attribute.itemSize + offset; + index = index * attribute.itemSize + offset; - this.x = attribute.array[ index ]; - this.y = attribute.array[ index + 1 ]; + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; - return this; + return this; }, diff --git a/src/math/Vector3.js b/src/math/Vector3.js index 409c5159519dfc..464a635f5cceb4 100644 --- a/src/math/Vector3.js +++ b/src/math/Vector3.js @@ -599,9 +599,9 @@ THREE.Vector3.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - return this; + return this; }, @@ -819,15 +819,15 @@ THREE.Vector3.prototype = { fromAttribute: function ( attribute, index, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - index = index * attribute.itemSize + offset; + index = index * attribute.itemSize + offset; - this.x = attribute.array[ index ]; - this.y = attribute.array[ index + 1 ]; - this.z = attribute.array[ index + 2 ]; + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; + this.z = attribute.array[ index + 2 ]; - return this; + return this; }, diff --git a/src/math/Vector4.js b/src/math/Vector4.js index aac65abb7fb2a2..d27e9ebc9e5955 100644 --- a/src/math/Vector4.js +++ b/src/math/Vector4.js @@ -507,45 +507,45 @@ THREE.Vector4.prototype = { floor: function () { - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); - this.w = Math.floor( this.w ); + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); + this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); - return this; + return this; }, ceil: function () { - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); - this.w = Math.ceil( this.w ); + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); + this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); - return this; + return this; }, round: function () { - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); - this.w = Math.round( this.w ); + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); + this.z = Math.round( this.z ); + this.w = Math.round( this.w ); - return this; + return this; }, roundToZero: function () { - this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); - this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); - this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); - return this; + return this; }, @@ -617,9 +617,9 @@ THREE.Vector4.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - return this; + return this; }, @@ -658,16 +658,16 @@ THREE.Vector4.prototype = { fromAttribute: function ( attribute, index, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - index = index * attribute.itemSize + offset; + index = index * attribute.itemSize + offset; - this.x = attribute.array[ index ]; - this.y = attribute.array[ index + 1 ]; - this.z = attribute.array[ index + 2 ]; - this.w = attribute.array[ index + 3 ]; + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; + this.z = attribute.array[ index + 2 ]; + this.w = attribute.array[ index + 3 ]; - return this; + return this; }, diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index c6f7033656a31e..47ff43d4d94503 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -6155,49 +6155,49 @@ THREE.WebGLRenderer = function ( parameters ) { this.readRenderTargetPixels = function( renderTarget, x, y, width, height, buffer ) { - if ( ! ( renderTarget instanceof THREE.WebGLRenderTarget ) ) { + if ( ! ( renderTarget instanceof THREE.WebGLRenderTarget ) ) { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); - return; + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); + return; - } + } - if ( renderTarget.__webglFramebuffer ) { + if ( renderTarget.__webglFramebuffer ) { - if ( renderTarget.format !== THREE.RGBAFormat ) { + if ( renderTarget.format !== THREE.RGBAFormat ) { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.' ); - return; + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.' ); + return; - } + } - var restore = false; + var restore = false; - if ( renderTarget.__webglFramebuffer !== _currentFramebuffer ) { + if ( renderTarget.__webglFramebuffer !== _currentFramebuffer ) { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTarget.__webglFramebuffer ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTarget.__webglFramebuffer ); - restore = true; + restore = true; - } + } - if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) { + if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) { - _gl.readPixels( x, y, width, height, _gl.RGBA, _gl.UNSIGNED_BYTE, buffer ); + _gl.readPixels( x, y, width, height, _gl.RGBA, _gl.UNSIGNED_BYTE, buffer ); - } else { + } else { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' ); + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' ); - } + } - if ( restore ) { + if ( restore ) { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer ); - } + } - } + } }; From b3b9d8bfdf78bbb832db5a50010e82a5ce6f1c43 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 11:12:58 -0800 Subject: [PATCH 169/333] ObjectLoader: Fixed onLoad. See fcf54cd2ed3b9097126c3f6b4fc5764a07f5195e. --- src/loaders/ObjectLoader.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 6e4e9272843664..d6f289077c8383 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -48,11 +48,16 @@ THREE.ObjectLoader.prototype = { var geometries = this.parseGeometries( json.geometries ); - var images = this.parseImages( json.images, onLoad ); + var images = this.parseImages( json.images, function () { + + if ( onLoad !== undefined ) onLoad( object ); + + } ); var textures = this.parseTextures( json.textures, images ); var materials = this.parseMaterials( json.materials, textures ); + var object = this.parseObject( json.object, geometries, materials ); - return this.parseObject( json.object, geometries, materials ); + return object; }, From 3289c6ce45846b06604c939514594894b8d858ad Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 13:14:14 -0800 Subject: [PATCH 170/333] ColladaLoader: Code clean up. --- examples/js/loaders/ColladaLoader.js | 43 ++++++++++++++++------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index c2608f376e58f5..63bfa31fd22ff3 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -85,11 +85,16 @@ THREE.ColladaLoader = function () { } else { - if (faillCallback) - failCallback(); - else + if ( faillCallback ) { + + failCallback(); + + } else { + console.error( "ColladaLoader: Empty or non-existing file (" + url + ")" ); + } + } } @@ -694,8 +699,7 @@ THREE.ColladaLoader = function () { } var animationBounds = calcAnimationBounds(); - var skeleton = visualScene.getChildById( instanceCtrl.skeleton[0], true ) || - visualScene.getChildBySid( instanceCtrl.skeleton[0], true ); + var skeleton = visualScene.getChildById( instanceCtrl.skeleton[0], true ) || visualScene.getChildBySid( instanceCtrl.skeleton[0], true ); //flatten the skeleton into a list of bones var bonelist = flattenSkeleton(skeleton); @@ -745,8 +749,8 @@ THREE.ColladaLoader = function () { var skinWeights = []; var weights = skinController.skin.weights; - //hook up the skin weights - // TODO - this might be a good place to choose greatest 4 weights + // hook up the skin weights + // TODO - this might be a good place to choose greatest 4 weights for(var i =0; i < weights.length; i++) { var indicies = new THREE.Vector4(weights[i][0]?weights[i][0].joint:0,weights[i][1]?weights[i][1].joint:0,weights[i][2]?weights[i][2].joint:0,weights[i][3]?weights[i][3].joint:0); @@ -1346,17 +1350,21 @@ THREE.ColladaLoader = function () { function getLibraryNode( id ) { - var nodes = COLLADA.querySelectorAll('library_nodes node'); + var nodes = COLLADA.querySelectorAll('library_nodes node'); - for ( var i = 0; i < nodes.length; i++ ) { + for ( var i = 0; i < nodes.length; i++ ) { - var attObj = nodes[i].attributes.getNamedItem('id'); - if ( attObj && attObj.value === id ) { - return nodes[i]; - } - } + var attObj = nodes[i].attributes.getNamedItem('id'); + + if ( attObj && attObj.value === id ) { + + return nodes[i]; + + } + + } - return undefined; + return undefined; }; @@ -3042,7 +3050,7 @@ THREE.ColladaLoader = function () { // FIXME: normals don't seem to be quite right - faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ], clr ) ); + faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ], clr ) ); } @@ -3607,8 +3615,7 @@ THREE.ColladaLoader = function () { } else if ( bumpType.toLowerCase() === "normalmap" ) { this[ 'normal' ] = ( new ColorOrTexture() ).parse( child ); } else { - console.error( "Shader.prototype.parse: Invalid value for attribute 'bumptype' (" + bumpType + - ") - valid bumptypes are 'HEIGHTFIELD' and 'NORMALMAP' - defaulting to 'HEIGHTFIELD'" ); + console.error( "Shader.prototype.parse: Invalid value for attribute 'bumptype' (" + bumpType + ") - valid bumptypes are 'HEIGHTFIELD' and 'NORMALMAP' - defaulting to 'HEIGHTFIELD'" ); this[ 'bump' ] = ( new ColorOrTexture() ).parse( child ); } } else { From b326bdf64b452438d09f2fa88d1629e79dfaae8b Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 13:14:42 -0800 Subject: [PATCH 171/333] Updated builds. --- build/three.js | 9 +++++++-- build/three.min.js | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/build/three.js b/build/three.js index 8ad68686ae1fa5..390ce541dcb31e 100644 --- a/build/three.js +++ b/build/three.js @@ -12621,11 +12621,16 @@ THREE.ObjectLoader.prototype = { var geometries = this.parseGeometries( json.geometries ); - var images = this.parseImages( json.images, onLoad ); + var images = this.parseImages( json.images, function () { + + if ( onLoad !== undefined ) onLoad( object ); + + } ); var textures = this.parseTextures( json.textures, images ); var materials = this.parseMaterials( json.materials, textures ); + var object = this.parseObject( json.object, geometries, materials ); - return this.parseObject( json.object, geometries, materials ); + return object; }, diff --git a/build/three.min.js b/build/three.min.js index b868852cfbd565..53672b5ee90d13 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -278,17 +278,17 @@ a=a.boundingSphere;void 0!==a&&(c=new THREE.Vector3,void 0!==a.center&&c.fromArr THREE.MaterialLoader.prototype={constructor:THREE.MaterialLoader,load:function(a,b,c,d){var e=this,f=new THREE.XHRLoader(e.manager);f.setCrossOrigin(this.crossOrigin);f.load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},setCrossOrigin:function(a){this.crossOrigin=a},parse:function(a){var b=new THREE[a.type];void 0!==a.color&&b.color.setHex(a.color);void 0!==a.emissive&&b.emissive.setHex(a.emissive);void 0!==a.specular&&b.specular.setHex(a.specular);void 0!==a.shininess&&(b.shininess=a.shininess); void 0!==a.uniforms&&(b.uniforms=a.uniforms);void 0!==a.vertexShader&&(b.vertexShader=a.vertexShader);void 0!==a.fragmentShader&&(b.fragmentShader=a.fragmentShader);void 0!==a.vertexColors&&(b.vertexColors=a.vertexColors);void 0!==a.shading&&(b.shading=a.shading);void 0!==a.blending&&(b.blending=a.blending);void 0!==a.side&&(b.side=a.side);void 0!==a.opacity&&(b.opacity=a.opacity);void 0!==a.transparent&&(b.transparent=a.transparent);void 0!==a.wireframe&&(b.wireframe=a.wireframe);void 0!==a.size&& (b.size=a.size);void 0!==a.sizeAttenuation&&(b.sizeAttenuation=a.sizeAttenuation);if(void 0!==a.materials)for(var c=0,d=a.materials.length;c Date: Thu, 19 Feb 2015 14:18:44 -0800 Subject: [PATCH 172/333] Moved ShadowMesh to examples/js/objects by now. --- {src => examples/js}/objects/ShadowMesh.js | 26 ++++----- examples/webgl_shadowmesh.html | 68 ++++++++-------------- 2 files changed, 36 insertions(+), 58 deletions(-) rename {src => examples/js}/objects/ShadowMesh.js (89%) diff --git a/src/objects/ShadowMesh.js b/examples/js/objects/ShadowMesh.js similarity index 89% rename from src/objects/ShadowMesh.js rename to examples/js/objects/ShadowMesh.js index 1ff5768d96a20f..dd14f80c44432f 100644 --- a/src/objects/ShadowMesh.js +++ b/examples/js/objects/ShadowMesh.js @@ -1,28 +1,25 @@ -// File:src/objects/ShadowMesh.js - /** * @author erichlof / http://github.com/erichlof + * + * A shadow Mesh that follows a shadow-casting Mesh in the scene, but is confined to a single plane. */ -// a shadow Mesh that follows a shadow-casting Mesh in the scene, but is confined to a single plane. - THREE.ShadowMesh = function ( mesh ) { - + var shadowMaterial = new THREE.MeshBasicMaterial( { - + color: 0x000000, transparent: true, opacity: 0.6, depthWrite: false - + } ); - + THREE.Mesh.call( this, mesh.geometry, shadowMaterial ); - + this.meshMatrix = mesh.matrixWorld; - + this.frustumCulled = false; - this.matrixAutoUpdate = false; }; @@ -32,11 +29,12 @@ THREE.ShadowMesh.prototype.constructor = THREE.ShadowMesh; THREE.ShadowMesh.prototype.update = function () { - // based on https://www.opengl.org/archives/resources/features/StencilTalk/tsld021.htm var shadowMatrix = new THREE.Matrix4(); return function ( plane, lightPosition4D ) { - + + // based on https://www.opengl.org/archives/resources/features/StencilTalk/tsld021.htm + var dot = plane.normal.x * lightPosition4D.x + plane.normal.y * lightPosition4D.y + plane.normal.z * lightPosition4D.z + @@ -63,7 +61,7 @@ THREE.ShadowMesh.prototype.update = function () { sme[ 7 ] = - lightPosition4D.w * plane.normal.y; sme[ 11 ] = - lightPosition4D.w * plane.normal.z; sme[ 15 ] = dot - lightPosition4D.w * -plane.constant; - + this.matrix.multiplyMatrices( shadowMatrix, this.meshMatrix ); }; diff --git a/examples/webgl_shadowmesh.html b/examples/webgl_shadowmesh.html index 3eb929462ceac0..761753ea9b9624 100644 --- a/examples/webgl_shadowmesh.html +++ b/examples/webgl_shadowmesh.html @@ -1,40 +1,33 @@ - three.js webgl - ShadowMesh - -
- - - -
- three.js webgl - ShadowMesh -
- + - + - - From 3de90b479add3451731d8a4e740ea7b79399925a Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 14:56:22 -0800 Subject: [PATCH 173/333] Updated builds. --- build/three.js | 306 ++++++++++++++++++++++---------------------- src/math/Vector4.js | 56 ++++---- 2 files changed, 181 insertions(+), 181 deletions(-) diff --git a/build/three.js b/build/three.js index 390ce541dcb31e..e24ea0f8f32390 100644 --- a/build/three.js +++ b/build/three.js @@ -1554,9 +1554,9 @@ THREE.Vector2.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - return this; + return this; }, @@ -1591,14 +1591,14 @@ THREE.Vector2.prototype = { fromAttribute: function ( attribute, index, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - index = index * attribute.itemSize + offset; + index = index * attribute.itemSize + offset; - this.x = attribute.array[ index ]; - this.y = attribute.array[ index + 1 ]; + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; - return this; + return this; }, @@ -2213,9 +2213,9 @@ THREE.Vector3.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - return this; + return this; }, @@ -2433,15 +2433,15 @@ THREE.Vector3.prototype = { fromAttribute: function ( attribute, index, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - index = index * attribute.itemSize + offset; + index = index * attribute.itemSize + offset; - this.x = attribute.array[ index ]; - this.y = attribute.array[ index + 1 ]; - this.z = attribute.array[ index + 2 ]; + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; + this.z = attribute.array[ index + 2 ]; - return this; + return this; }, @@ -2962,49 +2962,49 @@ THREE.Vector4.prototype = { } )(), - floor: function () { + floor: function () { - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); - this.w = Math.floor( this.w ); + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); + this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); - return this; + return this; - }, + }, - ceil: function () { + ceil: function () { - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); - this.w = Math.ceil( this.w ); + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); + this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); - return this; + return this; - }, + }, - round: function () { + round: function () { - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); - this.w = Math.round( this.w ); + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); + this.z = Math.round( this.z ); + this.w = Math.round( this.w ); - return this; + return this; - }, + }, - roundToZero: function () { + roundToZero: function () { - this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); - this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); - this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); - return this; + return this; - }, + }, negate: function () { @@ -3074,9 +3074,9 @@ THREE.Vector4.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - return this; + return this; }, @@ -3115,16 +3115,16 @@ THREE.Vector4.prototype = { fromAttribute: function ( attribute, index, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - index = index * attribute.itemSize + offset; + index = index * attribute.itemSize + offset; - this.x = attribute.array[ index ]; - this.y = attribute.array[ index + 1 ]; - this.z = attribute.array[ index + 2 ]; - this.w = attribute.array[ index + 3 ]; + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; + this.z = attribute.array[ index + 2 ]; + this.w = attribute.array[ index + 3 ]; - return this; + return this; }, @@ -4558,15 +4558,15 @@ THREE.Matrix4.prototype = { extractBasis: function ( xAxis, yAxis, zAxis ) { - var te = this.elements; + var te = this.elements; xAxis.set( te[ 0 ], te[ 1 ], te[ 2 ] ); yAxis.set( te[ 4 ], te[ 5 ], te[ 6 ] ); zAxis.set( te[ 8 ], te[ 9 ], te[ 10 ] ); - return this; + return this; - }, + }, makeBasis: function ( xAxis, yAxis, zAxis ) { @@ -4577,7 +4577,7 @@ THREE.Matrix4.prototype = { 0, 0, 0, 1 ); - return this; + return this; }, @@ -5802,7 +5802,7 @@ THREE.Ray.prototype = { }(), - intersectBox: function ( box , optionalTarget ) { + intersectBox: function ( box, optionalTarget ) { // http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-box-intersection/ @@ -6007,7 +6007,7 @@ THREE.Sphere.prototype = { var box = new THREE.Box3(); - return function ( points, optionalCenter ) { + return function ( points, optionalCenter ) { var center = this.center; @@ -6033,7 +6033,7 @@ THREE.Sphere.prototype = { return this; - }; + }; }(), @@ -7704,7 +7704,7 @@ THREE.Object3D.prototype = { if ( arguments.length > 1 ) { - for ( var i = 0; i < arguments.length; i++ ) { + for ( var i = 0; i < arguments.length; i ++ ) { this.add( arguments[ i ] ); @@ -7748,7 +7748,7 @@ THREE.Object3D.prototype = { if ( arguments.length > 1 ) { - for ( var i = 0; i < arguments.length; i++ ) { + for ( var i = 0; i < arguments.length; i ++ ) { this.remove( arguments[ i ] ); @@ -10966,7 +10966,7 @@ THREE.DirectionalLight = function ( color, intensity ) { this.shadowCascadeHeight = [ 512, 512, 512 ]; this.shadowCascadeNearZ = [ - 1.000, 0.990, 0.998 ]; - this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ]; + this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ]; this.shadowCascadeArray = []; @@ -12279,7 +12279,7 @@ THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - THREE.warn( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + + THREE.warn( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); } @@ -13184,7 +13184,7 @@ THREE.BinaryTextureLoader.prototype = { texture.image = texData.image; - } else if ( undefined !== texData.data ){ + } else if ( undefined !== texData.data ) { texture.image.width = texData.width; texture.image.height = texData.height; @@ -13289,7 +13289,7 @@ THREE.CompressedTextureLoader.prototype = { if ( loaded === 6 ) { - if (texDatas.mipmapCount == 1) + if (texDatas.mipmapCount == 1) texture.minFilter = THREE.LinearFilter; texture.format = texDatas.format; @@ -14964,7 +14964,7 @@ THREE.PointCloud.prototype.raycast = ( function () { } - for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) { + for ( var oi = 0, ol = offsets.length; oi < ol; ++ oi ) { var start = offsets[ oi ].start; var count = offsets[ oi ].count; @@ -15111,7 +15111,7 @@ THREE.Line.prototype.raycast = ( function () { } - for ( var oi = 0; oi < offsets.length; oi++){ + for ( var oi = 0; oi < offsets.length; oi ++) { var start = offsets[ oi ].start; var count = offsets[ oi ].count; @@ -15325,7 +15325,7 @@ THREE.Mesh.prototype.raycast = ( function () { if ( geometry.boundingBox !== null ) { - if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) { + if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) { return; @@ -15356,7 +15356,7 @@ THREE.Mesh.prototype.raycast = ( function () { } - for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) { + for ( var oi = 0, ol = offsets.length; oi < ol; ++ oi ) { var start = offsets[ oi ].start; var count = offsets[ oi ].count; @@ -15793,7 +15793,7 @@ THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) { var bone, gbone, p, q, s; - for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++b ) { + for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) { gbone = this.geometry.bones[ b ]; @@ -15820,7 +15820,7 @@ THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) { } - for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++b ) { + for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) { gbone = this.geometry.bones[ b ]; @@ -16379,7 +16379,7 @@ THREE.LensFlare = function ( texture, size, distance, blending, color ) { this.positionScreen = new THREE.Vector3(); this.customUpdateCallback = undefined; - if( texture !== undefined ) { + if ( texture !== undefined ) { this.add( texture, size, distance, blending, color ); @@ -16431,7 +16431,7 @@ THREE.LensFlare.prototype.updateLensFlares = function () { var vecX = - this.positionScreen.x * 2; var vecY = - this.positionScreen.y * 2; - for( f = 0; f < fl; f ++ ) { + for ( f = 0; f < fl; f ++ ) { flare = this.lensFlares[ f ]; @@ -18066,7 +18066,7 @@ THREE.WebGLRenderer = function ( parameters ) { var formats = _gl.getParameter( _gl.COMPRESSED_TEXTURE_FORMATS ); - for ( var i = 0; i < formats.length; i ++ ){ + for ( var i = 0; i < formats.length; i ++ ) { array.push( formats[ i ] ); @@ -23865,49 +23865,49 @@ THREE.WebGLRenderer = function ( parameters ) { this.readRenderTargetPixels = function( renderTarget, x, y, width, height, buffer ) { - if ( ! ( renderTarget instanceof THREE.WebGLRenderTarget ) ) { + if ( ! ( renderTarget instanceof THREE.WebGLRenderTarget ) ) { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); - return; + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); + return; - } + } - if ( renderTarget.__webglFramebuffer ) { + if ( renderTarget.__webglFramebuffer ) { - if ( renderTarget.format !== THREE.RGBAFormat ) { + if ( renderTarget.format !== THREE.RGBAFormat ) { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.' ); - return; + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.' ); + return; - } + } - var restore = false; + var restore = false; - if ( renderTarget.__webglFramebuffer !== _currentFramebuffer ) { + if ( renderTarget.__webglFramebuffer !== _currentFramebuffer ) { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTarget.__webglFramebuffer ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTarget.__webglFramebuffer ); - restore = true; + restore = true; - } + } - if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) { + if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) { - _gl.readPixels( x, y, width, height, _gl.RGBA, _gl.UNSIGNED_BYTE, buffer ); + _gl.readPixels( x, y, width, height, _gl.RGBA, _gl.UNSIGNED_BYTE, buffer ); - } else { + } else { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' ); + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' ); - } + } - if ( restore ) { + if ( restore ) { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer ); - } + } - } + } }; @@ -24590,7 +24590,7 @@ THREE.WebGLProgram = ( function () { '#define MAX_SHADOWS ' + parameters.maxShadows, - parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest: '', + parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '', _this.gammaInput ? '#define GAMMA_INPUT' : '', _this.gammaOutput ? '#define GAMMA_OUTPUT' : '', @@ -25636,7 +25636,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje }; - function projectObject( scene, object, shadowCamera ){ + function projectObject( scene, object, shadowCamera ) { if ( object.visible ) { @@ -26360,7 +26360,7 @@ THREE.ImageUtils = { points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] ); points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] ); points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] ); - points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] ); + points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] ); points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] ); points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] ); points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] ); @@ -26639,7 +26639,7 @@ THREE.FontUtils = { x = outline[ i ++ ] * scaleX + offset; y = outline[ i ++ ] * scaleY; - path.lineTo( x,y ); + path.lineTo( x, y ); break; case 'q': @@ -26665,11 +26665,11 @@ THREE.FontUtils = { var t = i2 / divisions; var tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx ); var ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy ); - } + } - } + } - break; + break; case 'b': @@ -26850,7 +26850,7 @@ THREE.FontUtils.generateShapes = function ( text, parameters ) { /* remove v from the remaining polygon */ - for ( s = v, t = v + 1; t < nv; s++, t++ ) { + for ( s = v, t = v + 1; t < nv; s ++, t ++ ) { verts[ s ] = verts[ t ]; @@ -27199,7 +27199,7 @@ THREE.Curve.prototype.getLength = function () { THREE.Curve.prototype.getLengths = function ( divisions ) { - if ( ! divisions ) divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions): 200; + if ( ! divisions ) divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions) : 200; if ( this.cacheArcLengths && ( this.cacheArcLengths.length == divisions + 1 ) @@ -27304,17 +27304,17 @@ THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) { // we could get finer grain at lengths, or use simple interpolatation between two points var lengthBefore = arcLengths[ i ]; - var lengthAfter = arcLengths[ i + 1 ]; + var lengthAfter = arcLengths[ i + 1 ]; - var segmentLength = lengthAfter - lengthBefore; + var segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points - var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; + var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; // add that fractional amount to t - var t = ( i + segmentFraction ) / ( il -1 ); + var t = ( i + segmentFraction ) / ( il - 1 ); return t; @@ -27373,8 +27373,8 @@ THREE.Curve.Utils = { tangentCubicBezier: function (t, p0, p1, p2, p3 ) { return - 3 * p0 * (1 - t) * (1 - t) + - 3 * p1 * (1 - t) * (1-t) - 6 *t *p1 * (1-t) + - 6 * t * p2 * (1-t) - 3 * t * t * p2 + + 3 * p1 * (1 - t) * (1 - t) - 6 * t * p1 * (1 - t) + + 6 * t * p2 * (1 - t) - 3 * t * t * p2 + 3 * t * t * p3; }, @@ -27465,7 +27465,7 @@ THREE.CurvePath.prototype.closePath = function() { // and verify for vector3 (needs to implement equals) // Add a line curve if start and end of lines are not connected var startPoint = this.curves[0].getPoint(0); - var endPoint = this.curves[this.curves.length-1].getPoint(1); + var endPoint = this.curves[this.curves.length - 1].getPoint(1); if (! startPoint.equals(endPoint)) { this.curves.push( new THREE.LineCurve(endPoint, startPoint) ); @@ -28053,7 +28053,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) { action = item.action; args = item.args; - switch( action ) { + switch ( action ) { case THREE.PathActions.MOVE_TO: @@ -28200,7 +28200,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) { //console.log(points); - break; + break; case THREE.PathActions.ELLIPSE: @@ -28238,7 +28238,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) { //console.log(points); - break; + break; } // end switch @@ -28345,7 +28345,7 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) { // with the horizontal line through inPt, left of inPt // not counting lowerY endpoints of edges and whole edges on that line var inside = false; - for( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { + for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { var edgeLowPt = inPolygon[ p ]; var edgeHighPt = inPolygon[ q ]; @@ -28677,16 +28677,16 @@ THREE.Shape.Utils = { if ( perpSeg2 == 0 ) { if ( ( inExcludeAdjacentSegs ) && ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return []; - return [ inSeg1Pt1 ]; + return [ inSeg1Pt1 ]; } if ( perpSeg2 == limit ) { if ( ( inExcludeAdjacentSegs ) && ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return []; - return [ inSeg1Pt2 ]; + return [ inSeg1Pt2 ]; } // intersection at endpoint of segment#2? - if ( perpSeg1 == 0 ) return [ inSeg2Pt1 ]; - if ( perpSeg1 == limit ) return [ inSeg2Pt2 ]; + if ( perpSeg1 == 0 ) return [ inSeg2Pt1 ]; + if ( perpSeg1 == limit ) return [ inSeg2Pt2 ]; // return real intersection point var factorSeg1 = perpSeg2 / limit; @@ -28704,17 +28704,17 @@ THREE.Shape.Utils = { if ( seg1Pt && seg2Pt ) { if ( (inSeg1Pt1.x != inSeg2Pt1.x) || (inSeg1Pt1.y != inSeg2Pt1.y) ) return []; // they are distinct points - return [ inSeg1Pt1 ]; // they are the same point + return [ inSeg1Pt1 ]; // they are the same point } // segment#1 is a single point if ( seg1Pt ) { if (! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) ) return []; // but not in segment#2 - return [ inSeg1Pt1 ]; + return [ inSeg1Pt1 ]; } // segment#2 is a single point if ( seg2Pt ) { if (! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) ) return []; // but not in segment#1 - return [ inSeg2Pt1 ]; + return [ inSeg2Pt1 ]; } // they are collinear segments, which might overlap @@ -28845,7 +28845,7 @@ THREE.Shape.Utils = { // checks for intersections with shape edges var sIdx, nextIdx, intersection; for ( sIdx = 0; sIdx < shape.length; sIdx ++ ) { - nextIdx = sIdx+1; nextIdx %= shape.length; + nextIdx = sIdx + 1; nextIdx %= shape.length; intersection = intersect_segments_2D( inShapePt, inHolePt, shape[sIdx], shape[nextIdx], true ); if ( intersection.length > 0 ) return true; } @@ -28862,7 +28862,7 @@ THREE.Shape.Utils = { for ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) { chkHole = holes[indepHoles[ihIdx]]; for ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) { - nextIdx = hIdx+1; nextIdx %= chkHole.length; + nextIdx = hIdx + 1; nextIdx %= chkHole.length; intersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[hIdx], chkHole[nextIdx], true ); if ( intersection.length > 0 ) return true; } @@ -28914,12 +28914,12 @@ THREE.Shape.Utils = { if ( intersectsHoleEdge( shapePt, holePt ) ) continue; holeIndex = h2; - indepHoles.splice(h,1); + indepHoles.splice(h, 1); - tmpShape1 = shape.slice( 0, shapeIndex+1 ); + tmpShape1 = shape.slice( 0, shapeIndex + 1 ); tmpShape2 = shape.slice( shapeIndex ); tmpHole1 = hole.slice( holeIndex ); - tmpHole2 = hole.slice( 0, holeIndex+1 ); + tmpHole2 = hole.slice( 0, holeIndex + 1 ); shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 ); @@ -29233,8 +29233,8 @@ THREE.SplineCurve.prototype.getPoint = function ( t ) { var point0 = points[ intPoint == 0 ? intPoint : intPoint - 1 ] var point1 = points[ intPoint ] - var point2 = points[ intPoint > points.length - 2 ? points.length -1 : intPoint + 1 ] - var point3 = points[ intPoint > points.length - 3 ? points.length -1 : intPoint + 2 ] + var point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ] + var point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ] var vector = new THREE.Vector2(); @@ -29726,7 +29726,7 @@ THREE.Animation.prototype.keyTypes = [ "pos", "rot", "scl" ]; THREE.Animation.prototype.play = function ( startTime, weight ) { this.currentTime = startTime !== undefined ? startTime : 0; - this.weight = weight !== undefined ? weight: 1; + this.weight = weight !== undefined ? weight : 1; this.isPlaying = true; @@ -29817,7 +29817,7 @@ THREE.Animation.prototype.resetBlendWeights = function () { }; -THREE.Animation.prototype.update = (function(){ +THREE.Animation.prototype.update = (function() { var points = []; var target = new THREE.Vector3(); @@ -30967,7 +30967,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var contour = vertices; // vertices has all points but contour has only points of circumference - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { ahole = holes[ h ]; @@ -31100,7 +31100,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var pt_j = contour[ j ]; var pt_k = contour[ k ]; - contourMovements[ i ]= getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); + contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); } @@ -31118,7 +31118,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { if ( k === il ) k = 0; // (j)---(i)---(k) - oneHoleMovements[ i ]= getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); + oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); } @@ -31137,7 +31137,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { z = bevelThickness * ( 1 - t ); //z = bevelThickness * t; - bs = bevelSize * ( Math.sin ( t * Math.PI/2 ) ) ; // curved + bs = bevelSize * ( Math.sin ( t * Math.PI / 2 ) ) ; // curved //bs = bevelSize * t ; // linear // contract shape @@ -31237,7 +31237,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { t = b / bevelSegments; z = bevelThickness * ( 1 - t ); //bs = bevelSize * ( 1-Math.sin ( ( 1 - t ) * Math.PI/2 ) ); - bs = bevelSize * Math.sin ( t * Math.PI/2 ) ; + bs = bevelSize * Math.sin ( t * Math.PI / 2 ) ; // contract shape @@ -31300,7 +31300,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { for ( i = 0; i < flen; i ++ ) { face = faces[ i ]; - f3( face[ 2 ]+ offset, face[ 1 ]+ offset, face[ 0 ] + offset ); + f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset ); } @@ -31347,7 +31347,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { sidewalls( contour, layeroffset ); layeroffset += contour.length; - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { ahole = holes[ h ]; sidewalls( ahole, layeroffset ); @@ -31364,7 +31364,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var j, k; i = contour.length; - while ( --i >= 0 ) { + while ( -- i >= 0 ) { j = i; k = i - 1; @@ -31409,7 +31409,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var uvs = uvgen.generateTopUV( scope, a, b, c ); - scope.faceVertexUvs[ 0 ].push( uvs ); + scope.faceVertexUvs[ 0 ].push( uvs ); } @@ -31420,13 +31420,13 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { c += shapesOffset; d += shapesOffset; - scope.faces.push( new THREE.Face3( a, b, d, null, null, extrudeMaterial ) ); - scope.faces.push( new THREE.Face3( b, c, d, null, null, extrudeMaterial ) ); + scope.faces.push( new THREE.Face3( a, b, d, null, null, extrudeMaterial ) ); + scope.faces.push( new THREE.Face3( b, c, d, null, null, extrudeMaterial ) ); - var uvs = uvgen.generateSideWallUV( scope, a, b, c, d ); + var uvs = uvgen.generateSideWallUV( scope, a, b, c, d ); - scope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] ); - scope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] ); + scope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] ); + scope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] ); } @@ -32572,17 +32572,17 @@ THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { for ( i = 1; i < numpoints; i ++ ) { - normals[ i ] = normals[ i-1 ].clone(); + normals[ i ] = normals[ i - 1 ].clone(); - binormals[ i ] = binormals[ i-1 ].clone(); + binormals[ i ] = binormals[ i - 1 ].clone(); - vec.crossVectors( tangents[ i-1 ], tangents[ i ] ); + vec.crossVectors( tangents[ i - 1 ], tangents[ i ] ); if ( vec.length() > epsilon ) { vec.normalize(); - theta = Math.acos( THREE.Math.clamp( tangents[ i-1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors + theta = Math.acos( THREE.Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); @@ -32597,10 +32597,10 @@ THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { if ( closed ) { - theta = Math.acos( THREE.Math.clamp( normals[ 0 ].dot( normals[ numpoints-1 ] ), - 1, 1 ) ); + theta = Math.acos( THREE.Math.clamp( normals[ 0 ].dot( normals[ numpoints - 1 ] ), - 1, 1 ) ); theta /= ( numpoints - 1 ); - if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ numpoints-1 ] ) ) > 0 ) { + if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ numpoints - 1 ] ) ) > 0 ) { theta = - theta; diff --git a/src/math/Vector4.js b/src/math/Vector4.js index d27e9ebc9e5955..940f3ce8cb0764 100644 --- a/src/math/Vector4.js +++ b/src/math/Vector4.js @@ -505,49 +505,49 @@ THREE.Vector4.prototype = { } )(), - floor: function () { + floor: function () { - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); - this.w = Math.floor( this.w ); + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); + this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); - return this; + return this; - }, + }, - ceil: function () { + ceil: function () { - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); - this.w = Math.ceil( this.w ); + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); + this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); - return this; + return this; - }, + }, - round: function () { + round: function () { - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); - this.w = Math.round( this.w ); + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); + this.z = Math.round( this.z ); + this.w = Math.round( this.w ); - return this; + return this; - }, + }, - roundToZero: function () { + roundToZero: function () { - this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); - this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); - this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); - return this; + return this; - }, + }, negate: function () { From ebd739ad141500ba59b548f4a8128b5c30a8d534 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 15:51:54 -0800 Subject: [PATCH 174/333] Docs: Nicer ASCII. --- docs/index.html | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/index.html b/docs/index.html index a51b6a8fae7327..645f432298cc9d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -269,11 +269,11 @@

three.js / docs

var li = document.createElement( 'li' ); var a = document.createElement( 'a' ); a.setAttribute( 'href', '#' ); - ( function( s, c, p ) { + ( function( s, c, p ) { a.addEventListener( 'click', function( e ) { goTo( s, c, p ); e.preventDefault(); - } ) + } ) } )( section, category, page[ 0 ] ) a.textContent = page[ 0 ]; li.appendChild( a ); @@ -370,7 +370,7 @@

three.js / docs

// Resolve links of the form 'Class.member' if(section.indexOf(MEMBER_DELIMITER) !== -1) { parts = section.split(MEMBER_DELIMITER) - section = parts[0]; + section = parts[0]; member = parts[1]; } @@ -379,7 +379,7 @@

three.js / docs

section = location.section; category = location.category; name = location.name; - } + } var title = 'three.js - documentation - ' + section + ' - ' + name; var url = encodeUrl(section) + DELIMITER + encodeUrl( category ) + DELIMITER + encodeUrl(name) + (!!member ? MEMBER_DELIMITER + encodeUrl(member) : ''); @@ -405,17 +405,17 @@

three.js / docs

if ( window.location.hash.length > 0 ) goToHash(); - console.log(["\n __________ ____\n", - " /\\ \\/\\ \\ ____ ____ __\n", - " / \\_________\\ \\___\\ _______ /\\ \\ /\\ \\ _ / /\\\n", - " \\ / / / / /\\ \\/ \\___\\/ \\___\\ / /\\ / / /_ \n", - " \\__ ___/ / / \\/ \\______\\ / __ \\ / __ \\ / / / /_/ / \\\n", - " __/ / // / /___\\ / __ / / ____/ / ____/ /_/ \\ \\ \\ / / \n", - "/\\ \\ / / \\ / __ / / /\\/_/\\/ /___\\\\/ /___\\ \\_\\/\\ \\ `/`/ /\n", - "\\ \\ \\/___/ \\/___/\\/__/\\/__/ \\_____/ \\_____/ __ \\_\\ \\ \\_\\/\n", - " \\ \\____________________________________________\\ /_/\\ /_/ /\n", - " \\/____________________________________________/ \\_\\/ \\_\\/\n"].join('')) - + console.log([ + '________ __', + '/ ________\\/ __\\__ ____ _____ _____', + '\\/__ ___/ / /___\\/ ____\\/ _____\\/ _____\\', + ' / / / / / _ / / __/ / __ / / __ /_ __ _____', + '/ / / / / / / / / / / / ___/ / ___/\\ _\\/ __\\/ _____\\', + '\\/__/ \\/__/\\/__/\\/__/ \\/_____/\\/_____/\\/__/ / / / ___/', + ' / __/ / \\__ \\', + ' \\/____/\\/_____/' + ].join('\n')); + From e044429b791aa1a8629f5a8b58b6782aee3f44fd Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 15:56:20 -0800 Subject: [PATCH 175/333] Docs: Fixed ASCII T. --- docs/index.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/index.html b/docs/index.html index 645f432298cc9d..b2d1624f909ffa 100644 --- a/docs/index.html +++ b/docs/index.html @@ -406,14 +406,14 @@

three.js / docs

if ( window.location.hash.length > 0 ) goToHash(); console.log([ - '________ __', - '/ ________\\/ __\\__ ____ _____ _____', - '\\/__ ___/ / /___\\/ ____\\/ _____\\/ _____\\', - ' / / / / / _ / / __/ / __ / / __ /_ __ _____', - '/ / / / / / / / / / / / ___/ / ___/\\ _\\/ __\\/ _____\\', - '\\/__/ \\/__/\\/__/\\/__/ \\/_____/\\/_____/\\/__/ / / / ___/', - ' / __/ / \\__ \\', - ' \\/____/\\/_____/' + '_______ __', + '/ _______\\/ __\\__ ____ _____ _____', + '\\/__ __/ / /___\\/ ____\\/ _____\\/ _____\\', + ' / / / / / _ / / __/ / __ / / __ /_ __ _____', + '/ / / / / / / / / / / / ___/ / ___/\\ _\\/ __\\/ _____\\', + '\\/__/ \\/__/\\/__/\\/__/ \\/_____/\\/_____/\\/__/ / / / ___/', + ' / __/ / \\__ \\', + ' \\/____/\\/_____/' ].join('\n')); From 052f81ab6ed877935ad4657453752e9efa8018a4 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 16:14:05 -0800 Subject: [PATCH 176/333] Object3D/WebGLRenderer: Added .renderOrder. See #5496. --- src/core/Object3D.js | 1 + src/renderers/WebGLRenderer.js | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 3afb965aca5383..46f92db63ce1db 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -70,6 +70,7 @@ THREE.Object3D = function () { this.receiveShadow = false; this.frustumCulled = true; + this.renderOrder = 0; this.userData = {}; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 47ff43d4d94503..b9cde399cdf4b1 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3263,7 +3263,11 @@ THREE.WebGLRenderer = function ( parameters ) { function painterSortStable ( a, b ) { - if ( a.material.id !== b.material.id ) { + if ( a.renderOrder !== b.renderOrder ) { + + return a.renderOrder - b.renderOrder; + + } else if ( a.material.id !== b.material.id ) { return a.material.id - b.material.id; @@ -3281,7 +3285,11 @@ THREE.WebGLRenderer = function ( parameters ) { function reversePainterSortStable ( a, b ) { - if ( a.z !== b.z ) { + if ( a.renderOrder !== b.renderOrder ) { + + return a.renderOrder - b.renderOrder; + + } if ( a.z !== b.z ) { return b.z - a.z; From 837fa7f24b709617eaa126e01c67c8a7e58c0159 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 16:18:07 -0800 Subject: [PATCH 177/333] Updated builds. --- build/three.js | 13 ++- build/three.min.js | 267 +++++++++++++++++++++++---------------------- 2 files changed, 145 insertions(+), 135 deletions(-) diff --git a/build/three.js b/build/three.js index e24ea0f8f32390..716938afd8c193 100644 --- a/build/three.js +++ b/build/three.js @@ -7472,6 +7472,7 @@ THREE.Object3D = function () { this.receiveShadow = false; this.frustumCulled = true; + this.renderOrder = 0; this.userData = {}; @@ -20973,7 +20974,11 @@ THREE.WebGLRenderer = function ( parameters ) { function painterSortStable ( a, b ) { - if ( a.material.id !== b.material.id ) { + if ( a.renderOrder !== b.renderOrder ) { + + return a.renderOrder - b.renderOrder; + + } else if ( a.material.id !== b.material.id ) { return a.material.id - b.material.id; @@ -20991,7 +20996,11 @@ THREE.WebGLRenderer = function ( parameters ) { function reversePainterSortStable ( a, b ) { - if ( a.z !== b.z ) { + if ( a.renderOrder !== b.renderOrder ) { + + return a.renderOrder - b.renderOrder; + + } if ( a.z !== b.z ) { return b.z - a.z; diff --git a/build/three.min.js b/build/three.min.js index 53672b5ee90d13..bff367a19699f1 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -157,7 +157,7 @@ c[a].push(b)},hasEventListener:function(a,b){if(void 0===this._listeners)return! (this.ray.origin.copy(c.position),this.ray.direction.set(b.x,b.y,.5).unproject(c).sub(c.position).normalize()):c instanceof a.OrthographicCamera?(this.ray.origin.set(b.x,b.y,-1).unproject(c),this.ray.direction.set(0,0,-1).transformDirection(c.matrixWorld)):a.error("THREE.Raycaster: Unsupported camera type.")},intersectObject:function(a,e){var f=[];c(a,this,f,e);f.sort(b);return f},intersectObjects:function(d,e){var f=[];if(!1===d instanceof Array)return a.warn("THREE.Raycaster.intersectObjects: objects is not an Array."), f;for(var g=0,h=d.length;gh&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(n={id:mc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m, -numMorphNormals:p},q[k]=n,s.push(n)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=s;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gX;X++)pa=L[X],Ua[Ya]=pa.x,Ua[Ya+1]=pa.y,Ua[Ya+2]=pa.z,Ya+=3;else for(X=0;3>X;X++)Ua[Ya]=P.x,Ua[Ya+1]= -P.y,Ua[Ya+2]=P.z,Ya+=3;l.bindBuffer(l.ARRAY_BUFFER,u.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Ua,C)}if(xb&&Ib){y=0;for(z=Z.length;yX;X++)ma=S[X],Qa[qb]=ma.x,Qa[qb+1]=ma.y,qb+=2;0X;X++)cb=Q[X],rb[ua]=cb.x,rb[ua+1]=cb.y,ua+=2;0wa;wa++)kb[wa]=!B.autoScaleCubemaps||Vb||Jb?Jb?W.image[wa].image:W.image[wa]:L(W.image[wa],Gc); -var Sb=kb[0],Tb=THREE.Math.isPowerOfTwo(Sb.width)&&THREE.Math.isPowerOfTwo(Sb.height),bb=S(W.format),wb=S(W.type);z(l.TEXTURE_CUBE_MAP,W,Tb);for(wa=0;6>wa;wa++)if(Vb)for(var lb,Ub=kb[wa].mipmaps,Eb=0,Wb=Ub.length;Eb=sc&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Nb+=1;return a}function A(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)} -function F(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a){a*=P;a!==tc&&(l.lineWidth(a),tc=a)}function E(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc===c||(l.polygonOffset(b,c),vc=b,wc=c)}function z(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,S(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,S(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,S(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,S(b.minFilter))):(l.texParameteri(a, -l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,K(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,K(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+ -b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width, -a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function J(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height), -l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function M(a){a instanceof THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function K(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter|| -a===THREE.NearestMipMapLinearFilter?l.NEAREST:l.LINEAR}function S(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST; -if(a===THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT; -if(a===THREE.FloatType)return l.FLOAT;b=aa.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return l.ALPHA;if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT; -if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a===THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR; -if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE;b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; -if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var O=void 0!==a.canvas?a.canvas:document.createElement("canvas"),N=void 0!== -a.context?a.context:null,P=1,V=void 0!==a.precision?a.precision:"highp",I=void 0!==a.alpha?a.alpha:!1,ma=void 0!==a.depth?a.depth:!0,ca=void 0!==a.stencil?a.stencil:!0,qa=void 0!==a.antialias?a.antialias:!1,Q=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,ua=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,pa=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ja=new THREE.Color(0),ta=0,xa=[],ya={},Ma=[],Ea=[],Ra=[],Da=[],pb=[];this.domElement=O;this.context=null;this.sortObjects= -this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,cb=[],$b=null,yb=null,xb=-1,La="", -Fb=null,Nb=0,zb=-1,Pb=-1,Qb=-1,Rb=-1,ac=-1,Sb=-1,Tb=-1,Ub=-1,gc=-1,hc=-1,ic=-1,uc=null,vc=null,wc=null,tc=null,mb=0,nb=0,Wa=O.width,eb=O.height,xc=0,yc=0,ob=new Uint8Array(16),Qa=new Uint8Array(16),hb=new THREE.Frustum,ub=new THREE.Matrix4;new THREE.Matrix4;var Aa=new THREE.Vector3,la=new THREE.Vector3,Gb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[], -anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},l;try{var zc={alpha:I,depth:ma,stencil:ca,antialias:qa,premultipliedAlpha:Q,preserveDrawingBuffer:ua};l=N||O.getContext("webgl",zc)||O.getContext("experimental-webgl",zc);if(null===l){if(null!==O.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}O.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();ya={}}, -!1)}catch(Hc){THREE.error("THREE.WebGLRenderer: "+Hc)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_texture_half_float");aa.get("OES_texture_half_float_linear");aa.get("OES_standard_derivatives");pa&&aa.get("EXT_frag_depth");var jc=function(a,b,c,d){!0===Q&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0, -0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND);l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(mb,nb,Wa,eb);jc(ja.r,ja.g,ja.b,ta)},Ac=function(){Fb=$b=null;Pb=zb=ic=hc=Qb=-1;La="";xb=-1;Gb=!0;for(var a=0;ab;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--}, -pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."), -q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&&n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]=l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER, -l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),z(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0, -d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER, -null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Wa,a=eb,d=mb,e=nb);b!==yb&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),yb=b);xc=c;yc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); -else{var g=!1;a.__webglFramebuffer!==yb&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)===l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,yb)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}; -this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +a.defaultAttributeValues[m]):3===a.defaultAttributeValues[m].length&&l.vertexAttrib3fv(p,a.defaultAttributeValues[m]))}}g()}function e(){for(var a=0,b=ob.length;ah&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(n={id:mc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:p},q[k]=n,s.push(n)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=s;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gX;X++)pa=L[X],Ua[Ya]=pa.x,Ua[Ya+1]=pa.y,Ua[Ya+2]=pa.z,Ya+=3;else for(X=0;3>X;X++)Ua[Ya]=P.x,Ua[Ya+1]=P.y,Ua[Ya+2]=P.z,Ya+=3;l.bindBuffer(l.ARRAY_BUFFER,u.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Ua,C)}if(xb&&Ib){y=0;for(z=Z.length;yX;X++)ma=S[X],Qa[qb]=ma.x,Qa[qb+1]=ma.y,qb+=2;0X;X++)cb=Q[X],rb[ua]=cb.x,rb[ua+1]=cb.y,ua+=2;0wa;wa++)kb[wa]=!B.autoScaleCubemaps||Vb||Jb?Jb?W.image[wa].image:W.image[wa]:L(W.image[wa],Gc);var Sb=kb[0],Tb=THREE.Math.isPowerOfTwo(Sb.width)&&THREE.Math.isPowerOfTwo(Sb.height),bb=S(W.format),wb=S(W.type);z(l.TEXTURE_CUBE_MAP,W,Tb);for(wa=0;6>wa;wa++)if(Vb)for(var lb,Ub=kb[wa].mipmaps,Eb=0,Wb=Ub.length;Eb=sc&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Nb+=1;return a}function A(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function F(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a){a*=P;a!==tc&&(l.lineWidth(a),tc=a)}function E(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc=== +c||(l.polygonOffset(b,c),vc=b,wc=c)}function z(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,S(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,S(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,S(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,S(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+ +b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,K(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,K(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a} +function J(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function M(a){a instanceof +THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function K(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?l.NEAREST:l.LINEAR}function S(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE; +if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4; +if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT;if(a===THREE.FloatType)return l.FLOAT;b=aa.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return l.ALPHA; +if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a===THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR; +if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE;b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT; +if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; +if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var O=void 0!==a.canvas?a.canvas:document.createElement("canvas"),N=void 0!==a.context?a.context:null,P=1,V=void 0!==a.precision?a.precision:"highp",I=void 0!==a.alpha?a.alpha:!1,ma=void 0!==a.depth?a.depth:!0,ca=void 0!==a.stencil? +a.stencil:!0,qa=void 0!==a.antialias?a.antialias:!1,Q=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,ua=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,pa=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ja=new THREE.Color(0),ta=0,xa=[],ya={},Ma=[],Ea=[],Ra=[],Da=[],pb=[];this.domElement=O;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput= +!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,cb=[],$b=null,yb=null,xb=-1,La="",Fb=null,Nb=0,zb=-1,Pb=-1,Qb=-1,Rb=-1,ac=-1,Sb=-1,Tb=-1,Ub=-1,gc=-1,hc=-1,ic=-1,uc=null,vc=null,wc=null,tc=null,mb=0,nb=0,Wa=O.width,eb=O.height,xc=0,yc=0, +ob=new Uint8Array(16),Qa=new Uint8Array(16),hb=new THREE.Frustum,ub=new THREE.Matrix4;new THREE.Matrix4;var Aa=new THREE.Vector3,la=new THREE.Vector3,Gb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},l;try{var zc={alpha:I,depth:ma,stencil:ca,antialias:qa, +premultipliedAlpha:Q,preserveDrawingBuffer:ua};l=N||O.getContext("webgl",zc)||O.getContext("experimental-webgl",zc);if(null===l){if(null!==O.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}O.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();ya={}},!1)}catch(Hc){THREE.error("THREE.WebGLRenderer: "+Hc)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1, +precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_texture_half_float");aa.get("OES_texture_half_float_linear");aa.get("OES_standard_derivatives");pa&&aa.get("EXT_frag_depth");var jc=function(a,b,c,d){!0===Q&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND); +l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(mb,nb,Wa,eb);jc(ja.r,ja.g,ja.b,ta)},Ac=function(){Fb=$b=null;Pb=zb=ic=hc=Qb=-1;La="";xb=-1;Gb=!0;for(var a=0;ab;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), +c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&& +n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]= +l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: +l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),z(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER, +l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Wa,a=eb,d=mb,e=nb);b!==yb&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),yb=b);xc=c;yc=a};this.readRenderTargetPixels= +function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==yb&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== +l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,yb)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; +this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; From 1f5d18b5cd6ba2a96fb8235f89a1a8b107d3b48f Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 18:03:12 -0800 Subject: [PATCH 178/333] WebGLRenderer: _old* to _current*. --- src/renderers/WebGLRenderer.js | 106 ++++++++++++++++----------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index f8076dabe9ad63..26284e66d5e896 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -120,26 +120,26 @@ THREE.WebGLRenderer = function ( parameters ) { // GL state cache - _oldDoubleSided = - 1, - _oldFlipSided = - 1, + _currentDoubleSided = - 1, + _currentFlipSided = - 1, - _oldBlending = - 1, + _currentBlending = - 1, - _oldBlendEquation = - 1, - _oldBlendSrc = - 1, - _oldBlendDst = - 1, - _oldBlendEquationAlpha = - 1, - _oldBlendSrcAlpha = - 1, - _oldBlendDstAlpha = - 1, + _currentBlendEquation = - 1, + _currentBlendSrc = - 1, + _currentBlendDst = - 1, + _currentBlendEquationAlpha = - 1, + _currentBlendSrcAlpha = - 1, + _currentBlendDstAlpha = - 1, - _oldDepthTest = - 1, - _oldDepthWrite = - 1, + _currentDepthTest = - 1, + _currentDepthWrite = - 1, - _oldPolygonOffset = null, - _oldPolygonOffsetFactor = null, - _oldPolygonOffsetUnits = null, + _currentPolygonOffset = null, + _currentPolygonOffsetFactor = null, + _currentPolygonOffsetUnits = null, - _oldLineWidth = null, + _currentLineWidth = null, _viewportX = 0, _viewportY = 0, @@ -296,11 +296,11 @@ THREE.WebGLRenderer = function ( parameters ) { _currentProgram = null; _currentCamera = null; - _oldBlending = - 1; - _oldDepthTest = - 1; - _oldDepthWrite = - 1; - _oldDoubleSided = - 1; - _oldFlipSided = - 1; + _currentBlending = - 1; + _currentDepthTest = - 1; + _currentDepthWrite = - 1; + _currentDoubleSided = - 1; + _currentFlipSided = - 1; _currentGeometryProgram = ''; _currentMaterialId = - 1; @@ -5460,7 +5460,7 @@ THREE.WebGLRenderer = function ( parameters ) { var doubleSided = material.side === THREE.DoubleSide; var flipSided = material.side === THREE.BackSide; - if ( _oldDoubleSided !== doubleSided ) { + if ( _currentDoubleSided !== doubleSided ) { if ( doubleSided ) { @@ -5472,11 +5472,11 @@ THREE.WebGLRenderer = function ( parameters ) { } - _oldDoubleSided = doubleSided; + _currentDoubleSided = doubleSided; } - if ( _oldFlipSided !== flipSided ) { + if ( _currentFlipSided !== flipSided ) { if ( flipSided ) { @@ -5488,7 +5488,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - _oldFlipSided = flipSided; + _currentFlipSided = flipSided; } @@ -5496,7 +5496,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.setDepthTest = function ( depthTest ) { - if ( _oldDepthTest !== depthTest ) { + if ( _currentDepthTest !== depthTest ) { if ( depthTest ) { @@ -5508,7 +5508,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - _oldDepthTest = depthTest; + _currentDepthTest = depthTest; } @@ -5516,10 +5516,10 @@ THREE.WebGLRenderer = function ( parameters ) { this.setDepthWrite = function ( depthWrite ) { - if ( _oldDepthWrite !== depthWrite ) { + if ( _currentDepthWrite !== depthWrite ) { _gl.depthMask( depthWrite ); - _oldDepthWrite = depthWrite; + _currentDepthWrite = depthWrite; } @@ -5529,11 +5529,11 @@ THREE.WebGLRenderer = function ( parameters ) { width *= pixelRatio; - if ( width !== _oldLineWidth ) { + if ( width !== _currentLineWidth ) { _gl.lineWidth( width ); - _oldLineWidth = width; + _currentLineWidth = width; } @@ -5541,7 +5541,7 @@ THREE.WebGLRenderer = function ( parameters ) { function setPolygonOffset ( polygonoffset, factor, units ) { - if ( _oldPolygonOffset !== polygonoffset ) { + if ( _currentPolygonOffset !== polygonoffset ) { if ( polygonoffset ) { @@ -5553,16 +5553,16 @@ THREE.WebGLRenderer = function ( parameters ) { } - _oldPolygonOffset = polygonoffset; + _currentPolygonOffset = polygonoffset; } - if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) { + if ( polygonoffset && ( _currentPolygonOffsetFactor !== factor || _currentPolygonOffsetUnits !== units ) ) { _gl.polygonOffset( factor, units ); - _oldPolygonOffsetFactor = factor; - _oldPolygonOffsetUnits = units; + _currentPolygonOffsetFactor = factor; + _currentPolygonOffsetUnits = units; } @@ -5570,7 +5570,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { - if ( blending !== _oldBlending ) { + if ( blending !== _currentBlending ) { if ( blending === THREE.NoBlending ) { @@ -5608,7 +5608,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - _oldBlending = blending; + _currentBlending = blending; } @@ -5618,34 +5618,34 @@ THREE.WebGLRenderer = function ( parameters ) { blendSrcAlpha = blendSrcAlpha || blendSrc; blendDstAlpha = blendDstAlpha || blendDst; - if ( blendEquation !== _oldBlendEquation || blendEquationAlpha !== _oldBlendEquationAlpha ) { + if ( blendEquation !== _currentBlendEquation || blendEquationAlpha !== _currentBlendEquationAlpha ) { _gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) ); - _oldBlendEquation = blendEquation; - _oldBlendEquationAlpha = blendEquationAlpha; + _currentBlendEquation = blendEquation; + _currentBlendEquationAlpha = blendEquationAlpha; } - if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst || blendSrcAlpha !== _oldBlendSrcAlpha || blendDstAlpha !== _oldBlendDstAlpha ) { + if ( blendSrc !== _currentBlendSrc || blendDst !== _currentBlendDst || blendSrcAlpha !== _currentBlendSrcAlpha || blendDstAlpha !== _currentBlendDstAlpha ) { _gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) ); - _oldBlendSrc = blendSrc; - _oldBlendDst = blendDst; - _oldBlendSrcAlpha = blendSrcAlpha; - _oldBlendDstAlpha = blendDstAlpha; + _currentBlendSrc = blendSrc; + _currentBlendDst = blendDst; + _currentBlendSrcAlpha = blendSrcAlpha; + _currentBlendDstAlpha = blendDstAlpha; } } else { - _oldBlendEquation = null; - _oldBlendSrc = null; - _oldBlendDst = null; - _oldBlendEquationAlpha = null; - _oldBlendSrcAlpha = null; - _oldBlendDstAlpha = null; + _currentBlendEquation = null; + _currentBlendSrc = null; + _currentBlendDst = null; + _currentBlendEquationAlpha = null; + _currentBlendSrcAlpha = null; + _currentBlendDstAlpha = null; } @@ -5691,10 +5691,10 @@ THREE.WebGLRenderer = function ( parameters ) { if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) { - if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) { + if ( texture.anisotropy > 1 || texture.__currentAnisotropy ) { _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) ); - texture.__oldAnisotropy = texture.anisotropy; + texture.__currentAnisotropy = texture.anisotropy; } From 8435ab7daf3b807fd9dd87be56b7fb6c0c6e9cec Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 18:51:04 -0800 Subject: [PATCH 179/333] Fixed ColladaLoader. --- examples/js/loaders/ColladaLoader.js | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index d487087738d4cf..fe6918622c464f 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -1352,7 +1352,6 @@ THREE.ColladaLoader = function () { var nodes = COLLADA.querySelectorAll('library_nodes node'); -<<<<<<< HEAD for ( var i = 0; i < nodes.length; i++ ) { var attObj = nodes[i].attributes.getNamedItem('id'); @@ -1363,14 +1362,6 @@ THREE.ColladaLoader = function () { } -======= - for ( var i = 0; i < nodes.length; i ++ ) { - - var attObj = nodes[i].attributes.getNamedItem('id'); - if ( attObj && attObj.value === id ) { - return nodes[i]; - } ->>>>>>> 4501d5a51d49e2e709930188a02af8d3dec5da61 } return undefined; @@ -3059,11 +3050,7 @@ THREE.ColladaLoader = function () { // FIXME: normals don't seem to be quite right -<<<<<<< HEAD - faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ], clr ) ); -======= - faces.push( new THREE.Face3( vs[0], vs[k], vs[k + 1], [ ns[0], ns[k ++], ns[k] ], clr ) ); ->>>>>>> 4501d5a51d49e2e709930188a02af8d3dec5da61 + faces.push( new THREE.Face3( vs[0], vs[k], vs[k + 1], [ ns[0], ns[k ++], ns[k] ], clr ) ); } From c5ec18bfddbaaceaa61f7f708ae2df5eaf1bbb6a Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 18:51:59 -0800 Subject: [PATCH 180/333] Started THREE.WebGLState. --- .../js/renderers/plugins/DepthPassPlugin.js | 35 ++- src/renderers/WebGLRenderer.js | 206 ++---------------- src/renderers/webgl/WebGLState.js | 188 ++++++++++++++++ .../webgl/plugins/LensFlarePlugin.js | 4 +- .../webgl/plugins/ShadowMapPlugin.js | 4 +- src/renderers/webgl/plugins/SpritePlugin.js | 6 +- utils/build/includes/common.json | 1 + 7 files changed, 230 insertions(+), 214 deletions(-) create mode 100644 src/renderers/webgl/WebGLState.js diff --git a/examples/js/renderers/plugins/DepthPassPlugin.js b/examples/js/renderers/plugins/DepthPassPlugin.js index 08491865f44103..ce6545f58ff5b6 100644 --- a/examples/js/renderers/plugins/DepthPassPlugin.js +++ b/examples/js/renderers/plugins/DepthPassPlugin.js @@ -33,21 +33,21 @@ THREE.DepthPassPlugin = function () { vertexShader: depthShader.vertexShader, uniforms: depthUniforms } ); - + _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } ); - + _depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } ); - + _depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, @@ -86,7 +86,7 @@ THREE.DepthPassPlugin = function () { _gl.clearColor( 1, 1, 1, 1 ); _gl.disable( _gl.BLEND ); - _renderer.setDepthTest( true ); + _renderer.state.setDepthTest( true ); // update scene @@ -105,7 +105,7 @@ THREE.DepthPassPlugin = function () { _renderer.clear(); // set object matrices & frustum culling - + _renderList.length = 0; projectObject(scene, scene, camera); @@ -188,31 +188,31 @@ THREE.DepthPassPlugin = function () { _gl.enable( _gl.BLEND ); }; - + function projectObject(scene, object,camera) { - + if ( object.visible ) { - + var webglObjects = _webglObjects[object.id]; - + if (webglObjects && (object.frustumCulled === false || _frustum.intersectsObject( object ) === true) ) { - - + + for (var i = 0, l = webglObjects.length; i < l; i ++) { - + var webglObject = webglObjects[i]; - + object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); _renderList.push(webglObject); - + } } - + for (var i = 0, l = object.children.length; i < l; i ++) { - + projectObject(scene, object.children[i], camera); } - + } } @@ -228,4 +228,3 @@ THREE.DepthPassPlugin = function () { }; }; - diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 26284e66d5e896..161bfce9593003 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -123,24 +123,6 @@ THREE.WebGLRenderer = function ( parameters ) { _currentDoubleSided = - 1, _currentFlipSided = - 1, - _currentBlending = - 1, - - _currentBlendEquation = - 1, - _currentBlendSrc = - 1, - _currentBlendDst = - 1, - _currentBlendEquationAlpha = - 1, - _currentBlendSrcAlpha = - 1, - _currentBlendDstAlpha = - 1, - - _currentDepthTest = - 1, - _currentDepthWrite = - 1, - - _currentPolygonOffset = null, - _currentPolygonOffsetFactor = null, - _currentPolygonOffsetUnits = null, - - _currentLineWidth = null, - _viewportX = 0, _viewportY = 0, _viewportWidth = _canvas.width, @@ -226,6 +208,8 @@ THREE.WebGLRenderer = function ( parameters ) { } + var state = new THREE.WebGLState( _gl, paramThreeToGL ); + if ( _gl.getShaderPrecisionFormat === undefined ) { _gl.getShaderPrecisionFormat = function () { @@ -296,9 +280,6 @@ THREE.WebGLRenderer = function ( parameters ) { _currentProgram = null; _currentCamera = null; - _currentBlending = - 1; - _currentDepthTest = - 1; - _currentDepthWrite = - 1; _currentDoubleSided = - 1; _currentFlipSided = - 1; _currentGeometryProgram = ''; @@ -312,11 +293,14 @@ THREE.WebGLRenderer = function ( parameters ) { } + state.reset(); + }; setDefaultGLState(); this.context = _gl; + this.state = state; // GPU capabilities @@ -2728,7 +2712,7 @@ THREE.WebGLRenderer = function ( parameters ) { var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - setLineWidth( material.linewidth ); + state.setLineWidth( material.linewidth ); var index = geometry.attributes.index; @@ -3022,7 +3006,8 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material.wireframe ) { - setLineWidth( material.wireframeLinewidth ); + state.setLineWidth( material.wireframeLinewidth ); + if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer ); _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, type, 0 ); @@ -3045,7 +3030,7 @@ THREE.WebGLRenderer = function ( parameters ) { var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - setLineWidth( material.linewidth ); + state.setLineWidth( material.linewidth ); _gl.drawArrays( mode, 0, geometryGroup.__webglLineCount ); @@ -3409,7 +3394,7 @@ THREE.WebGLRenderer = function ( parameters ) { var overrideMaterial = scene.overrideMaterial; // Reset blending in case material.transparent = false. setMaterial() doesn't set blending in such case. - this.setBlending( THREE.NoBlending ); + state.setBlending( THREE.NoBlending ); setMaterial( overrideMaterial ); renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial ); @@ -3420,7 +3405,7 @@ THREE.WebGLRenderer = function ( parameters ) { // opaque pass (front-to-back order) - this.setBlending( THREE.NoBlending ); + state.setBlending( THREE.NoBlending ); renderObjects( opaqueObjects, camera, lights, fog, null ); renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null ); @@ -3447,8 +3432,8 @@ THREE.WebGLRenderer = function ( parameters ) { // Ensure depth buffer writing is enabled so it can be cleared on next render - this.setDepthTest( true ); - this.setDepthWrite( true ); + state.setDepthTest( true ); + state.setDepthWrite( true ); // _gl.finish(); @@ -4352,13 +4337,13 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material.transparent === true ) { - _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); + state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); } - _this.setDepthTest( material.depthTest ); - _this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + state.setDepthTest( material.depthTest ); + state.setDepthWrite( material.depthWrite ); + state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); } @@ -5494,163 +5479,6 @@ THREE.WebGLRenderer = function ( parameters ) { }; - this.setDepthTest = function ( depthTest ) { - - if ( _currentDepthTest !== depthTest ) { - - if ( depthTest ) { - - _gl.enable( _gl.DEPTH_TEST ); - - } else { - - _gl.disable( _gl.DEPTH_TEST ); - - } - - _currentDepthTest = depthTest; - - } - - }; - - this.setDepthWrite = function ( depthWrite ) { - - if ( _currentDepthWrite !== depthWrite ) { - - _gl.depthMask( depthWrite ); - _currentDepthWrite = depthWrite; - - } - - }; - - function setLineWidth ( width ) { - - width *= pixelRatio; - - if ( width !== _currentLineWidth ) { - - _gl.lineWidth( width ); - - _currentLineWidth = width; - - } - - } - - function setPolygonOffset ( polygonoffset, factor, units ) { - - if ( _currentPolygonOffset !== polygonoffset ) { - - if ( polygonoffset ) { - - _gl.enable( _gl.POLYGON_OFFSET_FILL ); - - } else { - - _gl.disable( _gl.POLYGON_OFFSET_FILL ); - - } - - _currentPolygonOffset = polygonoffset; - - } - - if ( polygonoffset && ( _currentPolygonOffsetFactor !== factor || _currentPolygonOffsetUnits !== units ) ) { - - _gl.polygonOffset( factor, units ); - - _currentPolygonOffsetFactor = factor; - _currentPolygonOffsetUnits = units; - - } - - } - - this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { - - if ( blending !== _currentBlending ) { - - if ( blending === THREE.NoBlending ) { - - _gl.disable( _gl.BLEND ); - - } else if ( blending === THREE.AdditiveBlending ) { - - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE ); - - } else if ( blending === THREE.SubtractiveBlending ) { - - // TODO: Find blendFuncSeparate() combination - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR ); - - } else if ( blending === THREE.MultiplyBlending ) { - - // TODO: Find blendFuncSeparate() combination - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR ); - - } else if ( blending === THREE.CustomBlending ) { - - _gl.enable( _gl.BLEND ); - - } else { - - _gl.enable( _gl.BLEND ); - _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD ); - _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA ); - - } - - _currentBlending = blending; - - } - - if ( blending === THREE.CustomBlending ) { - - blendEquationAlpha = blendEquationAlpha || blendEquation; - blendSrcAlpha = blendSrcAlpha || blendSrc; - blendDstAlpha = blendDstAlpha || blendDst; - - if ( blendEquation !== _currentBlendEquation || blendEquationAlpha !== _currentBlendEquationAlpha ) { - - _gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) ); - - _currentBlendEquation = blendEquation; - _currentBlendEquationAlpha = blendEquationAlpha; - - } - - if ( blendSrc !== _currentBlendSrc || blendDst !== _currentBlendDst || blendSrcAlpha !== _currentBlendSrcAlpha || blendDstAlpha !== _currentBlendDstAlpha ) { - - _gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) ); - - _currentBlendSrc = blendSrc; - _currentBlendDst = blendDst; - _currentBlendSrcAlpha = blendSrcAlpha; - _currentBlendDstAlpha = blendDstAlpha; - - } - - } else { - - _currentBlendEquation = null; - _currentBlendSrc = null; - _currentBlendDst = null; - _currentBlendEquationAlpha = null; - _currentBlendSrcAlpha = null; - _currentBlendDstAlpha = null; - - } - - }; - // Textures function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) { diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js new file mode 100644 index 00000000000000..0fbac20b5f4621 --- /dev/null +++ b/src/renderers/webgl/WebGLState.js @@ -0,0 +1,188 @@ +/** +* @author mrdoob / http://mrdoob.com/ +*/ + +THREE.WebGLState = function ( gl, paramThreeToGL ) { + + var currentBlending = - 1; + var currentBlendEquation = - 1; + var currentBlendSrc = - 1; + var currentBlendDst = - 1; + var currentBlendEquationAlpha = - 1; + var currentBlendSrcAlpha = - 1; + var currentBlendDstAlpha = - 1; + + this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { + + if ( blending !== currentBlending ) { + + if ( blending === THREE.NoBlending ) { + + gl.disable( gl.BLEND ); + + } else if ( blending === THREE.AdditiveBlending ) { + + gl.enable( gl.BLEND ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.SRC_ALPHA, gl.ONE ); + + } else if ( blending === THREE.SubtractiveBlending ) { + + // TODO: Find blendFuncSeparate() combination + gl.enable( gl.BLEND ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR ); + + } else if ( blending === THREE.MultiplyBlending ) { + + // TODO: Find blendFuncSeparate() combination + gl.enable( gl.BLEND ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); + + } else if ( blending === THREE.CustomBlending ) { + + gl.enable( gl.BLEND ); + + } else { + + gl.enable( gl.BLEND ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + + } + + currentBlending = blending; + + } + + if ( blending === THREE.CustomBlending ) { + + blendEquationAlpha = blendEquationAlpha || blendEquation; + blendSrcAlpha = blendSrcAlpha || blendSrc; + blendDstAlpha = blendDstAlpha || blendDst; + + if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { + + gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) ); + + currentBlendEquation = blendEquation; + currentBlendEquationAlpha = blendEquationAlpha; + + } + + if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { + + gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) ); + + currentBlendSrc = blendSrc; + currentBlendDst = blendDst; + currentBlendSrcAlpha = blendSrcAlpha; + currentBlendDstAlpha = blendDstAlpha; + + } + + } else { + + currentBlendEquation = null; + currentBlendSrc = null; + currentBlendDst = null; + currentBlendEquationAlpha = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; + + } + + }; + + var currentDepthTest = - 1; + + this.setDepthTest = function ( depthTest ) { + + if ( currentDepthTest !== depthTest ) { + + if ( depthTest ) { + + gl.enable( gl.DEPTH_TEST ); + + } else { + + gl.disable( gl.DEPTH_TEST ); + + } + + currentDepthTest = depthTest; + + } + + }; + + var currentDepthWrite = - 1; + + this.setDepthWrite = function ( depthWrite ) { + + if ( currentDepthWrite !== depthWrite ) { + + gl.depthMask( depthWrite ); + currentDepthWrite = depthWrite; + + } + + }; + + var currentLineWidth = null; + + this.setLineWidth = function ( width ) { + + if ( width !== currentLineWidth ) { + + gl.lineWidth( width ); + + currentLineWidth = width; + + } + + }; + + var currentPolygonOffset = null; + var currentPolygonOffsetFactor = null; + var currentPolygonOffsetUnits = null; + + this.setPolygonOffset = function ( polygonoffset, factor, units ) { + + if ( currentPolygonOffset !== polygonoffset ) { + + if ( polygonoffset ) { + + gl.enable( gl.POLYGON_OFFSET_FILL ); + + } else { + + gl.disable( gl.POLYGON_OFFSET_FILL ); + + } + + currentPolygonOffset = polygonoffset; + + } + + if ( polygonoffset && ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) ) { + + gl.polygonOffset( factor, units ); + + currentPolygonOffsetFactor = factor; + currentPolygonOffsetUnits = units; + + } + + }; + + this.reset = function () { + + currentBlending = - 1; + currentDepthTest = - 1; + currentDepthWrite = - 1; + + }; + +}; diff --git a/src/renderers/webgl/plugins/LensFlarePlugin.js b/src/renderers/webgl/plugins/LensFlarePlugin.js index d1c3a7b593e224..3368fadcbf019d 100644 --- a/src/renderers/webgl/plugins/LensFlarePlugin.js +++ b/src/renderers/webgl/plugins/LensFlarePlugin.js @@ -321,7 +321,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { // calc object screen position var flare = flares[ i ]; - + tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] ); tempPosition.applyMatrix4( camera.matrixWorldInverse ); @@ -419,7 +419,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { gl.uniform1f( uniforms.opacity, sprite.opacity ); gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b ); - renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst ); + renderer.state.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst ); renderer.setTexture( sprite.texture, 1 ); gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); diff --git a/src/renderers/webgl/plugins/ShadowMapPlugin.js b/src/renderers/webgl/plugins/ShadowMapPlugin.js index ed7d7b88487a4d..88e18a92379e23 100644 --- a/src/renderers/webgl/plugins/ShadowMapPlugin.js +++ b/src/renderers/webgl/plugins/ShadowMapPlugin.js @@ -15,7 +15,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje _max = new THREE.Vector3(), _matrixPosition = new THREE.Vector3(), - + _renderList = []; // init @@ -89,7 +89,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje } - _renderer.setDepthTest( true ); + _renderer.state.setDepthTest( true ); // preprocess lights // - skip lights that are not casting shadows diff --git a/src/renderers/webgl/plugins/SpritePlugin.js b/src/renderers/webgl/plugins/SpritePlugin.js index 704c977559c88e..7212d1216279af 100644 --- a/src/renderers/webgl/plugins/SpritePlugin.js +++ b/src/renderers/webgl/plugins/SpritePlugin.js @@ -214,9 +214,9 @@ THREE.SpritePlugin = function ( renderer, sprites ) { gl.uniform1f( uniforms.rotation, material.rotation ); gl.uniform2fv( uniforms.scale, scale ); - renderer.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); - renderer.setDepthTest( material.depthTest ); - renderer.setDepthWrite( material.depthWrite ); + renderer.state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); + renderer.state.setDepthTest( material.depthTest ); + renderer.state.setDepthWrite( material.depthWrite ); if ( material.map && material.map.image && material.map.image.width ) { diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index a13220077d8465..5bbc980316ece5 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -146,6 +146,7 @@ "src/renderers/webgl/WebGLExtensions.js", "src/renderers/webgl/WebGLProgram.js", "src/renderers/webgl/WebGLShader.js", + "src/renderers/webgl/WebGLState.js", "src/renderers/webgl/plugins/LensFlarePlugin.js", "src/renderers/webgl/plugins/ShadowMapPlugin.js", "src/renderers/webgl/plugins/SpritePlugin.js" From 0eb402d3543feb756d2235eedd616948e1faec7d Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 19:00:04 -0800 Subject: [PATCH 181/333] WebGLRenderer: Moved doubleSided/flipSided code to WebGLState. --- src/renderers/WebGLRenderer.js | 43 +-------------------- src/renderers/webgl/WebGLState.js | 62 ++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 161bfce9593003..95887ac4d9fc47 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -118,11 +118,6 @@ THREE.WebGLRenderer = function ( parameters ) { _usedTextureUnits = 0, - // GL state cache - - _currentDoubleSided = - 1, - _currentFlipSided = - 1, - _viewportX = 0, _viewportY = 0, _viewportWidth = _canvas.width, @@ -280,8 +275,6 @@ THREE.WebGLRenderer = function ( parameters ) { _currentProgram = null; _currentCamera = null; - _currentDoubleSided = - 1; - _currentFlipSided = - 1; _currentGeometryProgram = ''; _currentMaterialId = - 1; @@ -5442,40 +5435,8 @@ THREE.WebGLRenderer = function ( parameters ) { this.setMaterialFaces = function ( material ) { - var doubleSided = material.side === THREE.DoubleSide; - var flipSided = material.side === THREE.BackSide; - - if ( _currentDoubleSided !== doubleSided ) { - - if ( doubleSided ) { - - _gl.disable( _gl.CULL_FACE ); - - } else { - - _gl.enable( _gl.CULL_FACE ); - - } - - _currentDoubleSided = doubleSided; - - } - - if ( _currentFlipSided !== flipSided ) { - - if ( flipSided ) { - - _gl.frontFace( _gl.CW ); - - } else { - - _gl.frontFace( _gl.CCW ); - - } - - _currentFlipSided = flipSided; - - } + state.setDoubleSided( material.side === THREE.DoubleSide ); + state.setFlipSided( material.side === THREE.BackSide ); }; diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index 0fbac20b5f4621..1d9c8c0f0218fd 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -12,6 +12,18 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { var currentBlendSrcAlpha = - 1; var currentBlendDstAlpha = - 1; + var currentDepthTest = - 1; + var currentDepthWrite = - 1; + + var currentDoubleSided = - 1; + var currentFlipSided = - 1; + + var currentLineWidth = null; + + var currentPolygonOffset = null; + var currentPolygonOffsetFactor = null; + var currentPolygonOffsetUnits = null; + this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { if ( blending !== currentBlending ) { @@ -95,8 +107,6 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { }; - var currentDepthTest = - 1; - this.setDepthTest = function ( depthTest ) { if ( currentDepthTest !== depthTest ) { @@ -117,8 +127,6 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { }; - var currentDepthWrite = - 1; - this.setDepthWrite = function ( depthWrite ) { if ( currentDepthWrite !== depthWrite ) { @@ -130,7 +138,45 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { }; - var currentLineWidth = null; + this.setDoubleSided = function ( doubleSided ) { + + if ( currentDoubleSided !== doubleSided ) { + + if ( doubleSided ) { + + gl.disable( gl.CULL_FACE ); + + } else { + + gl.enable( gl.CULL_FACE ); + + } + + currentDoubleSided = doubleSided; + + } + + }; + + this.setFlipSided = function ( flipSided ) { + + if ( currentFlipSided !== flipSided ) { + + if ( flipSided ) { + + gl.frontFace( gl.CW ); + + } else { + + gl.frontFace( gl.CCW ); + + } + + currentFlipSided = flipSided; + + } + + }; this.setLineWidth = function ( width ) { @@ -144,10 +190,6 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { }; - var currentPolygonOffset = null; - var currentPolygonOffsetFactor = null; - var currentPolygonOffsetUnits = null; - this.setPolygonOffset = function ( polygonoffset, factor, units ) { if ( currentPolygonOffset !== polygonoffset ) { @@ -182,6 +224,8 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { currentBlending = - 1; currentDepthTest = - 1; currentDepthWrite = - 1; + currentDoubleSided = - 1; + currentFlipSided = - 1; }; From 41a173c6609c99fa2259dccd9094d981b3484c7b Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 19:03:41 -0800 Subject: [PATCH 182/333] WebGLRenderer: setMaterial() does setBlending( THREE.NoBlending ) if needed. See #5940. --- src/renderers/WebGLRenderer.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 95887ac4d9fc47..4a55ee76f13766 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3386,8 +3386,6 @@ THREE.WebGLRenderer = function ( parameters ) { var overrideMaterial = scene.overrideMaterial; - // Reset blending in case material.transparent = false. setMaterial() doesn't set blending in such case. - state.setBlending( THREE.NoBlending ); setMaterial( overrideMaterial ); renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial ); @@ -4332,6 +4330,10 @@ THREE.WebGLRenderer = function ( parameters ) { state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); + } else { + + state.setBlending( THREE.NoBlending ); + } state.setDepthTest( material.depthTest ); From 3ab982bc4a089bc54a30181da693fb5eaac8a5bb Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 19:05:16 -0800 Subject: [PATCH 183/333] Updated builds. --- build/three.js | 549 ++++++++++++++++++++++++--------------------- build/three.min.js | 538 ++++++++++++++++++++++---------------------- 2 files changed, 558 insertions(+), 529 deletions(-) diff --git a/build/three.js b/build/three.js index 716938afd8c193..2f9302d05a96aa 100644 --- a/build/three.js +++ b/build/three.js @@ -17829,29 +17829,6 @@ THREE.WebGLRenderer = function ( parameters ) { _usedTextureUnits = 0, - // GL state cache - - _oldDoubleSided = - 1, - _oldFlipSided = - 1, - - _oldBlending = - 1, - - _oldBlendEquation = - 1, - _oldBlendSrc = - 1, - _oldBlendDst = - 1, - _oldBlendEquationAlpha = - 1, - _oldBlendSrcAlpha = - 1, - _oldBlendDstAlpha = - 1, - - _oldDepthTest = - 1, - _oldDepthWrite = - 1, - - _oldPolygonOffset = null, - _oldPolygonOffsetFactor = null, - _oldPolygonOffsetUnits = null, - - _oldLineWidth = null, - _viewportX = 0, _viewportY = 0, _viewportWidth = _canvas.width, @@ -17937,6 +17914,8 @@ THREE.WebGLRenderer = function ( parameters ) { } + var state = new THREE.WebGLState( _gl, paramThreeToGL ); + if ( _gl.getShaderPrecisionFormat === undefined ) { _gl.getShaderPrecisionFormat = function () { @@ -18007,11 +17986,6 @@ THREE.WebGLRenderer = function ( parameters ) { _currentProgram = null; _currentCamera = null; - _oldBlending = - 1; - _oldDepthTest = - 1; - _oldDepthWrite = - 1; - _oldDoubleSided = - 1; - _oldFlipSided = - 1; _currentGeometryProgram = ''; _currentMaterialId = - 1; @@ -18023,11 +17997,14 @@ THREE.WebGLRenderer = function ( parameters ) { } + state.reset(); + }; setDefaultGLState(); this.context = _gl; + this.state = state; // GPU capabilities @@ -20439,7 +20416,7 @@ THREE.WebGLRenderer = function ( parameters ) { var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - setLineWidth( material.linewidth ); + state.setLineWidth( material.linewidth ); var index = geometry.attributes.index; @@ -20733,7 +20710,8 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material.wireframe ) { - setLineWidth( material.wireframeLinewidth ); + state.setLineWidth( material.wireframeLinewidth ); + if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer ); _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, type, 0 ); @@ -20756,7 +20734,7 @@ THREE.WebGLRenderer = function ( parameters ) { var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - setLineWidth( material.linewidth ); + state.setLineWidth( material.linewidth ); _gl.drawArrays( mode, 0, geometryGroup.__webglLineCount ); @@ -21117,32 +21095,27 @@ THREE.WebGLRenderer = function ( parameters ) { if ( scene.overrideMaterial ) { - var material = scene.overrideMaterial; + var overrideMaterial = scene.overrideMaterial; - this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); - this.setDepthTest( material.depthTest ); - this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + setMaterial( overrideMaterial ); - renderObjects( opaqueObjects, camera, lights, fog, true, material ); - renderObjects( transparentObjects, camera, lights, fog, true, material ); - renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, false, material ); + renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial ); + renderObjects( transparentObjects, camera, lights, fog, overrideMaterial ); + renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, overrideMaterial ); } else { - var material = null; - // opaque pass (front-to-back order) - this.setBlending( THREE.NoBlending ); + state.setBlending( THREE.NoBlending ); - renderObjects( opaqueObjects, camera, lights, fog, false, material ); - renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, false, material ); + renderObjects( opaqueObjects, camera, lights, fog, null ); + renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null ); // transparent pass (back-to-front order) - renderObjects( transparentObjects, camera, lights, fog, true, material ); - renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, true, material ); + renderObjects( transparentObjects, camera, lights, fog, null ); + renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, null ); } @@ -21161,8 +21134,8 @@ THREE.WebGLRenderer = function ( parameters ) { // Ensure depth buffer writing is enabled so it can be cleared on next render - this.setDepthTest( true ); - this.setDepthWrite( true ); + state.setDepthTest( true ); + state.setDepthWrite( true ); // _gl.finish(); @@ -21231,7 +21204,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - function renderObjects( renderList, camera, lights, fog, useBlending, overrideMaterial ) { + function renderObjects( renderList, camera, lights, fog, overrideMaterial ) { var material; @@ -21254,11 +21227,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! material ) continue; - if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); - - _this.setDepthTest( material.depthTest ); - _this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + setMaterial( material ); } @@ -21278,7 +21247,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) { + function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, overrideMaterial ) { var material; @@ -21299,11 +21268,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! material ) continue; - if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); - - _this.setDepthTest( material.depthTest ); - _this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + setMaterial( material ); } @@ -22070,6 +22035,24 @@ THREE.WebGLRenderer = function ( parameters ) { } + function setMaterial( material ) { + + if ( material.transparent === true ) { + + state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); + + } else { + + state.setBlending( THREE.NoBlending ); + + } + + state.setDepthTest( material.depthTest ); + state.setDepthWrite( material.depthWrite ); + state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + + } + function setProgram( camera, lights, fog, material, object ) { _usedTextureUnits = 0; @@ -23165,197 +23148,8 @@ THREE.WebGLRenderer = function ( parameters ) { this.setMaterialFaces = function ( material ) { - var doubleSided = material.side === THREE.DoubleSide; - var flipSided = material.side === THREE.BackSide; - - if ( _oldDoubleSided !== doubleSided ) { - - if ( doubleSided ) { - - _gl.disable( _gl.CULL_FACE ); - - } else { - - _gl.enable( _gl.CULL_FACE ); - - } - - _oldDoubleSided = doubleSided; - - } - - if ( _oldFlipSided !== flipSided ) { - - if ( flipSided ) { - - _gl.frontFace( _gl.CW ); - - } else { - - _gl.frontFace( _gl.CCW ); - - } - - _oldFlipSided = flipSided; - - } - - }; - - this.setDepthTest = function ( depthTest ) { - - if ( _oldDepthTest !== depthTest ) { - - if ( depthTest ) { - - _gl.enable( _gl.DEPTH_TEST ); - - } else { - - _gl.disable( _gl.DEPTH_TEST ); - - } - - _oldDepthTest = depthTest; - - } - - }; - - this.setDepthWrite = function ( depthWrite ) { - - if ( _oldDepthWrite !== depthWrite ) { - - _gl.depthMask( depthWrite ); - _oldDepthWrite = depthWrite; - - } - - }; - - function setLineWidth ( width ) { - - width *= pixelRatio; - - if ( width !== _oldLineWidth ) { - - _gl.lineWidth( width ); - - _oldLineWidth = width; - - } - - } - - function setPolygonOffset ( polygonoffset, factor, units ) { - - if ( _oldPolygonOffset !== polygonoffset ) { - - if ( polygonoffset ) { - - _gl.enable( _gl.POLYGON_OFFSET_FILL ); - - } else { - - _gl.disable( _gl.POLYGON_OFFSET_FILL ); - - } - - _oldPolygonOffset = polygonoffset; - - } - - if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) { - - _gl.polygonOffset( factor, units ); - - _oldPolygonOffsetFactor = factor; - _oldPolygonOffsetUnits = units; - - } - - } - - this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { - - if ( blending !== _oldBlending ) { - - if ( blending === THREE.NoBlending ) { - - _gl.disable( _gl.BLEND ); - - } else if ( blending === THREE.AdditiveBlending ) { - - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE ); - - } else if ( blending === THREE.SubtractiveBlending ) { - - // TODO: Find blendFuncSeparate() combination - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR ); - - } else if ( blending === THREE.MultiplyBlending ) { - - // TODO: Find blendFuncSeparate() combination - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR ); - - } else if ( blending === THREE.CustomBlending ) { - - _gl.enable( _gl.BLEND ); - - } else { - - _gl.enable( _gl.BLEND ); - _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD ); - _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA ); - - } - - _oldBlending = blending; - - } - - if ( blending === THREE.CustomBlending ) { - - blendEquationAlpha = blendEquationAlpha || blendEquation; - blendSrcAlpha = blendSrcAlpha || blendSrc; - blendDstAlpha = blendDstAlpha || blendDst; - - if ( blendEquation !== _oldBlendEquation || blendEquationAlpha !== _oldBlendEquationAlpha ) { - - _gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) ); - - _oldBlendEquation = blendEquation; - _oldBlendEquationAlpha = blendEquationAlpha; - - } - - if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst || blendSrcAlpha !== _oldBlendSrcAlpha || blendDstAlpha !== _oldBlendDstAlpha ) { - - _gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) ); - - _oldBlendSrc = blendSrc; - _oldBlendDst = blendDst; - _oldBlendSrcAlpha = blendSrcAlpha; - _oldBlendDstAlpha = blendDstAlpha; - - } - - } else { - - _oldBlendEquation = null; - _oldBlendSrc = null; - _oldBlendDst = null; - _oldBlendEquationAlpha = null; - _oldBlendSrcAlpha = null; - _oldBlendDstAlpha = null; - - } + state.setDoubleSided( material.side === THREE.DoubleSide ); + state.setFlipSided( material.side === THREE.BackSide ); }; @@ -23399,10 +23193,10 @@ THREE.WebGLRenderer = function ( parameters ) { if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) { - if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) { + if ( texture.anisotropy > 1 || texture.__currentAnisotropy ) { _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) ); - texture.__oldAnisotropy = texture.anisotropy; + texture.__currentAnisotropy = texture.anisotropy; } @@ -24821,6 +24615,241 @@ THREE.WebGLShader = ( function () { } )(); +// File:src/renderers/webgl/WebGLState.js + +/** +* @author mrdoob / http://mrdoob.com/ +*/ + +THREE.WebGLState = function ( gl, paramThreeToGL ) { + + var currentBlending = - 1; + var currentBlendEquation = - 1; + var currentBlendSrc = - 1; + var currentBlendDst = - 1; + var currentBlendEquationAlpha = - 1; + var currentBlendSrcAlpha = - 1; + var currentBlendDstAlpha = - 1; + + var currentDepthTest = - 1; + var currentDepthWrite = - 1; + + var currentDoubleSided = - 1; + var currentFlipSided = - 1; + + var currentLineWidth = null; + + var currentPolygonOffset = null; + var currentPolygonOffsetFactor = null; + var currentPolygonOffsetUnits = null; + + this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { + + if ( blending !== currentBlending ) { + + if ( blending === THREE.NoBlending ) { + + gl.disable( gl.BLEND ); + + } else if ( blending === THREE.AdditiveBlending ) { + + gl.enable( gl.BLEND ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.SRC_ALPHA, gl.ONE ); + + } else if ( blending === THREE.SubtractiveBlending ) { + + // TODO: Find blendFuncSeparate() combination + gl.enable( gl.BLEND ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR ); + + } else if ( blending === THREE.MultiplyBlending ) { + + // TODO: Find blendFuncSeparate() combination + gl.enable( gl.BLEND ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); + + } else if ( blending === THREE.CustomBlending ) { + + gl.enable( gl.BLEND ); + + } else { + + gl.enable( gl.BLEND ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + + } + + currentBlending = blending; + + } + + if ( blending === THREE.CustomBlending ) { + + blendEquationAlpha = blendEquationAlpha || blendEquation; + blendSrcAlpha = blendSrcAlpha || blendSrc; + blendDstAlpha = blendDstAlpha || blendDst; + + if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { + + gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) ); + + currentBlendEquation = blendEquation; + currentBlendEquationAlpha = blendEquationAlpha; + + } + + if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { + + gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) ); + + currentBlendSrc = blendSrc; + currentBlendDst = blendDst; + currentBlendSrcAlpha = blendSrcAlpha; + currentBlendDstAlpha = blendDstAlpha; + + } + + } else { + + currentBlendEquation = null; + currentBlendSrc = null; + currentBlendDst = null; + currentBlendEquationAlpha = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; + + } + + }; + + this.setDepthTest = function ( depthTest ) { + + if ( currentDepthTest !== depthTest ) { + + if ( depthTest ) { + + gl.enable( gl.DEPTH_TEST ); + + } else { + + gl.disable( gl.DEPTH_TEST ); + + } + + currentDepthTest = depthTest; + + } + + }; + + this.setDepthWrite = function ( depthWrite ) { + + if ( currentDepthWrite !== depthWrite ) { + + gl.depthMask( depthWrite ); + currentDepthWrite = depthWrite; + + } + + }; + + this.setDoubleSided = function ( doubleSided ) { + + if ( currentDoubleSided !== doubleSided ) { + + if ( doubleSided ) { + + gl.disable( gl.CULL_FACE ); + + } else { + + gl.enable( gl.CULL_FACE ); + + } + + currentDoubleSided = doubleSided; + + } + + }; + + this.setFlipSided = function ( flipSided ) { + + if ( currentFlipSided !== flipSided ) { + + if ( flipSided ) { + + gl.frontFace( gl.CW ); + + } else { + + gl.frontFace( gl.CCW ); + + } + + currentFlipSided = flipSided; + + } + + }; + + this.setLineWidth = function ( width ) { + + if ( width !== currentLineWidth ) { + + gl.lineWidth( width ); + + currentLineWidth = width; + + } + + }; + + this.setPolygonOffset = function ( polygonoffset, factor, units ) { + + if ( currentPolygonOffset !== polygonoffset ) { + + if ( polygonoffset ) { + + gl.enable( gl.POLYGON_OFFSET_FILL ); + + } else { + + gl.disable( gl.POLYGON_OFFSET_FILL ); + + } + + currentPolygonOffset = polygonoffset; + + } + + if ( polygonoffset && ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) ) { + + gl.polygonOffset( factor, units ); + + currentPolygonOffsetFactor = factor; + currentPolygonOffsetUnits = units; + + } + + }; + + this.reset = function () { + + currentBlending = - 1; + currentDepthTest = - 1; + currentDepthWrite = - 1; + currentDoubleSided = - 1; + currentFlipSided = - 1; + + }; + +}; + // File:src/renderers/webgl/plugins/LensFlarePlugin.js /** @@ -25146,7 +25175,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { // calc object screen position var flare = flares[ i ]; - + tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] ); tempPosition.applyMatrix4( camera.matrixWorldInverse ); @@ -25244,7 +25273,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { gl.uniform1f( uniforms.opacity, sprite.opacity ); gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b ); - renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst ); + renderer.state.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst ); renderer.setTexture( sprite.texture, 1 ); gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); @@ -25312,7 +25341,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje _max = new THREE.Vector3(), _matrixPosition = new THREE.Vector3(), - + _renderList = []; // init @@ -25386,7 +25415,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje } - _renderer.setDepthTest( true ); + _renderer.state.setDepthTest( true ); // preprocess lights // - skip lights that are not casting shadows @@ -26036,9 +26065,9 @@ THREE.SpritePlugin = function ( renderer, sprites ) { gl.uniform1f( uniforms.rotation, material.rotation ); gl.uniform2fv( uniforms.scale, scale ); - renderer.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); - renderer.setDepthTest( material.depthTest ); - renderer.setDepthWrite( material.depthWrite ); + renderer.state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); + renderer.state.setDepthTest( material.depthTest ); + renderer.state.setDepthWrite( material.depthWrite ); if ( material.map && material.map.image && material.map.image.width ) { diff --git a/build/three.min.js b/build/three.min.js index bff367a19699f1..fab4f65ecc8811 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -94,21 +94,21 @@ a;b[1]*=a;b[4]*=a;b[7]*=a;b[2]*=a;b[5]*=a;b[8]*=a;return this},determinant:funct c=c[0]*d[0]+c[1]*d[3]+c[2]*d[6];if(0===c){if(b)throw Error("Matrix3.getInverse(): can't invert matrix, determinant is 0");THREE.warn("Matrix3.getInverse(): can't invert matrix, determinant is 0");this.identity();return this}this.multiplyScalar(1/c);return this},transpose:function(){var a,b=this.elements;a=b[1];b[1]=b[3];b[3]=a;a=b[2];b[2]=b[6];b[6]=a;a=b[5];b[5]=b[7];b[7]=a;return this},flattenToArrayOffset:function(a,b){var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4]; a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];return a},getNormalMatrix:function(a){this.getInverse(a).transpose();return this},transposeIntoArray:function(a){var b=this.elements;a[0]=b[0];a[1]=b[3];a[2]=b[6];a[3]=b[1];a[4]=b[4];a[5]=b[7];a[6]=b[2];a[7]=b[5];a[8]=b[8];return this},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]]},clone:function(){return(new THREE.Matrix3).fromArray(this.elements)}}; THREE.Matrix4=function(){this.elements=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);0d?c.copy(this.origin):c.copy(this.direction).multiplyScalar(d).add(this.origin)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceTo(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceTo(b)}}(),distanceSqToSegment:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5); -b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var h=.5*d.distanceTo(e),k=-this.direction.dot(b),p=c.dot(this.direction),n=-c.dot(b),q=c.lengthSq(),m=Math.abs(1-k*k),s;0=-s?e<=s?(h=1/m,d*=h,e*=h,k=d*(d+k*e+2*p)+e*(k*d+e+2*n)+q):(e=h,d=Math.max(0,-(k*e+p)),k=-d*d+e*(e+2*n)+q):(e=-h,d=Math.max(0,-(k*e+p)),k=-d*d+e*(e+2*n)+q):e<=-s?(d=Math.max(0,-(-k*h+p)),e=0=-s?e<=s?(h=1/l,d*=h,e*=h,k=d*(d+k*e+2*p)+e*(k*d+e+2*n)+q):(e=h,d=Math.max(0,-(k*e+p)),k=-d*d+e*(e+2*n)+q):(e=-h,d=Math.max(0,-(k*e+p)),k=-d*d+e*(e+2*n)+q):e<=-s?(d=Math.max(0,-(-k*h+p)),e=0f)return null;f=Math.sqrt(f-e);e=d-f;d+=f;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),isIntersectionPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0==b)return 0==a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){var c=this.distanceToPlane(a);return null===c?null:this.at(c,b)}, isIntersectionBox:function(){var a=new THREE.Vector3;return function(b){return null!==this.intersectBox(b,a)}}(),intersectBox:function(a,b){var c,d,e,f,g;d=1/this.direction.x;f=1/this.direction.y;g=1/this.direction.z;var h=this.origin;0<=d?(c=(a.min.x-h.x)*d,d*=a.max.x-h.x):(c=(a.max.x-h.x)*d,d*=a.min.x-h.x);0<=f?(e=(a.min.y-h.y)*f,f*=a.max.y-h.y):(e=(a.max.y-h.y)*f,f*=a.min.y-h.y);if(c>f||e>d)return null;if(e>c||c!==c)c=e;if(fthis.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=a||new THREE.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius); return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius},clone:function(){return(new THREE.Sphere).copy(this)}}; THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]}; -THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],p=c[7],n=c[8],q=c[9],m=c[10],s=c[11],t=c[12],r=c[13],u=c[14],c=c[15];b[0].setComponents(f-a,p-g,s-n,c-t).normalize();b[1].setComponents(f+ -a,p+g,s+n,c+t).normalize();b[2].setComponents(f+d,p+h,s+q,c+r).normalize();b[3].setComponents(f-d,p-h,s-q,c-r).normalize();b[4].setComponents(f-e,p-k,s-m,c-u).normalize();b[5].setComponents(f+e,p+k,s+m,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes, +THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],p=c[7],n=c[8],q=c[9],l=c[10],s=c[11],t=c[12],r=c[13],u=c[14],c=c[15];b[0].setComponents(f-a,p-g,s-n,c-t).normalize();b[1].setComponents(f+ +a,p+g,s+n,c+t).normalize();b[2].setComponents(f+d,p+h,s+q,c+r).normalize();b[3].setComponents(f-d,p-h,s-q,c-r).normalize();b[4].setComponents(f-e,p-k,s-l,c-u).normalize();b[5].setComponents(f+e,p+k,s+l,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes, c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)e;e++){var f=d[e];a.x=0g&&0>f)return!1}return!0}}(), containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d, @@ -140,9 +140,9 @@ a.constant==this.constant},clone:function(){return(new THREE.Plane).copy(this)}} THREE.Math={generateUUID:function(){var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d;return function(){for(var e=0;36>e;e++)8==e||13==e||18==e||23==e?b[e]="-":14==e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19==e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return a=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){return(65280*Math.random()+255*Math.random())/65535},randInt:function(a,b){return Math.floor(this.randFloat(a,b))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a= 180/Math.PI;return function(b){return b*a}}(),isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}}; -THREE.Spline=function(a){function b(a,b,c,d,e,f,g){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,f,g,h,k,p,n,q,m;this.initFromArray=function(a){this.points=[];for(var b=0;bthis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ -2;p=this.points[c[0]];n=this.points[c[1]];q=this.points[c[2]];m=this.points[c[3]];h=g*g;k=g*h;d.x=b(p.x,n.x,q.x,m.x,g,h,k);d.y=b(p.y,n.y,q.y,m.y,g,h,k);d.z=b(p.z,n.z,q.z,m.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;athis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ +2;p=this.points[c[0]];n=this.points[c[1]];q=this.points[c[2]];l=this.points[c[3]];h=g*g;k=g*h;d.x=b(p.x,n.x,q.x,l.x,g,h,k);d.y=b(p.y,n.y,q.y,l.y,g,h,k);d.z=b(p.z,n.z,q.z,l.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a=b.x+b.y}}(); @@ -186,19 +186,19 @@ THREE.Float64Attribute=function(a,b){THREE.warn("THREE.Float64Attribute has been THREE.DynamicBufferAttribute.prototype.clone=function(){return new THREE.DynamicBufferAttribute(new this.array.constructor(this.array),this.itemSize)};THREE.BufferGeometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="BufferGeometry";this.attributes={};this.attributesKeys=[];this.offsets=this.drawcalls=[];this.boundingSphere=this.boundingBox=null}; THREE.BufferGeometry.prototype={constructor:THREE.BufferGeometry,addAttribute:function(a,b,c){!1===b instanceof THREE.BufferAttribute?(THREE.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),this.attributes[a]={array:b,itemSize:c}):(this.attributes[a]=b,this.attributesKeys=Object.keys(this.attributes))},getAttribute:function(a){return this.attributes[a]},addDrawCall:function(a,b,c){this.drawcalls.push({start:a,count:b,index:void 0!==c?c:0})},applyMatrix:function(a){var b= this.attributes.position;void 0!==b&&(a.applyToVector3Array(b.array),b.needsUpdate=!0);b=this.attributes.normal;void 0!==b&&((new THREE.Matrix3).getNormalMatrix(a).applyToVector3Array(b.array),b.needsUpdate=!0)},center:function(){},fromGeometry:function(a,b){b=b||{vertexColors:THREE.NoColors};var c=a.vertices,d=a.faces,e=a.faceVertexUvs,f=b.vertexColors,g=0ja?-1:1;h[4*a]=ma.x;h[4*a+1]=ma.y;h[4*a+2]=ma.z;h[4*a+3]=ua}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],p=[],n=0;nr;r++)t=a[3*c+r],-1==m[t]?(q[2*r]=t,q[2*r+1]=-1,n++):m[t]k.index+b)for(k={start:f,count:0,index:g},h.push(k),n=0;6>n;n+=2)r=q[n+1],-1n;n+=2)t=q[n],r=q[n+1],-1===r&&(r=g++),m[t]=r,s[r]=t,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,s,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hna?-1:1;h[4*a]=ma.x;h[4*a+1]=ma.y;h[4*a+2]=ma.z;h[4*a+3]=Ka}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, +e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],p=[],n=0;nr;r++)t=a[3*c+r],-1==l[t]?(q[2*r]=t,q[2*r+1]=-1,n++):l[t]k.index+b)for(k={start:f,count:0,index:g},h.push(k),n=0;6>n;n+=2)r=q[n+1],-1n;n+=2)t=q[n],r=q[n+1],-1===r&&(r=g++),l[t]=r,s[r]=t,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,s,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cg;g++)m=x[k++],v=u[2*m],m=u[2*m+1],v=new THREE.Vector2(v,m),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]),r.normal.copy(s.normal));if(t)for(d=0;4>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++], -C[q++],C[q]),2!==d&&s.vertexNormals.push(t),0!==d&&r.vertexNormals.push(t);n&&(n=x[k++],n=w[n],s.color.setHex(n),r.color.setHex(n));if(b)for(d=0;4>d;d++)n=x[k++],n=w[n],2!==d&&s.vertexColors.push(new THREE.Color(n)),0!==d&&r.vertexColors.push(new THREE.Color(n));c.faces.push(s);c.faces.push(r)}else{s=new THREE.Face3;s.a=x[k++];s.b=x[k++];s.c=x[k++];h&&(h=x[k++],s.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)m=x[k++],v=u[2*m],m=u[2*m+1], -v=new THREE.Vector2(v,m),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]));if(t)for(d=0;3>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++],C[q++],C[q]),s.vertexNormals.push(t);n&&(n=x[k++],s.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=x[k++],s.vertexColors.push(new THREE.Color(w[n]));c.faces.push(s)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;dg;g++)l=x[k++],v=u[2*l],l=u[2*l+1],v=new THREE.Vector2(v,l),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]),r.normal.copy(s.normal));if(t)for(d=0;4>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++], +C[q++],C[q]),2!==d&&s.vertexNormals.push(t),0!==d&&r.vertexNormals.push(t);n&&(n=x[k++],n=w[n],s.color.setHex(n),r.color.setHex(n));if(b)for(d=0;4>d;d++)n=x[k++],n=w[n],2!==d&&s.vertexColors.push(new THREE.Color(n)),0!==d&&r.vertexColors.push(new THREE.Color(n));c.faces.push(s);c.faces.push(r)}else{s=new THREE.Face3;s.a=x[k++];s.b=x[k++];s.c=x[k++];h&&(h=x[k++],s.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)l=x[k++],v=u[2*l],l=u[2*l+1], +v=new THREE.Vector2(v,l),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]));if(t)for(d=0;3>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++],C[q++],C[q]),s.vertexNormals.push(t);n&&(n=x[k++],s.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=x[k++],s.vertexColors.push(new THREE.Color(w[n]));c.faces.push(s)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;df||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, -object:this}))}}else for(m=m.position.array,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld), +THREE.BufferGeometry){var l=g.attributes;if(void 0!==l.index){var s=l.index.array,l=l.position.array,t=g.offsets;0===t.length&&(t=[{start:0,count:s.length,index:0}]);for(var r=0;rf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, +object:this}))}}else for(l=l.position.array,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld), index:g,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(a){void 0===a&&(a=new THREE.Line(this.geometry,this.material,this.mode));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype); THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=n.position.array,t=k=0,w=r.length;k -g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,m,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(t=this.material instanceof THREE.MeshFaceMaterial,r=!0===t?this.material.materials:null,s=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,l,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=n.position.array,t=k=0,w=r.length;k +g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,l,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(t=this.material instanceof THREE.MeshFaceMaterial,r=!0===t?this.material.materials:null,s=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:C,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.type="Bone";this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(this.boneTextureHeight=this.boneTextureWidth=a=256h&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in q||(n={id:mc++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:m,numMorphNormals:p},q[k]=n,s.push(n)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=s;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gX;X++)pa=L[X],Ua[Ya]=pa.x,Ua[Ya+1]=pa.y,Ua[Ya+2]=pa.z,Ya+=3;else for(X=0;3>X;X++)Ua[Ya]=P.x,Ua[Ya+1]=P.y,Ua[Ya+2]=P.z,Ya+=3;l.bindBuffer(l.ARRAY_BUFFER,u.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,Ua,C)}if(xb&&Ib){y=0;for(z=Z.length;yX;X++)ma=S[X],Qa[qb]=ma.x,Qa[qb+1]=ma.y,qb+=2;0X;X++)cb=Q[X],rb[ua]=cb.x,rb[ua+1]=cb.y,ua+=2;0wa;wa++)kb[wa]=!B.autoScaleCubemaps||Vb||Jb?Jb?W.image[wa].image:W.image[wa]:L(W.image[wa],Gc);var Sb=kb[0],Tb=THREE.Math.isPowerOfTwo(Sb.width)&&THREE.Math.isPowerOfTwo(Sb.height),bb=S(W.format),wb=S(W.type);z(l.TEXTURE_CUBE_MAP,W,Tb);for(wa=0;6>wa;wa++)if(Vb)for(var lb,Ub=kb[wa].mipmaps,Eb=0,Wb=Ub.length;Eb=sc&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+sc);Nb+=1;return a}function A(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function F(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a){a*=P;a!==tc&&(l.lineWidth(a),tc=a)}function E(a,b,c){uc!==a&&(a?l.enable(l.POLYGON_OFFSET_FILL):l.disable(l.POLYGON_OFFSET_FILL),uc=a);!a||vc===b&&wc=== -c||(l.polygonOffset(b,c),vc=b,wc=c)}function z(a,b,c){c?(l.texParameteri(a,l.TEXTURE_WRAP_S,S(b.wrapS)),l.texParameteri(a,l.TEXTURE_WRAP_T,S(b.wrapT)),l.texParameteri(a,l.TEXTURE_MAG_FILTER,S(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,S(b.minFilter))):(l.texParameteri(a,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(a,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+ -b.sourceFile+" )"),l.texParameteri(a,l.TEXTURE_MAG_FILTER,K(b.magFilter)),l.texParameteri(a,l.TEXTURE_MIN_FILTER,K(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=aa.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a} -function J(a,b){l.bindRenderbuffer(l.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_COMPONENT16,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(l.renderbufferStorage(l.RENDERBUFFER,l.DEPTH_STENCIL,b.width,b.height),l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a)):l.renderbufferStorage(l.RENDERBUFFER,l.RGBA4,b.width,b.height)}function M(a){a instanceof -THREE.WebGLRenderTargetCube?(l.bindTexture(l.TEXTURE_CUBE_MAP,a.__webglTexture),l.generateMipmap(l.TEXTURE_CUBE_MAP),l.bindTexture(l.TEXTURE_CUBE_MAP,null)):(l.bindTexture(l.TEXTURE_2D,a.__webglTexture),l.generateMipmap(l.TEXTURE_2D),l.bindTexture(l.TEXTURE_2D,null))}function K(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?l.NEAREST:l.LINEAR}function S(a){var b;if(a===THREE.RepeatWrapping)return l.REPEAT;if(a===THREE.ClampToEdgeWrapping)return l.CLAMP_TO_EDGE; -if(a===THREE.MirroredRepeatWrapping)return l.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return l.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return l.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return l.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return l.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return l.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return l.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return l.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return l.UNSIGNED_SHORT_4_4_4_4; -if(a===THREE.UnsignedShort5551Type)return l.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return l.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return l.BYTE;if(a===THREE.ShortType)return l.SHORT;if(a===THREE.UnsignedShortType)return l.UNSIGNED_SHORT;if(a===THREE.IntType)return l.INT;if(a===THREE.UnsignedIntType)return l.UNSIGNED_INT;if(a===THREE.FloatType)return l.FLOAT;b=aa.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return l.ALPHA; -if(a===THREE.RGBFormat)return l.RGB;if(a===THREE.RGBAFormat)return l.RGBA;if(a===THREE.LuminanceFormat)return l.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return l.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return l.FUNC_ADD;if(a===THREE.SubtractEquation)return l.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return l.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return l.ZERO;if(a===THREE.OneFactor)return l.ONE;if(a===THREE.SrcColorFactor)return l.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return l.ONE_MINUS_SRC_COLOR; -if(a===THREE.SrcAlphaFactor)return l.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return l.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return l.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return l.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return l.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return l.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return l.SRC_ALPHA_SATURATE;b=aa.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT; -if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=aa.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; -if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=aa.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var O=void 0!==a.canvas?a.canvas:document.createElement("canvas"),N=void 0!==a.context?a.context:null,P=1,V=void 0!==a.precision?a.precision:"highp",I=void 0!==a.alpha?a.alpha:!1,ma=void 0!==a.depth?a.depth:!0,ca=void 0!==a.stencil? -a.stencil:!0,qa=void 0!==a.antialias?a.antialias:!1,Q=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,ua=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,pa=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ja=new THREE.Color(0),ta=0,xa=[],ya={},Ma=[],Ea=[],Ra=[],Da=[],pb=[];this.domElement=O;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput= -!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,cb=[],$b=null,yb=null,xb=-1,La="",Fb=null,Nb=0,zb=-1,Pb=-1,Qb=-1,Rb=-1,ac=-1,Sb=-1,Tb=-1,Ub=-1,gc=-1,hc=-1,ic=-1,uc=null,vc=null,wc=null,tc=null,mb=0,nb=0,Wa=O.width,eb=O.height,xc=0,yc=0, -ob=new Uint8Array(16),Qa=new Uint8Array(16),hb=new THREE.Frustum,ub=new THREE.Matrix4;new THREE.Matrix4;var Aa=new THREE.Vector3,la=new THREE.Vector3,Gb=!0,qc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},l;try{var zc={alpha:I,depth:ma,stencil:ca,antialias:qa, -premultipliedAlpha:Q,preserveDrawingBuffer:ua};l=N||O.getContext("webgl",zc)||O.getContext("experimental-webgl",zc);if(null===l){if(null!==O.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}O.addEventListener("webglcontextlost",function(a){a.preventDefault();Ac();Bc();ya={}},!1)}catch(Hc){THREE.error("THREE.WebGLRenderer: "+Hc)}void 0===l.getShaderPrecisionFormat&&(l.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1, -precision:1}});var aa=new THREE.WebGLExtensions(l);aa.get("OES_texture_float");aa.get("OES_texture_float_linear");aa.get("OES_texture_half_float");aa.get("OES_texture_half_float_linear");aa.get("OES_standard_derivatives");pa&&aa.get("EXT_frag_depth");var jc=function(a,b,c,d){!0===Q&&(a*=d,b*=d,c*=d);l.clearColor(a,b,c,d)},Bc=function(){l.clearColor(0,0,0,1);l.clearDepth(1);l.clearStencil(0);l.enable(l.DEPTH_TEST);l.depthFunc(l.LEQUAL);l.frontFace(l.CCW);l.cullFace(l.BACK);l.enable(l.CULL_FACE);l.enable(l.BLEND); -l.blendEquation(l.FUNC_ADD);l.blendFunc(l.SRC_ALPHA,l.ONE_MINUS_SRC_ALPHA);l.viewport(mb,nb,Wa,eb);jc(ja.r,ja.g,ja.b,ta)},Ac=function(){Fb=$b=null;Pb=zb=ic=hc=Qb=-1;La="";xb=-1;Gb=!0;for(var a=0;ab;b++)l.deleteFramebuffer(a.__webglFramebuffer[b]),l.deleteRenderbuffer(a.__webglRenderbuffer[b]);else l.deleteFramebuffer(a.__webglFramebuffer),l.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},pc=function(a){a=a.target;a.removeEventListener("dispose",pc);oc(a)},Dc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), -c=0,d=b.length;cm.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=m.length);m=0;for(s=q.length;md.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&& -n.push([0,0]);for(var m=0,r=d.numSupportedMorphTargets;mf;f++){a.__webglFramebuffer[f]= -l.createFramebuffer();a.__webglRenderbuffer[f]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=l.TEXTURE_CUBE_MAP_POSITIVE_X+f;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[f]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&l.generateMipmap(l.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: -l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),z(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?l.framebufferRenderbuffer(l.FRAMEBUFFER,l.DEPTH_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&l.framebufferRenderbuffer(l.FRAMEBUFFER, -l.DEPTH_STENCIL_ATTACHMENT,l.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&l.generateMipmap(l.TEXTURE_2D);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Wa,a=eb,d=mb,e=nb);b!==yb&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(d,e,c,a),yb=b);xc=c;yc=a};this.readRenderTargetPixels= -function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==yb&&(l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),g=!0);l.checkFramebufferStatus(l.FRAMEBUFFER)=== -l.FRAMEBUFFER_COMPLETE?l.readPixels(b,c,d,e,l.RGBA,l.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&l.bindFramebuffer(l.FRAMEBUFFER,yb)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; -this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +THREE.WebGLRenderer=function(a){function b(a){var b=a.geometry;a=a.material;var c=b.vertices.length;if(a.attributes){void 0===b.__webglCustomAttributesList&&(b.__webglCustomAttributesList=[]);for(var d in a.attributes){var e=a.attributes[d];if(!e.__webglInitialized||e.createUniqueBuffers){e.__webglInitialized=!0;var f=1;"v2"===e.type?f=2:"v3"===e.type?f=3:"v4"===e.type?f=4:"c"===e.type&&(f=3);e.size=f;e.array=new Float32Array(c*f);e.buffer=m.createBuffer();e.buffer.belongsToAttribute=d;e.needsUpdate= +!0}b.__webglCustomAttributesList.push(e)}}}function c(a,b){return a.material instanceof THREE.MeshFaceMaterial?a.material.materials[b.materialIndex]:a.material}function d(a,b,c,d){c=c.attributes;var e=b.attributes;b=b.attributesKeys;for(var h=0,k=b.length;hh&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in q||(n={id:Rb++,faces3:[],materialIndex:u,vertices:0,numMorphTargets:l,numMorphNormals:p},q[k]=n,s.push(n)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=s;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gX;X++)gb=K[X],Ta[Ya]=gb.x,Ta[Ya+1]=gb.y,Ta[Ya+2]=gb.z,Ya+=3;else for(X=0;3>X;X++)Ta[Ya]=J.x,Ta[Ya+1]=J.y,Ta[Ya+2]=J.z,Ya+=3;m.bindBuffer(m.ARRAY_BUFFER,u.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Ta,C)}if(yb&&Jb){y=0;for(z=Z.length;yX;X++)xa=U[X],Pa[tb]=xa.x,Pa[tb+1]=xa.y,tb+=2;0X;X++)qa=T[X],qb[Ka]=qa.x,qb[Ka+1]=qa.y,Ka+=2;0va;va++)mb[va]=!B.autoScaleCubemaps|| +Sb||Kb?Kb?W.image[va].image:W.image[va]:z(W.image[va],qc);var Yb=mb[0],Zb=THREE.Math.isPowerOfTwo(Yb.width)&&THREE.Math.isPowerOfTwo(Yb.height),bb=K(W.format),xb=K(W.type);F(m.TEXTURE_CUBE_MAP,W,Zb);for(va=0;6>va;va++)if(Sb)for(var nb,$b=mb[va].mipmaps,Fb=0,Tb=$b.length;Fb=fc&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+fc);Ob+=1;return a}function E(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)} +function H(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function F(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,K(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,K(b.wrapT)),m.texParameteri(a,m.TEXTURE_MAG_FILTER,K(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,K(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+ +b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,N(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,N(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=ca.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a} +function J(a,b){m.bindRenderbuffer(m.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_COMPONENT16,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_STENCIL,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a)):m.renderbufferStorage(m.RENDERBUFFER,m.RGBA4,b.width,b.height)}function M(a){a instanceof +THREE.WebGLRenderTargetCube?(m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture),m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function N(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function K(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE; +if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return m.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return m.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return m.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return m.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return m.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return m.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return m.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return m.UNSIGNED_SHORT_4_4_4_4; +if(a===THREE.UnsignedShort5551Type)return m.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return m.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return m.BYTE;if(a===THREE.ShortType)return m.SHORT;if(a===THREE.UnsignedShortType)return m.UNSIGNED_SHORT;if(a===THREE.IntType)return m.INT;if(a===THREE.UnsignedIntType)return m.UNSIGNED_INT;if(a===THREE.FloatType)return m.FLOAT;b=ca.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return m.ALPHA; +if(a===THREE.RGBFormat)return m.RGB;if(a===THREE.RGBAFormat)return m.RGBA;if(a===THREE.LuminanceFormat)return m.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return m.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return m.FUNC_ADD;if(a===THREE.SubtractEquation)return m.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return m.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return m.ZERO;if(a===THREE.OneFactor)return m.ONE;if(a===THREE.SrcColorFactor)return m.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return m.ONE_MINUS_SRC_COLOR; +if(a===THREE.SrcAlphaFactor)return m.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return m.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return m.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return m.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return m.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return m.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return m.SRC_ALPHA_SATURATE;b=ca.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT; +if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=ca.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; +if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=ca.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var T=void 0!==a.canvas?a.canvas:document.createElement("canvas"),O=void 0!==a.context?a.context:null,U=1,Q=void 0!==a.precision?a.precision:"highp",V=void 0!==a.alpha?a.alpha:!1,L=void 0!==a.depth?a.depth:!0,ma=void 0!==a.stencil? +a.stencil:!0,ba=void 0!==a.antialias?a.antialias:!1,ra=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,G=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,Ka=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,aa=new THREE.Color(0),na=0,wa=[],Ca={},za=[],Qa=[],La=[],gb=[],cb=[];this.domElement=T;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput= +!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,Va=[],tb=null,zb=null,yb=-1,Ja="",Gb=null,Ob=0,Ab=0,ob=0,Wa=T.width,eb=T.height,Yb=0,Zb=0,ib=new Uint8Array(16),Pa=new Uint8Array(16),jb=new THREE.Frustum,vb=new THREE.Matrix4;new THREE.Matrix4; +var xa=new THREE.Vector3,la=new THREE.Vector3,Hb=!0,ic={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},m;try{var $b={alpha:V,depth:L,stencil:ma,antialias:ba,premultipliedAlpha:ra,preserveDrawingBuffer:G};m=O||T.getContext("webgl",$b)||T.getContext("experimental-webgl", +$b);if(null===m){if(null!==T.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}T.addEventListener("webglcontextlost",function(a){a.preventDefault();kc();lc();Ca={}},!1)}catch(rc){THREE.error("THREE.WebGLRenderer: "+rc)}var qa=new THREE.WebGLState(m,K);void 0===m.getShaderPrecisionFormat&&(m.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var ca=new THREE.WebGLExtensions(m);ca.get("OES_texture_float"); +ca.get("OES_texture_float_linear");ca.get("OES_texture_half_float");ca.get("OES_texture_half_float_linear");ca.get("OES_standard_derivatives");Ka&&ca.get("EXT_frag_depth");var pb=function(a,b,c,d){!0===ra&&(a*=d,b*=d,c*=d);m.clearColor(a,b,c,d)},lc=function(){m.clearColor(0,0,0,1);m.clearDepth(1);m.clearStencil(0);m.enable(m.DEPTH_TEST);m.depthFunc(m.LEQUAL);m.frontFace(m.CCW);m.cullFace(m.BACK);m.enable(m.CULL_FACE);m.enable(m.BLEND);m.blendEquation(m.FUNC_ADD);m.blendFunc(m.SRC_ALPHA,m.ONE_MINUS_SRC_ALPHA); +m.viewport(Ab,ob,Wa,eb);pb(aa.r,aa.g,aa.b,na)},kc=function(){Gb=tb=null;Ja="";yb=-1;Hb=!0;for(var a=0;ab;b++)m.deleteFramebuffer(a.__webglFramebuffer[b]),m.deleteRenderbuffer(a.__webglRenderbuffer[b]);else m.deleteFramebuffer(a.__webglFramebuffer),m.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},hc=function(a){a=a.target;a.removeEventListener("dispose",hc);gc(a)},nc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), +c=0,d=b.length;cl.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=l.length);l=0;for(s=q.length;ld.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&& +n.push([0,0]);for(var l=0,r=d.numSupportedMorphTargets;lf;f++){a.__webglFramebuffer[f]=m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER, +m.COLOR_ATTACHMENT0,h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:m.createRenderbuffer(),m.bindTexture(m.TEXTURE_2D,a.__webglTexture),F(m.TEXTURE_2D,a,c),m.texImage2D(m.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=m.TEXTURE_2D,m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0, +d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&m.generateMipmap(m.TEXTURE_2D);b?m.bindTexture(m.TEXTURE_CUBE_MAP,null):m.bindTexture(m.TEXTURE_2D,null);m.bindRenderbuffer(m.RENDERBUFFER,null);m.bindFramebuffer(m.FRAMEBUFFER, +null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Wa,a=eb,d=Ab,e=ob);b!==zb&&(m.bindFramebuffer(m.FRAMEBUFFER,b),m.viewport(d,e,c,a),zb=b);Yb=c;Zb=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); +else{var g=!1;a.__webglFramebuffer!==zb&&(m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),g=!0);m.checkFramebufferStatus(m.FRAMEBUFFER)===m.FRAMEBUFFER_COMPLETE?m.readPixels(b,c,d,e,m.RGBA,m.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&m.bindFramebuffer(m.FRAMEBUFFER,zb)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}; +this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; a.shareDepthFrom=this.shareDepthFrom;return a},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube.prototype.constructor=THREE.WebGLRenderTargetCube; THREE.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c])return b[c];var d;switch(c){case "EXT_texture_filter_anisotropic":d=a.getExtension("EXT_texture_filter_anisotropic")||a.getExtension("MOZ_EXT_texture_filter_anisotropic")||a.getExtension("WEBKIT_EXT_texture_filter_anisotropic");break;case "WEBGL_compressed_texture_s3tc":d=a.getExtension("WEBGL_compressed_texture_s3tc")||a.getExtension("MOZ_WEBGL_compressed_texture_s3tc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc"); break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;default:d=a.getExtension(c)}null===d&&THREE.warn("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}; -THREE.WebGLProgram=function(){var a=0;return function(b,c,d,e){var f=b.context,g=d.defines,h=d.__webglShader.uniforms,k=d.attributes,p=d.__webglShader.vertexShader,n=d.__webglShader.fragmentShader,q=d.index0AttributeName;void 0===q&&!0===e.morphTargets&&(q="position");var m="SHADOWMAP_TYPE_BASIC";e.shadowMapType===THREE.PCFShadowMap?m="SHADOWMAP_TYPE_PCF":e.shadowMapType===THREE.PCFSoftShadowMap&&(m="SHADOWMAP_TYPE_PCF_SOFT");var s="ENVMAP_TYPE_CUBE",t="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY"; +THREE.WebGLProgram=function(){var a=0;return function(b,c,d,e){var f=b.context,g=d.defines,h=d.__webglShader.uniforms,k=d.attributes,p=d.__webglShader.vertexShader,n=d.__webglShader.fragmentShader,q=d.index0AttributeName;void 0===q&&!0===e.morphTargets&&(q="position");var l="SHADOWMAP_TYPE_BASIC";e.shadowMapType===THREE.PCFShadowMap?l="SHADOWMAP_TYPE_PCF":e.shadowMapType===THREE.PCFSoftShadowMap&&(l="SHADOWMAP_TYPE_PCF_SOFT");var s="ENVMAP_TYPE_CUBE",t="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY"; if(e.envMap){switch(d.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:s="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:s="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:s="ENVMAP_TYPE_SPHERE"}switch(d.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:t="ENVMAP_MODE_REFRACTION"}switch(d.combine){case THREE.MultiplyOperation:r="ENVMAP_BLENDING_MULTIPLY"; break;case THREE.MixOperation:r="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:r="ENVMAP_BLENDING_ADD"}}var u=0S;S++)L[S]=new THREE.Vector3,E[S]=new THREE.Vector3;L=z.shadowCascadeNearZ[K];z=z.shadowCascadeFarZ[K];E[0].set(-1,-1,L);E[1].set(1,-1,L);E[2].set(-1,1,L);E[3].set(1,1,L);E[4].set(-1,-1,z);E[5].set(1,-1,z);E[6].set(-1,1,z);E[7].set(1,1,z);M.originalCamera=u;E=new THREE.Gyroscope;E.position.copy(A.shadowCascadeOffset);E.add(M);E.add(M.target);u.add(E);A.shadowCascadeArray[G]=M}K=A;L=G;z=K.shadowCascadeArray[L];z.position.copy(K.position); -z.target.position.copy(K.target.position);z.lookAt(z.target);z.shadowCameraVisible=K.shadowCameraVisible;z.shadowDarkness=K.shadowDarkness;z.shadowBias=K.shadowCascadeBias[L];E=K.shadowCascadeNearZ[L];K=K.shadowCascadeFarZ[L];z=z.pointsFrustum;z[0].z=E;z[1].z=E;z[2].z=E;z[3].z=E;z[4].z=K;z[5].z=K;z[6].z=K;z[7].z=K;J[F]=M;F++}else J[F]=A,F++;v=0;for(y=J.length;v -K;K++)L=z[K],L.copy(E[K]),L.unproject(G),L.applyMatrix4(F.matrixWorldInverse),L.xs.x&&(s.x=L.x),L.ys.y&&(s.y=L.y),L.zs.z&&(s.z=L.z);F.left=m.x;F.right=s.x;F.top=s.y;F.bottom=m.y;F.updateProjectionMatrix()}F=A.shadowMap;E=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);t.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(t);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& -(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();E.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);E.multiply(G.projectionMatrix);E.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);n.setFromMatrix(q);a.setRenderTarget(F);a.clear();r.length=0;e(c,c,G);A=0;for(F=r.length;AT;T++)J[T]=new THREE.Vector3,F[T]=new THREE.Vector3;J=z.shadowCascadeNearZ[K];z=z.shadowCascadeFarZ[K];F[0].set(-1,-1,J);F[1].set(1,-1,J);F[2].set(-1,1,J);F[3].set(1,1,J);F[4].set(-1,-1,z);F[5].set(1,-1,z);F[6].set(-1,1,z);F[7].set(1,1,z);N.originalCamera=u;F=new THREE.Gyroscope;F.position.copy(A.shadowCascadeOffset);F.add(N);F.add(N.target);u.add(F);A.shadowCascadeArray[H]=N}K=A;J=H;z=K.shadowCascadeArray[J];z.position.copy(K.position); +z.target.position.copy(K.target.position);z.lookAt(z.target);z.shadowCameraVisible=K.shadowCameraVisible;z.shadowDarkness=K.shadowDarkness;z.shadowBias=K.shadowCascadeBias[J];F=K.shadowCascadeNearZ[J];K=K.shadowCascadeFarZ[J];z=z.pointsFrustum;z[0].z=F;z[1].z=F;z[2].z=F;z[3].z=F;z[4].z=K;z[5].z=K;z[6].z=K;z[7].z=K;M[E]=N;E++}else M[E]=A,E++;v=0;for(y=M.length;v +K;K++)J=z[K],J.copy(F[K]),J.unproject(H),J.applyMatrix4(E.matrixWorldInverse),J.xs.x&&(s.x=J.x),J.ys.y&&(s.y=J.y),J.zs.z&&(s.z=J.z);E.left=l.x;E.right=s.x;E.top=s.y;E.bottom=l.y;E.updateProjectionMatrix()}E=A.shadowMap;F=A.shadowMatrix;H=A.shadowCamera;H.position.setFromMatrixPosition(A.matrixWorld);t.setFromMatrixPosition(A.target.matrixWorld);H.lookAt(t);H.updateMatrixWorld();H.matrixWorldInverse.getInverse(H.matrixWorld);A.cameraHelper&& +(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();F.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);F.multiply(H.projectionMatrix);F.multiply(H.matrixWorldInverse);q.multiplyMatrices(H.projectionMatrix,H.matrixWorldInverse);n.setFromMatrix(q);a.setRenderTarget(E);a.clear();r.length=0;e(c,c,H);A=0;for(E=r.length;A 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); -w.compileShader(S);w.compileShader(O);w.attachShader(K,S);w.attachShader(K,O);w.linkProgram(K);F=K;v=w.getAttribLocation(F,"position");x=w.getAttribLocation(F,"uv");c=w.getUniformLocation(F,"uvOffset");d=w.getUniformLocation(F,"uvScale");e=w.getUniformLocation(F,"rotation");f=w.getUniformLocation(F,"scale");g=w.getUniformLocation(F,"color");h=w.getUniformLocation(F,"map");k=w.getUniformLocation(F,"opacity");p=w.getUniformLocation(F,"modelViewMatrix");n=w.getUniformLocation(F,"projectionMatrix");q= -w.getUniformLocation(F,"fogType");m=w.getUniformLocation(F,"fogDensity");s=w.getUniformLocation(F,"fogNear");t=w.getUniformLocation(F,"fogFar");r=w.getUniformLocation(F,"fogColor");u=w.getUniformLocation(F,"alphaTest");K=document.createElement("canvas");K.width=8;K.height=8;S=K.getContext("2d");S.fillStyle="white";S.fillRect(0,0,8,8);G=new THREE.Texture(K);G.needsUpdate=!0}w.useProgram(F);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, -y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(n,!1,M.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);S=K=0;(O=J.fog)?(w.uniform3f(r,O.color.r,O.color.g,O.color.b),O instanceof THREE.Fog?(w.uniform1f(s,O.near),w.uniform1f(t,O.far),w.uniform1i(q,1),S=K=1):O instanceof THREE.FogExp2&&(w.uniform1f(m,O.density),w.uniform1i(q,2),S=K=2)):(w.uniform1i(q,0),S=K=0);for(var O=0,N=b.length;O< -N;O++){var P=b[O];P._modelViewMatrix.multiplyMatrices(M.matrixWorldInverse,P.matrixWorld);P.z=-P._modelViewMatrix.elements[14]}b.sort(C);for(var V=[],O=0,N=b.length;Oq-1?0:q-1,s=q+1>e-1?e-1:q+1,t=0>n-1?0:n-1,r=n+1>d-1?d-1:n+1,u=[],v=[0,0,h[4*(q*d+n)]/255*b];u.push([-1,0,h[4*(q*d+t)]/255*b]);u.push([-1,-1,h[4*(m*d+t)]/255*b]);u.push([0,-1,h[4*(m*d+n)]/255*b]);u.push([1,-1,h[4*(m*d+r)]/255*b]);u.push([1,0,h[4*(q*d+r)]/255*b]);u.push([1,1,h[4*(s*d+r)]/255*b]);u.push([0,1,h[4*(s*d+n)]/255* -b]);u.push([-1,1,h[4*(s*d+t)]/255*b]);m=[];t=u.length;for(s=0;sq-1?0:q-1,s=q+1>e-1?e-1:q+1,t=0>n-1?0:n-1,r=n+1>d-1?d-1:n+1,u=[],v=[0,0,h[4*(q*d+n)]/255*b];u.push([-1,0,h[4*(q*d+t)]/255*b]);u.push([-1,-1,h[4*(l*d+t)]/255*b]);u.push([0,-1,h[4*(l*d+n)]/255*b]);u.push([1,-1,h[4*(l*d+r)]/255*b]);u.push([1,0,h[4*(q*d+r)]/255*b]);u.push([1,1,h[4*(s*d+r)]/255*b]);u.push([0,1,h[4*(s*d+n)]/255* +b]);u.push([-1,1,h[4*(s*d+t)]/255*b]);l=[];t=u.length;for(s=0;se)return null;var f=[],g=[],h=[],k,p,n;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=p;e<=k&&(k=0);p=k+1;e<=p&&(p=0);n=p+1;e<=n&&(n=0);var m;a:{var s=m=void 0,t=void 0,r=void 0, -u=void 0,v=void 0,x=void 0,C=void 0,w=void 0,s=a[g[k]].x,t=a[g[k]].y,r=a[g[p]].x,u=a[g[p]].y,v=a[g[n]].x,x=a[g[n]].y;if(1E-10>(r-s)*(x-t)-(u-t)*(v-s))m=!1;else{var y=void 0,A=void 0,F=void 0,G=void 0,E=void 0,z=void 0,L=void 0,J=void 0,M=void 0,K=void 0,M=J=L=w=C=void 0,y=v-r,A=x-u,F=s-v,G=t-x,E=r-s,z=u-t;for(m=0;me)return null;var f=[],g=[],h=[],k,p,n;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=p;e<=k&&(k=0);p=k+1;e<=p&&(p=0);n=p+1;e<=n&&(n=0);var l;a:{var s=l=void 0,t=void 0,r=void 0, +u=void 0,v=void 0,x=void 0,C=void 0,w=void 0,s=a[g[k]].x,t=a[g[k]].y,r=a[g[p]].x,u=a[g[p]].y,v=a[g[n]].x,x=a[g[n]].y;if(1E-10>(r-s)*(x-t)-(u-t)*(v-s))l=!1;else{var y=void 0,A=void 0,E=void 0,H=void 0,F=void 0,z=void 0,J=void 0,M=void 0,N=void 0,K=void 0,N=M=J=w=C=void 0,y=v-r,A=x-u,E=s-v,H=t-x,F=r-s,z=u-t;for(l=0;lMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; -THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cm&&(g=b[f],k=-k,h=b[e],m=-m),!(a.yh.y))if(a.y==g.y){if(a.x==g.x)return!0}else{e=m*(a.x-g.x)-k*(a.y-g.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<= +THREE.Path.prototype.getPoints=function(a,b){if(this.useSpacedPoints)return console.log("tata"),this.getSpacedPoints(a,b);a=a||12;var c=[],d,e,f,g,h,k,p,n,q,l,s,t,r;d=0;for(e=this.actions.length;dMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; +THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cl&&(g=b[f],k=-k,h=b[e],l=-l),!(a.yh.y))if(a.y==g.y){if(a.x==g.x)return!0}else{e=l*(a.x-g.x)-k*(a.y-g.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<= h.x))return!0}return d}var e=function(a){var b,c,d,e,f=[],g=new THREE.Path;b=0;for(c=a.length;bG||G>F)return[];k=n*p-k*q;if(0>k||k>F)return[]}else{if(0d?[]:k==d?f?[]:[g]:a<=d?[g,h]: +THREE.Shape.Utils={triangulateShape:function(a,b){function c(a,b,c){return a.x!=b.x?a.xH||H>E)return[];k=n*p-k*q;if(0>k||k>E)return[]}else{if(0d?[]:k==d?f?[]:[g]:a<=d?[g,h]: [g,n]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]); -if(!d)return!1;d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c -K){console.log("Infinite Loop! Holes left:"+n.length+", Probably Hole outside Shape!");break}for(q=z;qf&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c +K){console.log("Infinite Loop! Holes left:"+n.length+", Probably Hole outside Shape!");break}for(q=z;qh;h++)p=k[h].x+":"+k[h].y,p=n[p],void 0!==p&&(k[h]=p);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a* a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)}; THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()};THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve; @@ -698,11 +698,11 @@ THREE.Animation.prototype.play=function(a,b){this.currentTime=void 0!==a?a:0;thi THREE.Animation.prototype.reset=function(){for(var a=0,b=this.hierarchy.length;ad;d++){for(var e=this.keyTypes[d],f=this.data.hierarchy[a].keys[0],g=this.getNextKeyWith(e,a,1);g.timef.index;)f=g,g=this.getNextKeyWith(e,a,g.index+1);c.prevKey[e]=f;c.nextKey[e]=g}}}; THREE.Animation.prototype.resetBlendWeights=function(){for(var a=0,b=this.hierarchy.length;aa.length-2?q:q+1;c[3]=q>a.length-3?q:q+2;q=a[c[0]];s=a[c[1]];t=a[c[2]];r=a[c[3]];c=e*e;m=e*c;d[0]=f(q[0],s[0],t[0],r[0],e,c,m);d[1]=f(q[1],s[1],t[1],r[1],e,c,m);d[2]=f(q[2],s[2],t[2],r[2],e,c,m);return d},f=function(a,b,c,d,e,f,m){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*m+ -(-3*(b-c)-2*a-d)*f+a*e+b};return function(f){if(!1!==this.isPlaying&&(this.currentTime+=f*this.timeScale,0!==this.weight)){f=this.data.length;if(this.currentTime>f||0>this.currentTime)this.loop?(this.currentTime%=f,0>this.currentTime&&(this.currentTime+=f),this.reset()):this.stop();f=0;for(var h=this.hierarchy.length;fq;q++){var m=this.keyTypes[q],s=p.prevKey[m],t=p.nextKey[m];if(0this.timeScale&&s.time>=this.currentTime){s=this.data.hierarchy[f].keys[0];for(t=this.getNextKeyWith(m,f,1);t.times.index;)s=t,t=this.getNextKeyWith(m,f,t.index+1);p.prevKey[m]=s;p.nextKey[m]=t}var r=(this.currentTime-s.time)/(t.time-s.time),u=s[m],v=t[m];0>r&&(r=0);1a.length-2?q:q+1;c[3]=q>a.length-3?q:q+2;q=a[c[0]];s=a[c[1]];t=a[c[2]];r=a[c[3]];c=e*e;l=e*c;d[0]=f(q[0],s[0],t[0],r[0],e,c,l);d[1]=f(q[1],s[1],t[1],r[1],e,c,l);d[2]=f(q[2],s[2],t[2],r[2],e,c,l);return d},f=function(a,b,c,d,e,f,l){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*l+ +(-3*(b-c)-2*a-d)*f+a*e+b};return function(f){if(!1!==this.isPlaying&&(this.currentTime+=f*this.timeScale,0!==this.weight)){f=this.data.length;if(this.currentTime>f||0>this.currentTime)this.loop?(this.currentTime%=f,0>this.currentTime&&(this.currentTime+=f),this.reset()):this.stop();f=0;for(var h=this.hierarchy.length;fq;q++){var l=this.keyTypes[q],s=p.prevKey[l],t=p.nextKey[l];if(0this.timeScale&&s.time>=this.currentTime){s=this.data.hierarchy[f].keys[0];for(t=this.getNextKeyWith(l,f,1);t.times.index;)s=t,t=this.getNextKeyWith(l,f,t.index+1);p.prevKey[l]=s;p.nextKey[l]=t}var r=(this.currentTime-s.time)/(t.time-s.time),u=s[l],v=t[l];0>r&&(r=0);1=this.currentTime?f.interpolate(g,this.currentTime):f.inter THREE.KeyFrameAnimation.prototype.getPrevKeyWith=function(a,b,c){b=this.data.hierarchy[b].keys;for(c=0<=c?c:c+b.length;0<=c;c--)if(b[c].hasTarget(a))return b[c];return b[b.length-1]};THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);a=this.duration/this.frames;var b=Math.floor(this.currentTime/a);b!=this.currentFrame&&(this.mesh.morphTargetInfluences[this.lastFrame]=0,this.mesh.morphTargetInfluences[this.currentFrame]= 1,this.mesh.morphTargetInfluences[b]=0,this.lastFrame=this.currentFrame,this.currentFrame=b);this.mesh.morphTargetInfluences[b]=this.currentTime%a/a;this.mesh.morphTargetInfluences[this.lastFrame]=1-this.mesh.morphTargetInfluences[b]}}}; -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,r){var u,v=h.widthSegments,x=h.heightSegments,C=e/2,w=f/2,y=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",x=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",v=h.depthSegments;var A=v+1,F=x+1,G=e/v,E=f/x,z=new THREE.Vector3;z[u]=0=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(Q=a.length;0<=--Q;){c=Q;d=Q-1;0>d&&(d=a.length-1);for(var e=0,f=s+2*n,e=0;e=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(G=a.length;0<=--G;){c=G;d=G-1;0>d&&(d=a.length-1);for(var e=0,f=s+2*n,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;cc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5, -a.y));return a.clone()}THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,p=0,n=a.length;ps&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));p=0;for(n=this.vertices.length;pc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5, +a.y));return a.clone()}THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,p=0,n=a.length;ps&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));p=0;for(n=this.vertices.length;pt;t++){d[0]=s[g[t]];d[1]=s[g[(t+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1], +THREE.EdgesHelper=function(a,b){var c=void 0!==b?b:16777215,d=[0,0],e={},f=function(a,b){return a-b},g=["a","b","c"],h=new THREE.BufferGeometry,k;a.geometry instanceof THREE.BufferGeometry?(k=new THREE.Geometry,k.fromBufferGeometry(a.geometry)):k=a.geometry.clone();k.mergeVertices();k.computeFaceNormals();var p=k.vertices;k=k.faces;for(var n=0,q=0,l=k.length;qt;t++){d[0]=s[g[t]];d[1]=s[g[(t+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1], face1:q,face2:void 0},n++):e[r].face2=q}d=new Float32Array(6*n);f=0;for(r in e)if(g=e[r],void 0===g.face2||.9999>k[g.face1].normal.dot(k[g.face2].normal))n=p[g.vert1],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z,n=p[g.vert2],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype); THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper;THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=new THREE.Geometry;c=0;for(var e=this.object.geometry.faces.length;cr;r++){d[0]=t[g[r]];d[1]=t[g[(r+1)%3]];d.sort(f);var u=d.toString();void 0===e[u]&&(q[2*n]=d[0],q[2*n+1]=d[1],e[u]=!0,n++)}d=new Float32Array(6*n);m=0;for(s=n;mr;r++)n= -k[q[2*m+r]],g=6*m+3*r,d[g+0]=n.x,d[g+1]=n.y,d[g+2]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3))}else if(a.geometry instanceof THREE.BufferGeometry){if(void 0!==a.geometry.attributes.index){k=a.geometry.attributes.position.array;s=a.geometry.attributes.index.array;p=a.geometry.drawcalls;n=0;0===p.length&&(p=[{count:s.length,index:0,start:0}]);for(var q=new Uint32Array(2*s.length),t=0,v=p.length;tr;r++)d[0]= -g+s[m+r],d[1]=g+s[m+(r+1)%3],d.sort(f),u=d.toString(),void 0===e[u]&&(q[2*n]=d[0],q[2*n+1]=d[1],e[u]=!0,n++);d=new Float32Array(6*n);m=0;for(s=n;mr;r++)g=6*m+3*r,n=3*q[2*m+r],d[g+0]=k[n],d[g+1]=k[n+1],d[g+2]=k[n+2]}else for(k=a.geometry.attributes.position.array,n=k.length/3,q=n/3,d=new Float32Array(6*n),m=0,s=q;mr;r++)g=18*m+6*r,q=9*m+3*r,d[g+0]=k[q],d[g+1]=k[q+1],d[g+2]=k[q+2],n=9*m+(r+1)%3*3,d[g+3]=k[n],d[g+4]=k[n+1],d[g+5]=k[n+2];h.addAttribute("position",new THREE.BufferAttribute(d, +THREE.WireframeHelper=function(a,b){var c=void 0!==b?b:16777215,d=[0,0],e={},f=function(a,b){return a-b},g=["a","b","c"],h=new THREE.BufferGeometry;if(a.geometry instanceof THREE.Geometry){for(var k=a.geometry.vertices,p=a.geometry.faces,n=0,q=new Uint32Array(6*p.length),l=0,s=p.length;lr;r++){d[0]=t[g[r]];d[1]=t[g[(r+1)%3]];d.sort(f);var u=d.toString();void 0===e[u]&&(q[2*n]=d[0],q[2*n+1]=d[1],e[u]=!0,n++)}d=new Float32Array(6*n);l=0;for(s=n;lr;r++)n= +k[q[2*l+r]],g=6*l+3*r,d[g+0]=n.x,d[g+1]=n.y,d[g+2]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3))}else if(a.geometry instanceof THREE.BufferGeometry){if(void 0!==a.geometry.attributes.index){k=a.geometry.attributes.position.array;s=a.geometry.attributes.index.array;p=a.geometry.drawcalls;n=0;0===p.length&&(p=[{count:s.length,index:0,start:0}]);for(var q=new Uint32Array(2*s.length),t=0,v=p.length;tr;r++)d[0]= +g+s[l+r],d[1]=g+s[l+(r+1)%3],d.sort(f),u=d.toString(),void 0===e[u]&&(q[2*n]=d[0],q[2*n+1]=d[1],e[u]=!0,n++);d=new Float32Array(6*n);l=0;for(s=n;lr;r++)g=6*l+3*r,n=3*q[2*l+r],d[g+0]=k[n],d[g+1]=k[n+1],d[g+2]=k[n+2]}else for(k=a.geometry.attributes.position.array,n=k.length/3,q=n/3,d=new Float32Array(6*n),l=0,s=q;lr;r++)g=18*l+6*r,q=9*l+3*r,d[g+0]=k[q],d[g+1]=k[q+1],d[g+2]=k[q+2],n=9*l+(r+1)%3*3,d[g+3]=k[n],d[g+4]=k[n+1],d[g+5]=k[n+2];h.addAttribute("position",new THREE.BufferAttribute(d, 3))}THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.WireframeHelper.prototype=Object.create(THREE.Line.prototype);THREE.WireframeHelper.prototype.constructor=THREE.WireframeHelper;THREE.ImmediateRenderObject=function(){THREE.Object3D.call(this);this.render=function(a){}};THREE.ImmediateRenderObject.prototype=Object.create(THREE.Object3D.prototype);THREE.ImmediateRenderObject.prototype.constructor=THREE.ImmediateRenderObject; THREE.MorphBlendMesh=function(a,b){THREE.Mesh.call(this,a,b);this.animationsMap={};this.animationsList=[];var c=this.geometry.morphTargets.length;this.createAnimation("__default",0,c-1,c/1);this.setAnimationWeight("__default",1)};THREE.MorphBlendMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.MorphBlendMesh.prototype.constructor=THREE.MorphBlendMesh; THREE.MorphBlendMesh.prototype.createAnimation=function(a,b,c,d){b={startFrame:b,endFrame:c,length:c-b+1,fps:d,duration:(c-b)/d,lastFrame:0,currentFrame:0,active:!1,time:0,direction:1,weight:1,directionBackwards:!1,mirroredLoop:!1};this.animationsMap[a]=b;this.animationsList.push(b)}; From 154826d4e36de22e1dfede3d42b8fda9f6482c48 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 19:19:33 -0800 Subject: [PATCH 184/333] WebGLRenderer: Moved initAttributes/enableAttribute/disableUnusedAttributes to WebGLState. --- src/renderers/WebGLRenderer.js | 142 ++++++++++++++---------------- src/renderers/webgl/WebGLState.js | 47 ++++++++++ 2 files changed, 114 insertions(+), 75 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 4a55ee76f13766..a3ca313cd5dbc1 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -125,9 +125,6 @@ THREE.WebGLRenderer = function ( parameters ) { _currentWidth = 0, _currentHeight = 0, - _newAttributes = new Uint8Array( 16 ), - _enabledAttributes = new Uint8Array( 16 ), - // frustum _frustum = new THREE.Frustum(), @@ -280,12 +277,6 @@ THREE.WebGLRenderer = function ( parameters ) { _lightsNeedUpdate = true; - for ( var i = 0; i < _enabledAttributes.length; i ++ ) { - - _enabledAttributes[ i ] = 0; - - } - state.reset(); }; @@ -2330,7 +2321,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.renderBufferImmediate = function ( object, program, material ) { - initAttributes(); + state.initAttributes(); if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer(); if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer(); @@ -2341,7 +2332,9 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer ); _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.position ); + + state.enableAttribute( program.attributes.position ); + _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } @@ -2394,7 +2387,9 @@ THREE.WebGLRenderer = function ( parameters ) { } _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.normal ); + + state.enableAttribute( program.attributes.normal ); + _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); } @@ -2403,7 +2398,9 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer ); _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.uv ); + + state.enableAttribute( program.attributes.uv ); + _gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 ); } @@ -2412,12 +2409,14 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer ); _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.color ); + + state.enableAttribute( program.attributes.color ); + _gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 ); } - disableUnusedAttributes(); + state.disableUnusedAttributes(); _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); @@ -2447,7 +2446,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryAttribute.buffer ); - enableAttribute( programAttribute ); + state.enableAttribute( programAttribute ); _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, 0, startIndex * size * 4 ); // 4 bytes per Float32 @@ -2469,7 +2468,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - disableUnusedAttributes(); + state.disableUnusedAttributes(); } @@ -2494,7 +2493,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( updateBuffers ) { - initAttributes(); + state.initAttributes(); } @@ -2835,7 +2834,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( updateBuffers ) { - initAttributes(); + state.initAttributes(); } @@ -2846,7 +2845,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( updateBuffers ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer ); - enableAttribute( attributes.position ); + + state.enableAttribute( attributes.position ); + _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } @@ -2877,7 +2878,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer ); - enableAttribute( attributes[ attribute.buffer.belongsToAttribute ] ); + + state.enableAttribute( attributes[ attribute.buffer.belongsToAttribute ] ); + _gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 ); } @@ -2894,7 +2897,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( object.geometry.colors.length > 0 || object.geometry.faces.length > 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer ); - enableAttribute( attributes.color ); + + state.enableAttribute( attributes.color ); + _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 ); } else if ( material.defaultAttributeValues !== undefined ) { @@ -2911,7 +2916,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attributes.normal >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer ); - enableAttribute( attributes.normal ); + + state.enableAttribute( attributes.normal ); + _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); } @@ -2921,7 +2928,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attributes.tangent >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer ); - enableAttribute( attributes.tangent ); + + state.enableAttribute( attributes.tangent ); + _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 ); } @@ -2933,7 +2942,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( object.geometry.faceVertexUvs[ 0 ] ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer ); - enableAttribute( attributes.uv ); + + state.enableAttribute( attributes.uv ); + _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 ); } else if ( material.defaultAttributeValues !== undefined ) { @@ -2950,7 +2961,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( object.geometry.faceVertexUvs[ 1 ] ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer ); - enableAttribute( attributes.uv2 ); + + state.enableAttribute( attributes.uv2 ); + _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 ); } else if ( material.defaultAttributeValues !== undefined ) { @@ -2966,11 +2979,15 @@ THREE.WebGLRenderer = function ( parameters ) { attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer ); - enableAttribute( attributes.skinIndex ); + + state.enableAttribute( attributes.skinIndex ); + _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 ); _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer ); - enableAttribute( attributes.skinWeight ); + + state.enableAttribute( attributes.skinWeight ); + _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 ); } @@ -2980,14 +2997,16 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attributes.lineDistance >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglLineDistanceBuffer ); - enableAttribute( attributes.lineDistance ); + + state.enableAttribute( attributes.lineDistance ); + _gl.vertexAttribPointer( attributes.lineDistance, 1, _gl.FLOAT, false, 0, 0 ); } } - disableUnusedAttributes(); + state.disableUnusedAttributes(); // render mesh @@ -3042,44 +3061,6 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function initAttributes() { - - for ( var i = 0, l = _newAttributes.length; i < l; i ++ ) { - - _newAttributes[ i ] = 0; - - } - - } - - function enableAttribute( attribute ) { - - _newAttributes[ attribute ] = 1; - - if ( _enabledAttributes[ attribute ] === 0 ) { - - _gl.enableVertexAttribArray( attribute ); - _enabledAttributes[ attribute ] = 1; - - } - - } - - function disableUnusedAttributes() { - - for ( var i = 0, l = _enabledAttributes.length; i < l; i ++ ) { - - if ( _enabledAttributes[ i ] !== _newAttributes[ i ] ) { - - _gl.disableVertexAttribArray( i ); - _enabledAttributes[ i ] = 0; - - } - - } - - } - function setupMorphTargets ( material, geometryGroup, object ) { // set base @@ -3089,13 +3070,17 @@ THREE.WebGLRenderer = function ( parameters ) { if ( object.morphTargetBase !== - 1 && attributes.position >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] ); - enableAttribute( attributes.position ); + + state.enableAttribute( attributes.position ); + _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } else if ( attributes.position >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer ); - enableAttribute( attributes.position ); + + state.enableAttribute( attributes.position ); + _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } @@ -3117,7 +3102,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] ); - enableAttribute( attribute ); + + state.enableAttribute( attribute ); + _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); } @@ -3127,7 +3114,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute >= 0 && material.morphNormals ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] ); - enableAttribute( attribute ); + + state.enableAttribute( attribute ); + _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); } @@ -3189,7 +3178,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] ); - enableAttribute( attribute ); + + state.enableAttribute( attribute ); + _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); } @@ -3199,9 +3190,10 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute >= 0 && material.morphNormals ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] ); - enableAttribute( attribute ); - _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); + state.enableAttribute( attribute ); + + _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); } diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index 1d9c8c0f0218fd..53f409bb01da19 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -4,6 +4,9 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { + var newAttributes = new Uint8Array( 16 ); + var enabledAttributes = new Uint8Array( 16 ); + var currentBlending = - 1; var currentBlendEquation = - 1; var currentBlendSrc = - 1; @@ -24,6 +27,44 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { var currentPolygonOffsetFactor = null; var currentPolygonOffsetUnits = null; + this.initAttributes = function () { + + for ( var i = 0, l = newAttributes.length; i < l; i ++ ) { + + newAttributes[ i ] = 0; + + } + + }; + + this.enableAttribute = function ( attribute ) { + + newAttributes[ attribute ] = 1; + + if ( enabledAttributes[ attribute ] === 0 ) { + + gl.enableVertexAttribArray( attribute ); + enabledAttributes[ attribute ] = 1; + + } + + }; + + this.disableUnusedAttributes = function () { + + for ( var i = 0, l = enabledAttributes.length; i < l; i ++ ) { + + if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { + + gl.disableVertexAttribArray( i ); + enabledAttributes[ i ] = 0; + + } + + } + + }; + this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { if ( blending !== currentBlending ) { @@ -221,6 +262,12 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { this.reset = function () { + for ( var i = 0; i < enabledAttributes.length; i ++ ) { + + enabledAttributes[ i ] = 0; + + } + currentBlending = - 1; currentDepthTest = - 1; currentDepthWrite = - 1; From d91e4181ffda147020f074abde358c8cd2d23e2d Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 19:19:43 -0800 Subject: [PATCH 185/333] Updated builds. --- build/three.js | 189 +++++++------ build/three.min.js | 655 +++++++++++++++++++++++---------------------- 2 files changed, 442 insertions(+), 402 deletions(-) diff --git a/build/three.js b/build/three.js index 2f9302d05a96aa..95c81887d1af5c 100644 --- a/build/three.js +++ b/build/three.js @@ -17836,9 +17836,6 @@ THREE.WebGLRenderer = function ( parameters ) { _currentWidth = 0, _currentHeight = 0, - _newAttributes = new Uint8Array( 16 ), - _enabledAttributes = new Uint8Array( 16 ), - // frustum _frustum = new THREE.Frustum(), @@ -17991,12 +17988,6 @@ THREE.WebGLRenderer = function ( parameters ) { _lightsNeedUpdate = true; - for ( var i = 0; i < _enabledAttributes.length; i ++ ) { - - _enabledAttributes[ i ] = 0; - - } - state.reset(); }; @@ -20041,7 +20032,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.renderBufferImmediate = function ( object, program, material ) { - initAttributes(); + state.initAttributes(); if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer(); if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer(); @@ -20052,7 +20043,9 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer ); _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.position ); + + state.enableAttribute( program.attributes.position ); + _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } @@ -20105,7 +20098,9 @@ THREE.WebGLRenderer = function ( parameters ) { } _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.normal ); + + state.enableAttribute( program.attributes.normal ); + _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); } @@ -20114,7 +20109,9 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer ); _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.uv ); + + state.enableAttribute( program.attributes.uv ); + _gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 ); } @@ -20123,12 +20120,14 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer ); _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.color ); + + state.enableAttribute( program.attributes.color ); + _gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 ); } - disableUnusedAttributes(); + state.disableUnusedAttributes(); _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); @@ -20158,7 +20157,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryAttribute.buffer ); - enableAttribute( programAttribute ); + state.enableAttribute( programAttribute ); _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, 0, startIndex * size * 4 ); // 4 bytes per Float32 @@ -20180,7 +20179,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - disableUnusedAttributes(); + state.disableUnusedAttributes(); } @@ -20205,7 +20204,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( updateBuffers ) { - initAttributes(); + state.initAttributes(); } @@ -20546,7 +20545,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( updateBuffers ) { - initAttributes(); + state.initAttributes(); } @@ -20557,7 +20556,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( updateBuffers ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer ); - enableAttribute( attributes.position ); + + state.enableAttribute( attributes.position ); + _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } @@ -20588,7 +20589,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer ); - enableAttribute( attributes[ attribute.buffer.belongsToAttribute ] ); + + state.enableAttribute( attributes[ attribute.buffer.belongsToAttribute ] ); + _gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 ); } @@ -20605,7 +20608,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( object.geometry.colors.length > 0 || object.geometry.faces.length > 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer ); - enableAttribute( attributes.color ); + + state.enableAttribute( attributes.color ); + _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 ); } else if ( material.defaultAttributeValues !== undefined ) { @@ -20622,7 +20627,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attributes.normal >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer ); - enableAttribute( attributes.normal ); + + state.enableAttribute( attributes.normal ); + _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); } @@ -20632,7 +20639,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attributes.tangent >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer ); - enableAttribute( attributes.tangent ); + + state.enableAttribute( attributes.tangent ); + _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 ); } @@ -20644,7 +20653,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( object.geometry.faceVertexUvs[ 0 ] ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer ); - enableAttribute( attributes.uv ); + + state.enableAttribute( attributes.uv ); + _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 ); } else if ( material.defaultAttributeValues !== undefined ) { @@ -20661,7 +20672,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( object.geometry.faceVertexUvs[ 1 ] ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer ); - enableAttribute( attributes.uv2 ); + + state.enableAttribute( attributes.uv2 ); + _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 ); } else if ( material.defaultAttributeValues !== undefined ) { @@ -20677,11 +20690,15 @@ THREE.WebGLRenderer = function ( parameters ) { attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer ); - enableAttribute( attributes.skinIndex ); + + state.enableAttribute( attributes.skinIndex ); + _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 ); _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer ); - enableAttribute( attributes.skinWeight ); + + state.enableAttribute( attributes.skinWeight ); + _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 ); } @@ -20691,14 +20708,16 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attributes.lineDistance >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglLineDistanceBuffer ); - enableAttribute( attributes.lineDistance ); + + state.enableAttribute( attributes.lineDistance ); + _gl.vertexAttribPointer( attributes.lineDistance, 1, _gl.FLOAT, false, 0, 0 ); } } - disableUnusedAttributes(); + state.disableUnusedAttributes(); // render mesh @@ -20753,44 +20772,6 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function initAttributes() { - - for ( var i = 0, l = _newAttributes.length; i < l; i ++ ) { - - _newAttributes[ i ] = 0; - - } - - } - - function enableAttribute( attribute ) { - - _newAttributes[ attribute ] = 1; - - if ( _enabledAttributes[ attribute ] === 0 ) { - - _gl.enableVertexAttribArray( attribute ); - _enabledAttributes[ attribute ] = 1; - - } - - } - - function disableUnusedAttributes() { - - for ( var i = 0, l = _enabledAttributes.length; i < l; i ++ ) { - - if ( _enabledAttributes[ i ] !== _newAttributes[ i ] ) { - - _gl.disableVertexAttribArray( i ); - _enabledAttributes[ i ] = 0; - - } - - } - - } - function setupMorphTargets ( material, geometryGroup, object ) { // set base @@ -20800,13 +20781,17 @@ THREE.WebGLRenderer = function ( parameters ) { if ( object.morphTargetBase !== - 1 && attributes.position >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] ); - enableAttribute( attributes.position ); + + state.enableAttribute( attributes.position ); + _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } else if ( attributes.position >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer ); - enableAttribute( attributes.position ); + + state.enableAttribute( attributes.position ); + _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } @@ -20828,7 +20813,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] ); - enableAttribute( attribute ); + + state.enableAttribute( attribute ); + _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); } @@ -20838,7 +20825,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute >= 0 && material.morphNormals ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] ); - enableAttribute( attribute ); + + state.enableAttribute( attribute ); + _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); } @@ -20900,7 +20889,9 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute >= 0 ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] ); - enableAttribute( attribute ); + + state.enableAttribute( attribute ); + _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); } @@ -20910,9 +20901,10 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute >= 0 && material.morphNormals ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] ); - enableAttribute( attribute ); - _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); + state.enableAttribute( attribute ); + + _gl.vertexAttribPointer( attribute, 3, _gl.FLOAT, false, 0, 0 ); } @@ -24623,6 +24615,9 @@ THREE.WebGLShader = ( function () { THREE.WebGLState = function ( gl, paramThreeToGL ) { + var newAttributes = new Uint8Array( 16 ); + var enabledAttributes = new Uint8Array( 16 ); + var currentBlending = - 1; var currentBlendEquation = - 1; var currentBlendSrc = - 1; @@ -24643,6 +24638,44 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { var currentPolygonOffsetFactor = null; var currentPolygonOffsetUnits = null; + this.initAttributes = function () { + + for ( var i = 0, l = newAttributes.length; i < l; i ++ ) { + + newAttributes[ i ] = 0; + + } + + }; + + this.enableAttribute = function ( attribute ) { + + newAttributes[ attribute ] = 1; + + if ( enabledAttributes[ attribute ] === 0 ) { + + gl.enableVertexAttribArray( attribute ); + enabledAttributes[ attribute ] = 1; + + } + + }; + + this.disableUnusedAttributes = function () { + + for ( var i = 0, l = enabledAttributes.length; i < l; i ++ ) { + + if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { + + gl.disableVertexAttribArray( i ); + enabledAttributes[ i ] = 0; + + } + + } + + }; + this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { if ( blending !== currentBlending ) { @@ -24840,6 +24873,12 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { this.reset = function () { + for ( var i = 0; i < enabledAttributes.length; i ++ ) { + + enabledAttributes[ i ] = 0; + + } + currentBlending = - 1; currentDepthTest = - 1; currentDepthWrite = - 1; diff --git a/build/three.min.js b/build/three.min.js index fab4f65ecc8811..82beae00acff75 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -23,10 +23,10 @@ tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215, THREE.Quaternion.prototype={constructor:THREE.Quaternion,_x:0,_y:0,_z:0,_w:0,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get w(){return this._w},set w(a){this._w=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this.onChangeCallback();return this},copy:function(a){this._x=a.x;this._y=a.y;this._z=a.z; this._w=a.w;this.onChangeCallback();return this},setFromEuler:function(a,b){if(!1===a instanceof THREE.Euler)throw Error("THREE.Quaternion: .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var c=Math.cos(a._x/2),d=Math.cos(a._y/2),e=Math.cos(a._z/2),f=Math.sin(a._x/2),g=Math.sin(a._y/2),h=Math.sin(a._z/2);"XYZ"===a.order?(this._x=f*d*e+c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e-f*g*h):"YXZ"===a.order?(this._x=f*d*e+c*g*h,this._y=c*g*e-f*d*h,this._z= c*d*h-f*g*e,this._w=c*d*e+f*g*h):"ZXY"===a.order?(this._x=f*d*e-c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e-f*g*h):"ZYX"===a.order?(this._x=f*d*e-c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e+f*g*h):"YZX"===a.order?(this._x=f*d*e+c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e-f*g*h):"XZY"===a.order&&(this._x=f*d*e-c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e+f*g*h);if(!1!==b)this.onChangeCallback();return this},setFromAxisAngle:function(a, -b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w=Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],p=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y= +b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w=Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],l=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y= .25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+k)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):a.crossVectors(c,d);this._x=a.x;this._y=a.y;this._z=a.z;this._w=b;this.normalize();return this}}(),inverse:function(){this.conjugate().normalize();return this},conjugate:function(){this._x*= -1;this._y*=-1;this._z*=-1;this.onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this.onChangeCallback();return this}, -multiply:function(a,b){return void 0!==b?(THREE.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,p=b._w;this._x=c*p+f*g+d*k-e*h;this._y=d*p+f*h+e*g-c*k;this._z=e*p+f*k+c*h-d*g;this._w=f*p-c*g-d*h-e*k;this.onChangeCallback();return this},multiplyVector3:function(a){THREE.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead."); +multiply:function(a,b){return void 0!==b?(THREE.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,l=b._w;this._x=c*l+f*g+d*k-e*h;this._y=d*l+f*h+e*g-c*k;this._z=e*l+f*k+c*h-d*g;this._w=f*l-c*g-d*h-e*k;this.onChangeCallback();return this},multiplyVector3:function(a){THREE.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead."); return a.applyQuaternion(this)},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;var h=Math.acos(g),k=Math.sqrt(1-g*g);if(.001>Math.abs(k))return this._w=.5*(f+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;g=Math.sin((1-b)*h)/k;h= Math.sin(b*h)/k;this._w=f*g+this._w*h;this._x=c*g+this._x*h;this._y=d*g+this._y*h;this._z=e*g+this._z*h;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback= a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Quaternion(this._x,this._y,this._z,this._w)}};THREE.Quaternion.slerp=function(a,b,c,d){return c.copy(a).slerp(b,d)};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; @@ -42,7 +42,7 @@ a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:functio this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y= a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&&THREE.error("THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));return this}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),applyMatrix3:function(a){var b=this.x, c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z= -(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,p=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-p*-f;this.y=k*a+b*-f+p*-e-h*-g;this.z=p*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0=== +(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,l=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-l*-f;this.y=k*a+b*-f+l*-e-h*-g;this.z=l*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0=== a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},min:function(a){this.x> a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3,b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a, b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z); @@ -58,8 +58,8 @@ THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x= case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a, b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b= this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a):(this.z=this.y=this.x=0,this.w=1);return this},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this}, -setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var p=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+p-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;p=(p+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>p?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>p?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h), -b=d/c,d=k/c):.01>p?(c=b=.707106781,d=0):(d=Math.sqrt(p),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+p-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xMath.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+l-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;l=(l+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>l?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>l?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h), +b=d/c,d=k/c):.01>l?(c=b=.707106781,d=0):(d=Math.sqrt(l),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+l-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);this.wb.w&&(this.w=b.w);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector4,b=new THREE.Vector4);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w); return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w); return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())}, @@ -67,9 +67,9 @@ setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b) b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=a.array[b+3];return this},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)}};THREE.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||THREE.Euler.DefaultOrder};THREE.Euler.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" "); THREE.Euler.DefaultOrder="XYZ"; THREE.Euler.prototype={constructor:THREE.Euler,_x:0,_y:0,_z:0,_order:THREE.Euler.DefaultOrder,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get order(){return this._order},set order(a){this._order=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this.onChangeCallback();return this},copy:function(a){this._x= -a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],p=e[9],n=e[2],q=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-p,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(q,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h, -k)):(this._y=Math.atan2(-n,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(q,-1,1)),.99999>Math.abs(q)?(this._y=Math.atan2(-n,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._x=Math.atan2(q,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-p,k),this._y=Math.atan2(-n,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z= -Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(q,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-p,e),this._y=0)):THREE.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z, +a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],l=e[9],p=e[2],q=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-l,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(q,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(l,-1,1)),.99999>Math.abs(l)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h, +k)):(this._y=Math.atan2(-p,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(q,-1,1)),.99999>Math.abs(q)?(this._y=Math.atan2(-p,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(p,-1,1)),.99999>Math.abs(p)?(this._x=Math.atan2(q,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-l,k),this._y=Math.atan2(-p,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z= +Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(q,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-l,e),this._y=0)):THREE.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z, b||this._order)},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a? a.set(this._x,this._y,this._z):new THREE.Vector3(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Euler(this._x,this._y,this._z,this._order)}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; THREE.Line3.prototype={constructor:THREE.Line3,set:function(a,b){this.start.copy(a);this.end.copy(b);return this},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},center:function(a){return(a||new THREE.Vector3).addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){return(a||new THREE.Vector3).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a, @@ -88,38 +88,38 @@ this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max. new THREE.Vector3;return function(b){b=b||new THREE.Sphere;b.center=this.center();b.radius=.5*this.size(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];return function(b){a[0].set(this.min.x,this.min.y, this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.makeEmpty();this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a); this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box3).copy(this)}};THREE.Matrix3=function(){this.elements=new Float32Array([1,0,0,0,1,0,0,0,1]);0this.determinant()&&(g=-g);c.x=f[12]; -c.y=f[13];c.z=f[14];b.elements.set(this.elements);c=1/g;var f=1/h,p=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=p;b.elements[9]*=p;b.elements[10]*=p;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makeFrustum:function(a,b,c,d,e,f){var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(d-c);g[9]=(d+c)/(d-c);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0; -g[11]=-1;g[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(THREE.Math.degToRad(.5*a));var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=b-a,k=c-d,p=f-e;g[0]=2/h;g[4]=0;g[8]=0;g[12]=-((b+a)/h);g[1]=0;g[5]=2/k;g[9]=0;g[13]=-((c+d)/k);g[2]=0;g[6]=0;g[10]=-2/p;g[14]=-((f+e)/p);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0], +c,0,0,0,1);return this},makeRotationX:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(1,0,0,0,0,b,-a,0,0,a,b,0,0,0,0,1);return this},makeRotationY:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,0,a,0,0,1,0,0,-a,0,b,0,0,0,0,1);return this},makeRotationZ:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,-a,0,0,a,b,0,0,0,0,1,0,0,0,0,1);return this},makeRotationAxis:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=1-c,f=a.x,g=a.y,h=a.z,k=e*f,l=e*g;this.set(k*f+c,k*g-d*h,k*h+d*g,0,k*g+ +d*h,l*g+c,l*h-d*f,0,k*h-d*g,l*h+d*f,e*h*h+c,0,0,0,0,1);return this},makeScale:function(a,b,c){this.set(a,0,0,0,0,b,0,0,0,0,c,0,0,0,0,1);return this},compose:function(a,b,c){this.makeRotationFromQuaternion(b);this.scale(c);this.setPosition(a);return this},decompose:function(){var a=new THREE.Vector3,b=new THREE.Matrix4;return function(c,d,e){var f=this.elements,g=a.set(f[0],f[1],f[2]).length(),h=a.set(f[4],f[5],f[6]).length(),k=a.set(f[8],f[9],f[10]).length();0>this.determinant()&&(g=-g);c.x=f[12]; +c.y=f[13];c.z=f[14];b.elements.set(this.elements);c=1/g;var f=1/h,l=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=l;b.elements[9]*=l;b.elements[10]*=l;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makeFrustum:function(a,b,c,d,e,f){var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(d-c);g[9]=(d+c)/(d-c);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0; +g[11]=-1;g[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(THREE.Math.degToRad(.5*a));var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=b-a,k=c-d,l=f-e;g[0]=2/h;g[4]=0;g[8]=0;g[12]=-((b+a)/h);g[1]=0;g[5]=2/k;g[9]=0;g[13]=-((c+d)/k);g[2]=0;g[6]=0;g[10]=-2/l;g[14]=-((f+e)/l);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0], a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]]},clone:function(){return(new THREE.Matrix4).fromArray(this.elements)}};THREE.Ray=function(a,b){this.origin=void 0!==a?a:new THREE.Vector3;this.direction=void 0!==b?b:new THREE.Vector3}; THREE.Ray.prototype={constructor:THREE.Ray,set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){return(b||new THREE.Vector3).copy(this.direction).multiplyScalar(a).add(this.origin)},recast:function(){var a=new THREE.Vector3;return function(b){this.origin.copy(this.at(b,a));return this}}(),closestPointToPoint:function(a,b){var c=b||new THREE.Vector3;c.subVectors(a,this.origin); var d=c.dot(this.direction);return 0>d?c.copy(this.origin):c.copy(this.direction).multiplyScalar(d).add(this.origin)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceTo(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceTo(b)}}(),distanceSqToSegment:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5); -b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var h=.5*d.distanceTo(e),k=-this.direction.dot(b),p=c.dot(this.direction),n=-c.dot(b),q=c.lengthSq(),l=Math.abs(1-k*k),s;0=-s?e<=s?(h=1/l,d*=h,e*=h,k=d*(d+k*e+2*p)+e*(k*d+e+2*n)+q):(e=h,d=Math.max(0,-(k*e+p)),k=-d*d+e*(e+2*n)+q):(e=-h,d=Math.max(0,-(k*e+p)),k=-d*d+e*(e+2*n)+q):e<=-s?(d=Math.max(0,-(-k*h+p)),e=0=-t?e<=t?(h=1/n,d*=h,e*=h,k=d*(d+k*e+2*l)+e*(k*d+e+2*p)+q):(e=h,d=Math.max(0,-(k*e+l)),k=-d*d+e*(e+2*p)+q):(e=-h,d=Math.max(0,-(k*e+l)),k=-d*d+e*(e+2*p)+q):e<=-t?(d=Math.max(0,-(-k*h+l)),e=0f)return null;f=Math.sqrt(f-e);e=d-f;d+=f;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),isIntersectionPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0==b)return 0==a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){var c=this.distanceToPlane(a);return null===c?null:this.at(c,b)}, isIntersectionBox:function(){var a=new THREE.Vector3;return function(b){return null!==this.intersectBox(b,a)}}(),intersectBox:function(a,b){var c,d,e,f,g;d=1/this.direction.x;f=1/this.direction.y;g=1/this.direction.z;var h=this.origin;0<=d?(c=(a.min.x-h.x)*d,d*=a.max.x-h.x):(c=(a.max.x-h.x)*d,d*=a.min.x-h.x);0<=f?(e=(a.min.y-h.y)*f,f*=a.max.y-h.y):(e=(a.max.y-h.y)*f,f*=a.min.y-h.y);if(c>f||e>d)return null;if(e>c||c!==c)c=e;if(fg||e>d)return null;if(e>c||c!==c)c=e;if(gd?null:this.at(0<=c?c:d,b)},intersectTriangle:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3,d=new THREE.Vector3;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0f)h=-1,f=-f;else return null;a.subVectors(this.origin,e);e=h*this.direction.dot(c.crossVectors(a,c));if(0>e)return null;g=h*this.direction.dot(b.cross(a)); @@ -128,8 +128,8 @@ THREE.Sphere.prototype={constructor:THREE.Sphere,set:function(a,b){this.center.c this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},clampPoint:function(a,b){var c=this.center.distanceToSquared(a),d=b||new THREE.Vector3;d.copy(a);c>this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=a||new THREE.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius); return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius},clone:function(){return(new THREE.Sphere).copy(this)}}; THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]}; -THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],p=c[7],n=c[8],q=c[9],l=c[10],s=c[11],t=c[12],r=c[13],u=c[14],c=c[15];b[0].setComponents(f-a,p-g,s-n,c-t).normalize();b[1].setComponents(f+ -a,p+g,s+n,c+t).normalize();b[2].setComponents(f+d,p+h,s+q,c+r).normalize();b[3].setComponents(f-d,p-h,s-q,c-r).normalize();b[4].setComponents(f-e,p-k,s-l,c-u).normalize();b[5].setComponents(f+e,p+k,s+l,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes, +THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],l=c[7],p=c[8],q=c[9],n=c[10],t=c[11],s=c[12],r=c[13],u=c[14],c=c[15];b[0].setComponents(f-a,l-g,t-p,c-s).normalize();b[1].setComponents(f+ +a,l+g,t+p,c+s).normalize();b[2].setComponents(f+d,l+h,t+q,c+r).normalize();b[3].setComponents(f-d,l-h,t-q,c-r).normalize();b[4].setComponents(f-e,l-k,t-n,c-u).normalize();b[5].setComponents(f+e,l+k,t+n,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes, c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)e;e++){var f=d[e];a.x=0g&&0>f)return!1}return!0}}(), containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d, @@ -140,11 +140,11 @@ a.constant==this.constant},clone:function(){return(new THREE.Plane).copy(this)}} THREE.Math={generateUUID:function(){var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d;return function(){for(var e=0;36>e;e++)8==e||13==e||18==e||23==e?b[e]="-":14==e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19==e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return a=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){return(65280*Math.random()+255*Math.random())/65535},randInt:function(a,b){return Math.floor(this.randFloat(a,b))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a= 180/Math.PI;return function(b){return b*a}}(),isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}}; -THREE.Spline=function(a){function b(a,b,c,d,e,f,g){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,f,g,h,k,p,n,q,l;this.initFromArray=function(a){this.points=[];for(var b=0;bthis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ -2;p=this.points[c[0]];n=this.points[c[1]];q=this.points[c[2]];l=this.points[c[3]];h=g*g;k=g*h;d.x=b(p.x,n.x,q.x,l.x,g,h,k);d.y=b(p.y,n.y,q.y,l.y,g,h,k);d.z=b(p.z,n.z,q.z,l.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;athis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ +2;l=this.points[c[0]];p=this.points[c[1]];q=this.points[c[2]];n=this.points[c[3]];h=g*g;k=g*h;d.x=b(l.x,p.x,q.x,n.x,g,h,k);d.y=b(l.y,p.y,q.y,n.y,g,h,k);d.z=b(l.z,p.z,q.z,n.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a=b.x+b.y}}(); THREE.Triangle.prototype={constructor:THREE.Triangle,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*a.cross(b).length()}}(),midpoint:function(a){return(a|| new THREE.Vector3).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return THREE.Triangle.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new THREE.Plane).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return THREE.Triangle.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return THREE.Triangle.containsPoint(a,this.a,this.b,this.c)},equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}, @@ -185,49 +185,49 @@ THREE.Uint32Attribute=function(a,b){THREE.warn("THREE.Uint32Attribute has been r THREE.Float64Attribute=function(a,b){THREE.warn("THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.");return new THREE.BufferAttribute(a,b)};THREE.DynamicBufferAttribute=function(a,b){THREE.BufferAttribute.call(this,a,b);this.updateRange={offset:0,count:-1}};THREE.DynamicBufferAttribute.prototype=Object.create(THREE.BufferAttribute.prototype);THREE.DynamicBufferAttribute.prototype.constructor=THREE.DynamicBufferAttribute; THREE.DynamicBufferAttribute.prototype.clone=function(){return new THREE.DynamicBufferAttribute(new this.array.constructor(this.array),this.itemSize)};THREE.BufferGeometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="BufferGeometry";this.attributes={};this.attributesKeys=[];this.offsets=this.drawcalls=[];this.boundingSphere=this.boundingBox=null}; THREE.BufferGeometry.prototype={constructor:THREE.BufferGeometry,addAttribute:function(a,b,c){!1===b instanceof THREE.BufferAttribute?(THREE.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),this.attributes[a]={array:b,itemSize:c}):(this.attributes[a]=b,this.attributesKeys=Object.keys(this.attributes))},getAttribute:function(a){return this.attributes[a]},addDrawCall:function(a,b,c){this.drawcalls.push({start:a,count:b,index:void 0!==c?c:0})},applyMatrix:function(a){var b= -this.attributes.position;void 0!==b&&(a.applyToVector3Array(b.array),b.needsUpdate=!0);b=this.attributes.normal;void 0!==b&&((new THREE.Matrix3).getNormalMatrix(a).applyToVector3Array(b.array),b.needsUpdate=!0)},center:function(){},fromGeometry:function(a,b){b=b||{vertexColors:THREE.NoColors};var c=a.vertices,d=a.faces,e=a.faceVertexUvs,f=b.vertexColors,g=0na?-1:1;h[4*a]=ma.x;h[4*a+1]=ma.y;h[4*a+2]=ma.z;h[4*a+3]=Ka}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],p=[],n=0;nr;r++)t=a[3*c+r],-1==l[t]?(q[2*r]=t,q[2*r+1]=-1,n++):l[t]k.index+b)for(k={start:f,count:0,index:g},h.push(k),n=0;6>n;n+=2)r=q[n+1],-1n;n+=2)t=q[n],r=q[n+1],-1===r&&(r=g++),l[t]=r,s[r]=t,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,s,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hqa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, +e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cg;g++)l=x[k++],v=u[2*l],l=u[2*l+1],v=new THREE.Vector2(v,l),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]),r.normal.copy(s.normal));if(t)for(d=0;4>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++], -C[q++],C[q]),2!==d&&s.vertexNormals.push(t),0!==d&&r.vertexNormals.push(t);n&&(n=x[k++],n=w[n],s.color.setHex(n),r.color.setHex(n));if(b)for(d=0;4>d;d++)n=x[k++],n=w[n],2!==d&&s.vertexColors.push(new THREE.Color(n)),0!==d&&r.vertexColors.push(new THREE.Color(n));c.faces.push(s);c.faces.push(r)}else{s=new THREE.Face3;s.a=x[k++];s.b=x[k++];s.c=x[k++];h&&(h=x[k++],s.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)l=x[k++],v=u[2*l],l=u[2*l+1], -v=new THREE.Vector2(v,l),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],s.normal.set(C[q++],C[q++],C[q]));if(t)for(d=0;3>d;d++)q=3*x[k++],t=new THREE.Vector3(C[q++],C[q++],C[q]),s.vertexNormals.push(t);n&&(n=x[k++],s.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=x[k++],s.vertexColors.push(new THREE.Color(w[n]));c.faces.push(s)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1],v=new THREE.Vector2(v,n),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],t.normal.set(F[q++],F[q++],F[q]),r.normal.copy(t.normal));if(s)for(d=0;4>d;d++)q=3*x[k++],s=new THREE.Vector3(F[q++], +F[q++],F[q]),2!==d&&t.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);p&&(p=x[k++],p=w[p],t.color.setHex(p),r.color.setHex(p));if(b)for(d=0;4>d;d++)p=x[k++],p=w[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&r.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(r)}else{t=new THREE.Face3;t.a=x[k++];t.b=x[k++];t.c=x[k++];h&&(h=x[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1], +v=new THREE.Vector2(v,n),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],t.normal.set(F[q++],F[q++],F[q]));if(s)for(d=0;3>d;d++)q=3*x[k++],s=new THREE.Vector3(F[q++],F[q++],F[q]),t.vertexNormals.push(s);p&&(p=x[k++],t.color.setHex(w[p]));if(b)for(d=0;3>d;d++)p=x[k++],t.vertexColors.push(new THREE.Color(w[p]));c.faces.push(t)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;df||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, -object:this}))}}else for(l=l.position.array,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(C=b.origin.distanceTo(n),Cd.far||e.push({distance:C,point:p.clone().applyMatrix4(this.matrixWorld), +THREE.Line.prototype.raycast=function(){var a=new THREE.Matrix4,b=new THREE.Ray,c=new THREE.Sphere;return function(d,e){var f=d.linePrecision,f=f*f,g=this.geometry;null===g.boundingSphere&&g.computeBoundingSphere();c.copy(g.boundingSphere);c.applyMatrix4(this.matrixWorld);if(!1!==d.ray.isIntersectionSphere(c)){a.getInverse(this.matrixWorld);b.copy(d.ray).applyMatrix4(a);var h=new THREE.Vector3,k=new THREE.Vector3,l=new THREE.Vector3,p=new THREE.Vector3,q=this.mode===THREE.LineStrip?1:2;if(g instanceof +THREE.BufferGeometry){var n=g.attributes;if(void 0!==n.index){var t=n.index.array,n=n.position.array,s=g.offsets;0===s.length&&(s=[{start:0,count:t.length,index:0}]);for(var r=0;rf||(F=b.origin.distanceTo(p),Fd.far||e.push({distance:F,point:l.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, +object:this}))}}else for(n=n.position.array,g=0;gf||(F=b.origin.distanceTo(p),Fd.far||e.push({distance:F,point:l.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(F=b.origin.distanceTo(p),Fd.far||e.push({distance:F,point:l.clone().applyMatrix4(this.matrixWorld), index:g,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(a){void 0===a&&(a=new THREE.Line(this.geometry,this.material,this.mode));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype); THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,l,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=n.position.array,t=k=0,w=r.length;k -g.far||h.push({distance:A,point:y,face:new THREE.Face3(n,q,l,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(t=this.material instanceof THREE.MeshFaceMaterial,r=!0===t?this.material.materials:null,s=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:C,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.type="Bone";this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; +THREE.Mesh.prototype.raycast=function(){var a=new THREE.Matrix4,b=new THREE.Ray,c=new THREE.Sphere,d=new THREE.Vector3,e=new THREE.Vector3,f=new THREE.Vector3;return function(g,h){var k=this.geometry;null===k.boundingSphere&&k.computeBoundingSphere();c.copy(k.boundingSphere);c.applyMatrix4(this.matrixWorld);if(!1!==g.ray.isIntersectionSphere(c)&&(a.getInverse(this.matrixWorld),b.copy(g.ray).applyMatrix4(a),null===k.boundingBox||!1!==b.isIntersectionBox(k.boundingBox)))if(k instanceof THREE.BufferGeometry){var l= +this.material;if(void 0!==l){var p=k.attributes,q,n,t=g.precision;if(void 0!==p.index){var s=p.index.array,r=p.position.array,u=k.offsets;0===u.length&&(u=[{start:0,count:s.length,index:0}]);for(var v=0,x=u.length;vg.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=p.position.array,s=k=0,w=r.length;k +g.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(s=this.material instanceof THREE.MeshFaceMaterial,r=!0===s?this.material.materials:null,t=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:F,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.type="Bone";this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(this.boneTextureHeight=this.boneTextureWidth=a=256h&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in q||(n={id:Rb++,faces3:[],materialIndex:u,vertices:0,numMorphTargets:l,numMorphNormals:p},q[k]=n,s.push(n)));q[k].faces3.push(t);q[k].vertices+=3}f[g]=s;b.groupsNeedUpdate=!1}f=fb[b.id];g=0;for(d=f.length;gX;X++)gb=K[X],Ta[Ya]=gb.x,Ta[Ya+1]=gb.y,Ta[Ya+2]=gb.z,Ya+=3;else for(X=0;3>X;X++)Ta[Ya]=J.x,Ta[Ya+1]=J.y,Ta[Ya+2]=J.z,Ya+=3;m.bindBuffer(m.ARRAY_BUFFER,u.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Ta,C)}if(yb&&Jb){y=0;for(z=Z.length;yX;X++)xa=U[X],Pa[tb]=xa.x,Pa[tb+1]=xa.y,tb+=2;0X;X++)qa=T[X],qb[Ka]=qa.x,qb[Ka+1]=qa.y,Ka+=2;0va;va++)mb[va]=!B.autoScaleCubemaps|| -Sb||Kb?Kb?W.image[va].image:W.image[va]:z(W.image[va],qc);var Yb=mb[0],Zb=THREE.Math.isPowerOfTwo(Yb.width)&&THREE.Math.isPowerOfTwo(Yb.height),bb=K(W.format),xb=K(W.type);F(m.TEXTURE_CUBE_MAP,W,Zb);for(va=0;6>va;va++)if(Sb)for(var nb,$b=mb[va].mipmaps,Fb=0,Tb=$b.length;Fb=fc&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+fc);Ob+=1;return a}function E(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)} -function H(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function F(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,K(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,K(b.wrapT)),m.texParameteri(a,m.TEXTURE_MAG_FILTER,K(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,K(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+ -b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,N(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,N(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=ca.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a} -function J(a,b){m.bindRenderbuffer(m.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_COMPONENT16,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_STENCIL,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a)):m.renderbufferStorage(m.RENDERBUFFER,m.RGBA4,b.width,b.height)}function M(a){a instanceof -THREE.WebGLRenderTargetCube?(m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture),m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function N(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function K(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE; -if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return m.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return m.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return m.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return m.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return m.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return m.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return m.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return m.UNSIGNED_SHORT_4_4_4_4; -if(a===THREE.UnsignedShort5551Type)return m.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return m.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return m.BYTE;if(a===THREE.ShortType)return m.SHORT;if(a===THREE.UnsignedShortType)return m.UNSIGNED_SHORT;if(a===THREE.IntType)return m.INT;if(a===THREE.UnsignedIntType)return m.UNSIGNED_INT;if(a===THREE.FloatType)return m.FLOAT;b=ca.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return m.ALPHA; -if(a===THREE.RGBFormat)return m.RGB;if(a===THREE.RGBAFormat)return m.RGBA;if(a===THREE.LuminanceFormat)return m.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return m.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return m.FUNC_ADD;if(a===THREE.SubtractEquation)return m.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return m.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return m.ZERO;if(a===THREE.OneFactor)return m.ONE;if(a===THREE.SrcColorFactor)return m.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return m.ONE_MINUS_SRC_COLOR; -if(a===THREE.SrcAlphaFactor)return m.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return m.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return m.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return m.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return m.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return m.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return m.SRC_ALPHA_SATURATE;b=ca.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT; -if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=ca.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; -if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=ca.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var T=void 0!==a.canvas?a.canvas:document.createElement("canvas"),O=void 0!==a.context?a.context:null,U=1,Q=void 0!==a.precision?a.precision:"highp",V=void 0!==a.alpha?a.alpha:!1,L=void 0!==a.depth?a.depth:!0,ma=void 0!==a.stencil? -a.stencil:!0,ba=void 0!==a.antialias?a.antialias:!1,ra=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,G=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,Ka=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,aa=new THREE.Color(0),na=0,wa=[],Ca={},za=[],Qa=[],La=[],gb=[],cb=[];this.domElement=T;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput= -!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,Va=[],tb=null,zb=null,yb=-1,Ja="",Gb=null,Ob=0,Ab=0,ob=0,Wa=T.width,eb=T.height,Yb=0,Zb=0,ib=new Uint8Array(16),Pa=new Uint8Array(16),jb=new THREE.Frustum,vb=new THREE.Matrix4;new THREE.Matrix4; -var xa=new THREE.Vector3,la=new THREE.Vector3,Hb=!0,ic={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},m;try{var $b={alpha:V,depth:L,stencil:ma,antialias:ba,premultipliedAlpha:ra,preserveDrawingBuffer:G};m=O||T.getContext("webgl",$b)||T.getContext("experimental-webgl", -$b);if(null===m){if(null!==T.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}T.addEventListener("webglcontextlost",function(a){a.preventDefault();kc();lc();Ca={}},!1)}catch(rc){THREE.error("THREE.WebGLRenderer: "+rc)}var qa=new THREE.WebGLState(m,K);void 0===m.getShaderPrecisionFormat&&(m.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var ca=new THREE.WebGLExtensions(m);ca.get("OES_texture_float"); -ca.get("OES_texture_float_linear");ca.get("OES_texture_half_float");ca.get("OES_texture_half_float_linear");ca.get("OES_standard_derivatives");Ka&&ca.get("EXT_frag_depth");var pb=function(a,b,c,d){!0===ra&&(a*=d,b*=d,c*=d);m.clearColor(a,b,c,d)},lc=function(){m.clearColor(0,0,0,1);m.clearDepth(1);m.clearStencil(0);m.enable(m.DEPTH_TEST);m.depthFunc(m.LEQUAL);m.frontFace(m.CCW);m.cullFace(m.BACK);m.enable(m.CULL_FACE);m.enable(m.BLEND);m.blendEquation(m.FUNC_ADD);m.blendFunc(m.SRC_ALPHA,m.ONE_MINUS_SRC_ALPHA); -m.viewport(Ab,ob,Wa,eb);pb(aa.r,aa.g,aa.b,na)},kc=function(){Gb=tb=null;Ja="";yb=-1;Hb=!0;for(var a=0;ab;b++)m.deleteFramebuffer(a.__webglFramebuffer[b]),m.deleteRenderbuffer(a.__webglRenderbuffer[b]);else m.deleteFramebuffer(a.__webglFramebuffer),m.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},hc=function(a){a=a.target;a.removeEventListener("dispose",hc);gc(a)},nc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "), -c=0,d=b.length;cl.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),q.length=l.length);l=0;for(s=q.length;ld.numSupportedMorphTargets?(n.sort(p),n.length=d.numSupportedMorphTargets):n.length>d.numSupportedMorphNormals?n.sort(p):0===n.length&& -n.push([0,0]);for(var l=0,r=d.numSupportedMorphTargets;lf;f++){a.__webglFramebuffer[f]=m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER, -m.COLOR_ATTACHMENT0,h,g.__webglTexture,0);J(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:m.createRenderbuffer(),m.bindTexture(m.TEXTURE_2D,a.__webglTexture),F(m.TEXTURE_2D,a,c),m.texImage2D(m.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=m.TEXTURE_2D,m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0, -d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):J(a.__webglRenderbuffer,a),c&&m.generateMipmap(m.TEXTURE_2D);b?m.bindTexture(m.TEXTURE_CUBE_MAP,null):m.bindTexture(m.TEXTURE_2D,null);m.bindRenderbuffer(m.RENDERBUFFER,null);m.bindFramebuffer(m.FRAMEBUFFER, -null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Wa,a=eb,d=Ab,e=ob);b!==zb&&(m.bindFramebuffer(m.FRAMEBUFFER,b),m.viewport(d,e,c,a),zb=b);Yb=c;Zb=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); -else{var g=!1;a.__webglFramebuffer!==zb&&(m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),g=!0);m.checkFramebufferStatus(m.FRAMEBUFFER)===m.FRAMEBUFFER_COMPLETE?m.readPixels(b,c,d,e,m.RGBA,m.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&m.bindFramebuffer(m.FRAMEBUFFER,zb)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}; -this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +!0}b.__webglCustomAttributesList.push(e)}}}function c(a,b){return a.material instanceof THREE.MeshFaceMaterial?a.material.materials[b.materialIndex]:a.material}function d(a,b,c,d){c=c.attributes;var e=b.attributes;b=b.attributesKeys;for(var f=0,g=b.length;fh&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in r||(q={id:Qb++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:l,numMorphNormals:p},r[k]=q,t.push(q))); +r[k].faces3.push(s);r[k].vertices+=3}f[g]=t;b.groupsNeedUpdate=!1}f=Ua[b.id];g=0;for(d=f.length;gY;Y++)pa=H[Y],Na[Ra]=pa.x,Na[Ra+1]=pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=I.x,Na[Ra+1]=I.y,Na[Ra+2]=I.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER, +w.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Na,x)}if(vb&&Hb){y=0;for(z=$.length;yY;Y++)ab=U[Y],Ab[kb]=ab.x,Ab[kb+1]=ab.y,kb+=2;0Y;Y++)oa=O[Y],lb[yb]=oa.x,lb[yb+1]=oa.y,yb+=2;0ya;ya++)gb[ya]=!B.autoScaleCubemaps||Rb||Ib?Ib?X.image[ya].image:X.image[ya]:E(X.image[ya],qc);var Yb=gb[0],Zb=THREE.Math.isPowerOfTwo(Yb.width)&&THREE.Math.isPowerOfTwo(Yb.height),Wa=H(X.format),tb=H(X.type);A(m.TEXTURE_CUBE_MAP,X,Zb);for(ya=0;6>ya;ya++)if(Rb)for(var hb,$b=gb[ya].mipmaps,Fb= +0,Sb=$b.length;Fb=Wb&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Wb);Mb+=1;return a}function w(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function y(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,H(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,H(b.wrapT)),m.texParameteri(a, +m.TEXTURE_MAG_FILTER,H(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,H(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,D(b.magFilter)),m.texParameteri(a, +m.TEXTURE_MIN_FILTER,D(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=da.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function G(a,b){m.bindRenderbuffer(m.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer? +(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_COMPONENT16,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_STENCIL,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a)):m.renderbufferStorage(m.RENDERBUFFER,m.RGBA4,b.width,b.height)}function z(a){a instanceof THREE.WebGLRenderTargetCube?(m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture), +m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function D(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function H(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT; +if(a===THREE.NearestFilter)return m.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return m.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return m.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return m.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return m.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return m.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return m.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return m.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return m.UNSIGNED_SHORT_5_5_5_1; +if(a===THREE.UnsignedShort565Type)return m.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return m.BYTE;if(a===THREE.ShortType)return m.SHORT;if(a===THREE.UnsignedShortType)return m.UNSIGNED_SHORT;if(a===THREE.IntType)return m.INT;if(a===THREE.UnsignedIntType)return m.UNSIGNED_INT;if(a===THREE.FloatType)return m.FLOAT;b=da.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return m.ALPHA;if(a===THREE.RGBFormat)return m.RGB;if(a===THREE.RGBAFormat)return m.RGBA; +if(a===THREE.LuminanceFormat)return m.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return m.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return m.FUNC_ADD;if(a===THREE.SubtractEquation)return m.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return m.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return m.ZERO;if(a===THREE.OneFactor)return m.ONE;if(a===THREE.SrcColorFactor)return m.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return m.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return m.SRC_ALPHA; +if(a===THREE.OneMinusSrcAlphaFactor)return m.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return m.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return m.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return m.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return m.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return m.SRC_ALPHA_SATURATE;b=da.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT; +if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=da.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b= +da.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var U=void 0!==a.canvas?a.canvas:document.createElement("canvas"),M=void 0!==a.context?a.context:null,I=1,L=void 0!==a.precision?a.precision:"highp",P=void 0!==a.alpha?a.alpha:!1,N=void 0!==a.depth?a.depth:!0,R=void 0!==a.stencil?a.stencil:!0,V=void 0!==a.antialias?a.antialias:!1,J=void 0!==a.premultipliedAlpha? +a.premultipliedAlpha:!0,oa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,ja=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ha=new THREE.Color(0),O=0,ca=[],ba={},qa=[],Ka=[],Qa=[],Xa=[],Ya=[];this.domElement=U;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront; +this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,Pa=[],ob=null,ab=null,ub=-1,ta="",vb=null,Mb=0,ib=0,bb=0,pb=U.width,qb=U.height,Xb=0,fc=0,cb=new THREE.Frustum,db=new THREE.Matrix4;new THREE.Matrix4;var wa=new THREE.Vector3,pa=new THREE.Vector3,Ob=!0,jc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0, +colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},m;try{var Yb={alpha:P,depth:N,stencil:R,antialias:V,premultipliedAlpha:J,preserveDrawingBuffer:oa};m=M||U.getContext("webgl",Yb)||U.getContext("experimental-webgl",Yb);if(null===m){if(null!==U.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context."; +}U.addEventListener("webglcontextlost",function(a){a.preventDefault();Zb();lc();ba={}},!1)}catch(rc){THREE.error("THREE.WebGLRenderer: "+rc)}var W=new THREE.WebGLState(m,H);void 0===m.getShaderPrecisionFormat&&(m.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var da=new THREE.WebGLExtensions(m);da.get("OES_texture_float");da.get("OES_texture_float_linear");da.get("OES_texture_half_float");da.get("OES_texture_half_float_linear");da.get("OES_standard_derivatives");ja&& +da.get("EXT_frag_depth");var rb=function(a,b,c,d){!0===J&&(a*=d,b*=d,c*=d);m.clearColor(a,b,c,d)},lc=function(){m.clearColor(0,0,0,1);m.clearDepth(1);m.clearStencil(0);m.enable(m.DEPTH_TEST);m.depthFunc(m.LEQUAL);m.frontFace(m.CCW);m.cullFace(m.BACK);m.enable(m.CULL_FACE);m.enable(m.BLEND);m.blendEquation(m.FUNC_ADD);m.blendFunc(m.SRC_ALPHA,m.ONE_MINUS_SRC_ALPHA);m.viewport(ib,bb,pb,qb);rb(ha.r,ha.g,ha.b,O)},Zb=function(){vb=ob=null;ta="";ub=-1;Ob=!0;W.reset()};lc();this.context=m;this.state=W;var Wb= +m.getParameter(m.MAX_TEXTURE_IMAGE_UNITS),sc=m.getParameter(m.MAX_VERTEX_TEXTURE_IMAGE_UNITS),tc=m.getParameter(m.MAX_TEXTURE_SIZE),qc=m.getParameter(m.MAX_CUBE_MAP_TEXTURE_SIZE),Vb=0b;b++)m.deleteFramebuffer(a.__webglFramebuffer[b]),m.deleteRenderbuffer(a.__webglRenderbuffer[b]);else m.deleteFramebuffer(a.__webglFramebuffer), +m.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},ic=function(a){a=a.target;a.removeEventListener("dispose",ic);hc(a)},nc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;ch.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),n.length=h.length);h=0;for(l=n.length;hd.numSupportedMorphTargets? +(k.sort(g),k.length=d.numSupportedMorphTargets):k.length>d.numSupportedMorphNormals?k.sort(g):0===k.length&&k.push([0,0]);for(var h=0,p=d.numSupportedMorphTargets;hf;f++){a.__webglFramebuffer[f]= +m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,h,g.__webglTexture,0);G(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: +m.createRenderbuffer(),m.bindTexture(m.TEXTURE_2D,a.__webglTexture),A(m.TEXTURE_2D,a,c),m.texImage2D(m.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=m.TEXTURE_2D,m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&m.framebufferRenderbuffer(m.FRAMEBUFFER, +m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):G(a.__webglRenderbuffer,a),c&&m.generateMipmap(m.TEXTURE_2D);b?m.bindTexture(m.TEXTURE_CUBE_MAP,null):m.bindTexture(m.TEXTURE_2D,null);m.bindRenderbuffer(m.RENDERBUFFER,null);m.bindFramebuffer(m.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=pb,a=qb,d=ib,e=bb);b!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,b),m.viewport(d,e,c,a),ab=b);Xb=c;fc=a};this.readRenderTargetPixels= +function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),g=!0);m.checkFramebufferStatus(m.FRAMEBUFFER)=== +m.FRAMEBUFFER_COMPLETE?m.readPixels(b,c,d,e,m.RGBA,m.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&m.bindFramebuffer(m.FRAMEBUFFER,ab)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; +this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; a.shareDepthFrom=this.shareDepthFrom;return a},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube.prototype.constructor=THREE.WebGLRenderTargetCube; THREE.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c])return b[c];var d;switch(c){case "EXT_texture_filter_anisotropic":d=a.getExtension("EXT_texture_filter_anisotropic")||a.getExtension("MOZ_EXT_texture_filter_anisotropic")||a.getExtension("WEBKIT_EXT_texture_filter_anisotropic");break;case "WEBGL_compressed_texture_s3tc":d=a.getExtension("WEBGL_compressed_texture_s3tc")||a.getExtension("MOZ_WEBGL_compressed_texture_s3tc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc"); break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;default:d=a.getExtension(c)}null===d&&THREE.warn("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}; -THREE.WebGLProgram=function(){var a=0;return function(b,c,d,e){var f=b.context,g=d.defines,h=d.__webglShader.uniforms,k=d.attributes,p=d.__webglShader.vertexShader,n=d.__webglShader.fragmentShader,q=d.index0AttributeName;void 0===q&&!0===e.morphTargets&&(q="position");var l="SHADOWMAP_TYPE_BASIC";e.shadowMapType===THREE.PCFShadowMap?l="SHADOWMAP_TYPE_PCF":e.shadowMapType===THREE.PCFSoftShadowMap&&(l="SHADOWMAP_TYPE_PCF_SOFT");var s="ENVMAP_TYPE_CUBE",t="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY"; -if(e.envMap){switch(d.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:s="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:s="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:s="ENVMAP_TYPE_SPHERE"}switch(d.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:t="ENVMAP_MODE_REFRACTION"}switch(d.combine){case THREE.MultiplyOperation:r="ENVMAP_BLENDING_MULTIPLY"; -break;case THREE.MixOperation:r="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:r="ENVMAP_BLENDING_ADD"}}var u=0T;T++)J[T]=new THREE.Vector3,F[T]=new THREE.Vector3;J=z.shadowCascadeNearZ[K];z=z.shadowCascadeFarZ[K];F[0].set(-1,-1,J);F[1].set(1,-1,J);F[2].set(-1,1,J);F[3].set(1,1,J);F[4].set(-1,-1,z);F[5].set(1,-1,z);F[6].set(-1,1,z);F[7].set(1,1,z);N.originalCamera=u;F=new THREE.Gyroscope;F.position.copy(A.shadowCascadeOffset);F.add(N);F.add(N.target);u.add(F);A.shadowCascadeArray[H]=N}K=A;J=H;z=K.shadowCascadeArray[J];z.position.copy(K.position); -z.target.position.copy(K.target.position);z.lookAt(z.target);z.shadowCameraVisible=K.shadowCameraVisible;z.shadowDarkness=K.shadowDarkness;z.shadowBias=K.shadowCascadeBias[J];F=K.shadowCascadeNearZ[J];K=K.shadowCascadeFarZ[J];z=z.pointsFrustum;z[0].z=F;z[1].z=F;z[2].z=F;z[3].z=F;z[4].z=K;z[5].z=K;z[6].z=K;z[7].z=K;M[E]=N;E++}else M[E]=A,E++;v=0;for(y=M.length;v -K;K++)J=z[K],J.copy(F[K]),J.unproject(H),J.applyMatrix4(E.matrixWorldInverse),J.xs.x&&(s.x=J.x),J.ys.y&&(s.y=J.y),J.zs.z&&(s.z=J.z);E.left=l.x;E.right=s.x;E.top=s.y;E.bottom=l.y;E.updateProjectionMatrix()}E=A.shadowMap;F=A.shadowMatrix;H=A.shadowCamera;H.position.setFromMatrixPosition(A.matrixWorld);t.setFromMatrixPosition(A.target.matrixWorld);H.lookAt(t);H.updateMatrixWorld();H.matrixWorldInverse.getInverse(H.matrixWorld);A.cameraHelper&& -(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();F.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);F.multiply(H.projectionMatrix);F.multiply(H.matrixWorldInverse);q.multiplyMatrices(H.projectionMatrix,H.matrixWorldInverse);n.setFromMatrix(q);a.setRenderTarget(E);a.clear();r.length=0;e(c,c,H);A=0;for(E=r.length;AL;L++)H[L]=new THREE.Vector3,z[L]=new THREE.Vector3;H=D.shadowCascadeNearZ[I];D=D.shadowCascadeFarZ[I];z[0].set(-1,-1,H);z[1].set(1,-1,H);z[2].set(-1,1,H);z[3].set(1,1,H);z[4].set(-1,-1,D);z[5].set(1,-1,D);z[6].set(-1,1,D);z[7].set(1,1,D);M.originalCamera=u;z=new THREE.Gyroscope;z.position.copy(A.shadowCascadeOffset);z.add(M);z.add(M.target);u.add(z);A.shadowCascadeArray[G]=M}I=A;H=G;D=I.shadowCascadeArray[H];D.position.copy(I.position); +D.target.position.copy(I.target.position);D.lookAt(D.target);D.shadowCameraVisible=I.shadowCameraVisible;D.shadowDarkness=I.shadowDarkness;D.shadowBias=I.shadowCascadeBias[H];z=I.shadowCascadeNearZ[H];I=I.shadowCascadeFarZ[H];D=D.pointsFrustum;D[0].z=z;D[1].z=z;D[2].z=z;D[3].z=z;D[4].z=I;D[5].z=I;D[6].z=I;D[7].z=I;U[E]=M;E++}else U[E]=A,E++;v=0;for(y=U.length;v +I;I++)H=D[I],H.copy(z[I]),H.unproject(G),H.applyMatrix4(E.matrixWorldInverse),H.xt.x&&(t.x=H.x),H.yt.y&&(t.y=H.y),H.zt.z&&(t.z=H.z);E.left=n.x;E.right=t.x;E.top=t.y;E.bottom=n.y;E.updateProjectionMatrix()}E=A.shadowMap;z=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);s.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(s);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& +(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();z.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);z.multiply(G.projectionMatrix);z.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(E);a.clear();r.length=0;e(c,c,G);A=0;for(E=r.length;A 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); -w.compileShader(T);w.compileShader(O);w.attachShader(K,T);w.attachShader(K,O);w.linkProgram(K);E=K;v=w.getAttribLocation(E,"position");x=w.getAttribLocation(E,"uv");c=w.getUniformLocation(E,"uvOffset");d=w.getUniformLocation(E,"uvScale");e=w.getUniformLocation(E,"rotation");f=w.getUniformLocation(E,"scale");g=w.getUniformLocation(E,"color");h=w.getUniformLocation(E,"map");k=w.getUniformLocation(E,"opacity");p=w.getUniformLocation(E,"modelViewMatrix");n=w.getUniformLocation(E,"projectionMatrix");q= -w.getUniformLocation(E,"fogType");l=w.getUniformLocation(E,"fogDensity");s=w.getUniformLocation(E,"fogNear");t=w.getUniformLocation(E,"fogFar");r=w.getUniformLocation(E,"fogColor");u=w.getUniformLocation(E,"alphaTest");K=document.createElement("canvas");K.width=8;K.height=8;T=K.getContext("2d");T.fillStyle="white";T.fillRect(0,0,8,8);H=new THREE.Texture(K);H.needsUpdate=!0}w.useProgram(E);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, -y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(n,!1,N.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);T=K=0;(O=M.fog)?(w.uniform3f(r,O.color.r,O.color.g,O.color.b),O instanceof THREE.Fog?(w.uniform1f(s,O.near),w.uniform1f(t,O.far),w.uniform1i(q,1),T=K=1):O instanceof THREE.FogExp2&&(w.uniform1f(l,O.density),w.uniform1i(q,2),T=K=2)):(w.uniform1i(q,0),T=K=0);for(var O=0,U=b.length;O< -U;O++){var Q=b[O];Q._modelViewMatrix.multiplyMatrices(N.matrixWorldInverse,Q.matrixWorld);Q.z=-Q._modelViewMatrix.elements[14]}b.sort(C);for(var V=[],O=0,U=b.length;O 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); +w.compileShader(L);w.compileShader(P);w.attachShader(I,L);w.attachShader(I,P);w.linkProgram(I);E=I;v=w.getAttribLocation(E,"position");x=w.getAttribLocation(E,"uv");c=w.getUniformLocation(E,"uvOffset");d=w.getUniformLocation(E,"uvScale");e=w.getUniformLocation(E,"rotation");f=w.getUniformLocation(E,"scale");g=w.getUniformLocation(E,"color");h=w.getUniformLocation(E,"map");k=w.getUniformLocation(E,"opacity");l=w.getUniformLocation(E,"modelViewMatrix");p=w.getUniformLocation(E,"projectionMatrix");q= +w.getUniformLocation(E,"fogType");n=w.getUniformLocation(E,"fogDensity");t=w.getUniformLocation(E,"fogNear");s=w.getUniformLocation(E,"fogFar");r=w.getUniformLocation(E,"fogColor");u=w.getUniformLocation(E,"alphaTest");I=document.createElement("canvas");I.width=8;I.height=8;L=I.getContext("2d");L.fillStyle="white";L.fillRect(0,0,8,8);G=new THREE.Texture(I);G.needsUpdate=!0}w.useProgram(E);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, +y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(p,!1,M.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);L=I=0;(P=U.fog)?(w.uniform3f(r,P.color.r,P.color.g,P.color.b),P instanceof THREE.Fog?(w.uniform1f(t,P.near),w.uniform1f(s,P.far),w.uniform1i(q,1),L=I=1):P instanceof THREE.FogExp2&&(w.uniform1f(n,P.density),w.uniform1i(q,2),L=I=2)):(w.uniform1i(q,0),L=I=0);for(var P=0,N=b.length;P< +N;P++){var R=b[P];R._modelViewMatrix.multiplyMatrices(M.matrixWorldInverse,R.matrixWorld);R.z=-R._modelViewMatrix.elements[14]}b.sort(F);for(var V=[],P=0,N=b.length;Pq-1?0:q-1,s=q+1>e-1?e-1:q+1,t=0>n-1?0:n-1,r=n+1>d-1?d-1:n+1,u=[],v=[0,0,h[4*(q*d+n)]/255*b];u.push([-1,0,h[4*(q*d+t)]/255*b]);u.push([-1,-1,h[4*(l*d+t)]/255*b]);u.push([0,-1,h[4*(l*d+n)]/255*b]);u.push([1,-1,h[4*(l*d+r)]/255*b]);u.push([1,0,h[4*(q*d+r)]/255*b]);u.push([1,1,h[4*(s*d+r)]/255*b]);u.push([0,1,h[4*(s*d+n)]/255* -b]);u.push([-1,1,h[4*(s*d+t)]/255*b]);l=[];t=u.length;for(s=0;sq-1?0:q-1,t=q+1>e-1?e-1:q+1,s=0>p-1?0:p-1,r=p+1>d-1?d-1:p+1,u=[],v=[0,0,h[4*(q*d+p)]/255*b];u.push([-1,0,h[4*(q*d+s)]/255*b]);u.push([-1,-1,h[4*(n*d+s)]/255*b]);u.push([0,-1,h[4*(n*d+p)]/255*b]);u.push([1,-1,h[4*(n*d+r)]/255*b]);u.push([1,0,h[4*(q*d+r)]/255*b]);u.push([1,1,h[4*(t*d+r)]/255*b]);u.push([0,1,h[4*(t*d+p)]/255* +b]);u.push([-1,1,h[4*(t*d+s)]/255*b]);n=[];s=u.length;for(t=0;te)return null;var f=[],g=[],h=[],k,p,n;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=p;e<=k&&(k=0);p=k+1;e<=p&&(p=0);n=p+1;e<=n&&(n=0);var l;a:{var s=l=void 0,t=void 0,r=void 0, -u=void 0,v=void 0,x=void 0,C=void 0,w=void 0,s=a[g[k]].x,t=a[g[k]].y,r=a[g[p]].x,u=a[g[p]].y,v=a[g[n]].x,x=a[g[n]].y;if(1E-10>(r-s)*(x-t)-(u-t)*(v-s))l=!1;else{var y=void 0,A=void 0,E=void 0,H=void 0,F=void 0,z=void 0,J=void 0,M=void 0,N=void 0,K=void 0,N=M=J=w=C=void 0,y=v-r,A=x-u,E=s-v,H=t-x,F=r-s,z=u-t;for(l=0;le)return null;var f=[],g=[],h=[],k,l,p;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=l;e<=k&&(k=0);l=k+1;e<=l&&(l=0);p=l+1;e<=p&&(p=0);var n;a:{var t=n=void 0,s=void 0,r=void 0, +u=void 0,v=void 0,x=void 0,F=void 0,w=void 0,t=a[g[k]].x,s=a[g[k]].y,r=a[g[l]].x,u=a[g[l]].y,v=a[g[p]].x,x=a[g[p]].y;if(1E-10>(r-t)*(x-s)-(u-s)*(v-t))n=!1;else{var y=void 0,A=void 0,E=void 0,G=void 0,z=void 0,D=void 0,H=void 0,U=void 0,M=void 0,I=void 0,M=U=H=w=F=void 0,y=v-r,A=x-u,E=t-v,G=s-x,z=r-t,D=u-s;for(n=0;n=b)return b=c[a]-b,a=this.curves[a],b=1-b/a.getLength(),a.getPointAt(b);a++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]}; THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length==this.curves.length)return this.cacheLengths;var a=[],b=0,c,d=this.curves.length;for(c=0;cb?b=h.x:h.xc?c=h.y:h.yd?d=h.z:h.zb?b=h.x:h.xc?c=h.y:h.yd?d=h.z:h.zMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; -THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cl&&(g=b[f],k=-k,h=b[e],l=-l),!(a.yh.y))if(a.y==g.y){if(a.x==g.x)return!0}else{e=l*(a.x-g.x)-k*(a.y-g.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<= -h.x))return!0}return d}var e=function(a){var b,c,d,e,f=[],g=new THREE.Path;b=0;for(c=a.length;bMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; +THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cn&&(g=b[f],k=-k,h=b[e],n=-n),!(a.yh.y))if(a.y==g.y){if(a.x==g.x)return!0}else{e=n*(a.x-g.x)-k*(a.y-g.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<= +h.x))return!0}return d}var e=function(a){var b,c,d,e,f=[],g=new THREE.Path;b=0;for(c=a.length;bH||H>E)return[];k=n*p-k*q;if(0>k||k>E)return[]}else{if(0d?[]:k==d?f?[]:[g]:a<=d?[g,h]: -[g,n]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]); -if(!d)return!1;d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c -K){console.log("Infinite Loop! Holes left:"+n.length+", Probably Hole outside Shape!");break}for(q=z;qh;h++)p=k[h].x+":"+k[h].y,p=n[p],void 0!==p&&(k[h]=p);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a* +THREE.Shape.Utils={triangulateShape:function(a,b){function c(a,b,c){return a.x!=b.x?a.xG||G>E)return[];k=l*p-k*q;if(0>k||k>E)return[]}else{if(0d?[]:k==d?f?[]:[g]:a<=d?[g,h]: +[g,l]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]); +if(!d)return!1;d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c +I){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(q=D;qh;h++)l=k[h].x+":"+k[h].y,l=p[l],void 0!==l&&(k[h]=l);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a* a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)}; THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()};THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve; THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b=new THREE.Vector2;b.x=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);return b};THREE.QuadraticBezierCurve.prototype.getTangent=function(a){var b=new THREE.Vector2;b.x=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.y,this.v1.y,this.v2.y);return b.normalize()}; @@ -698,12 +699,12 @@ THREE.Animation.prototype.play=function(a,b){this.currentTime=void 0!==a?a:0;thi THREE.Animation.prototype.reset=function(){for(var a=0,b=this.hierarchy.length;ad;d++){for(var e=this.keyTypes[d],f=this.data.hierarchy[a].keys[0],g=this.getNextKeyWith(e,a,1);g.timef.index;)f=g,g=this.getNextKeyWith(e,a,g.index+1);c.prevKey[e]=f;c.nextKey[e]=g}}}; THREE.Animation.prototype.resetBlendWeights=function(){for(var a=0,b=this.hierarchy.length;aa.length-2?q:q+1;c[3]=q>a.length-3?q:q+2;q=a[c[0]];s=a[c[1]];t=a[c[2]];r=a[c[3]];c=e*e;l=e*c;d[0]=f(q[0],s[0],t[0],r[0],e,c,l);d[1]=f(q[1],s[1],t[1],r[1],e,c,l);d[2]=f(q[2],s[2],t[2],r[2],e,c,l);return d},f=function(a,b,c,d,e,f,l){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*l+ -(-3*(b-c)-2*a-d)*f+a*e+b};return function(f){if(!1!==this.isPlaying&&(this.currentTime+=f*this.timeScale,0!==this.weight)){f=this.data.length;if(this.currentTime>f||0>this.currentTime)this.loop?(this.currentTime%=f,0>this.currentTime&&(this.currentTime+=f),this.reset()):this.stop();f=0;for(var h=this.hierarchy.length;fq;q++){var l=this.keyTypes[q],s=p.prevKey[l],t=p.nextKey[l];if(0this.timeScale&&s.time>=this.currentTime){s=this.data.hierarchy[f].keys[0];for(t=this.getNextKeyWith(l,f,1);t.times.index;)s=t,t=this.getNextKeyWith(l,f,t.index+1);p.prevKey[l]=s;p.nextKey[l]=t}var r=(this.currentTime-s.time)/(t.time-s.time),u=s[l],v=t[l];0>r&&(r=0);1a.length-2?q:q+1;c[3]=q>a.length-3?q:q+2;q=a[c[0]];t=a[c[1]];s=a[c[2]];r=a[c[3]];c=e*e;n=e*c;d[0]=f(q[0],t[0],s[0],r[0],e,c,n);d[1]=f(q[1],t[1],s[1],r[1],e,c,n);d[2]=f(q[2],t[2],s[2],r[2],e,c,n);return d},f=function(a,b,c,d,e,f,n){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*n+ +(-3*(b-c)-2*a-d)*f+a*e+b};return function(f){if(!1!==this.isPlaying&&(this.currentTime+=f*this.timeScale,0!==this.weight)){f=this.data.length;if(this.currentTime>f||0>this.currentTime)this.loop?(this.currentTime%=f,0>this.currentTime&&(this.currentTime+=f),this.reset()):this.stop();f=0;for(var h=this.hierarchy.length;fq;q++){var n=this.keyTypes[q],t=l.prevKey[n],s=l.nextKey[n];if(0this.timeScale&&t.time>=this.currentTime){t=this.data.hierarchy[f].keys[0];for(s=this.getNextKeyWith(n,f,1);s.timet.index;)t=s,s=this.getNextKeyWith(n,f,s.index+1);l.prevKey[n]=t;l.nextKey[n]=s}var r=(this.currentTime-t.time)/(s.time-t.time),u=t[n],v=s[n];0>r&&(r=0);1=this.currentTime?f.interpolate(g,this.currentTime):f.inter THREE.KeyFrameAnimation.prototype.getPrevKeyWith=function(a,b,c){b=this.data.hierarchy[b].keys;for(c=0<=c?c:c+b.length;0<=c;c--)if(b[c].hasTarget(a))return b[c];return b[b.length-1]};THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);a=this.duration/this.frames;var b=Math.floor(this.currentTime/a);b!=this.currentFrame&&(this.mesh.morphTargetInfluences[this.lastFrame]=0,this.mesh.morphTargetInfluences[this.currentFrame]= 1,this.mesh.morphTargetInfluences[b]=0,this.lastFrame=this.currentFrame,this.currentFrame=b);this.mesh.morphTargetInfluences[b]=this.currentTime%a/a;this.mesh.morphTargetInfluences[this.lastFrame]=1-this.mesh.morphTargetInfluences[b]}}}; -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,r){var u,v=h.widthSegments,x=h.heightSegments,C=e/2,w=f/2,y=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",x=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",v=h.depthSegments;var A=v+1,E=x+1,H=e/v,F=f/x,z=new THREE.Vector3;z[u]=0=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(G=a.length;0<=--G;){c=G;d=G-1;0>d&&(d=a.length-1);for(var e=0,f=s+2*n,e=0;ed?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(O=a.length;0<=--O;){c=O;d=O-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;cc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5, -a.y));return a.clone()}THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,p=0,n=a.length;ps&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));p=0;for(n=this.vertices.length;pt&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));l=0;for(p=this.vertices.length;lt;t++){d[0]=s[g[t]];d[1]=s[g[(t+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1], -face1:q,face2:void 0},n++):e[r].face2=q}d=new Float32Array(6*n);f=0;for(r in e)if(g=e[r],void 0===g.face2||.9999>k[g.face1].normal.dot(k[g.face2].normal))n=p[g.vert1],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z,n=p[g.vert2],d[f++]=n.x,d[f++]=n.y,d[f++]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype); +THREE.EdgesHelper=function(a,b){var c=void 0!==b?b:16777215,d=[0,0],e={},f=function(a,b){return a-b},g=["a","b","c"],h=new THREE.BufferGeometry,k;a.geometry instanceof THREE.BufferGeometry?(k=new THREE.Geometry,k.fromBufferGeometry(a.geometry)):k=a.geometry.clone();k.mergeVertices();k.computeFaceNormals();var l=k.vertices;k=k.faces;for(var p=0,q=0,n=k.length;qs;s++){d[0]=t[g[s]];d[1]=t[g[(s+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1], +face1:q,face2:void 0},p++):e[r].face2=q}d=new Float32Array(6*p);f=0;for(r in e)if(g=e[r],void 0===g.face2||.9999>k[g.face1].normal.dot(k[g.face2].normal))p=l[g.vert1],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z,p=l[g.vert2],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype); THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper;THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=new THREE.Geometry;c=0;for(var e=this.object.geometry.faces.length;cr;r++){d[0]=t[g[r]];d[1]=t[g[(r+1)%3]];d.sort(f);var u=d.toString();void 0===e[u]&&(q[2*n]=d[0],q[2*n+1]=d[1],e[u]=!0,n++)}d=new Float32Array(6*n);l=0;for(s=n;lr;r++)n= -k[q[2*l+r]],g=6*l+3*r,d[g+0]=n.x,d[g+1]=n.y,d[g+2]=n.z;h.addAttribute("position",new THREE.BufferAttribute(d,3))}else if(a.geometry instanceof THREE.BufferGeometry){if(void 0!==a.geometry.attributes.index){k=a.geometry.attributes.position.array;s=a.geometry.attributes.index.array;p=a.geometry.drawcalls;n=0;0===p.length&&(p=[{count:s.length,index:0,start:0}]);for(var q=new Uint32Array(2*s.length),t=0,v=p.length;tr;r++)d[0]= -g+s[l+r],d[1]=g+s[l+(r+1)%3],d.sort(f),u=d.toString(),void 0===e[u]&&(q[2*n]=d[0],q[2*n+1]=d[1],e[u]=!0,n++);d=new Float32Array(6*n);l=0;for(s=n;lr;r++)g=6*l+3*r,n=3*q[2*l+r],d[g+0]=k[n],d[g+1]=k[n+1],d[g+2]=k[n+2]}else for(k=a.geometry.attributes.position.array,n=k.length/3,q=n/3,d=new Float32Array(6*n),l=0,s=q;lr;r++)g=18*l+6*r,q=9*l+3*r,d[g+0]=k[q],d[g+1]=k[q+1],d[g+2]=k[q+2],n=9*l+(r+1)%3*3,d[g+3]=k[n],d[g+4]=k[n+1],d[g+5]=k[n+2];h.addAttribute("position",new THREE.BufferAttribute(d, +THREE.WireframeHelper=function(a,b){var c=void 0!==b?b:16777215,d=[0,0],e={},f=function(a,b){return a-b},g=["a","b","c"],h=new THREE.BufferGeometry;if(a.geometry instanceof THREE.Geometry){for(var k=a.geometry.vertices,l=a.geometry.faces,p=0,q=new Uint32Array(6*l.length),n=0,t=l.length;nr;r++){d[0]=s[g[r]];d[1]=s[g[(r+1)%3]];d.sort(f);var u=d.toString();void 0===e[u]&&(q[2*p]=d[0],q[2*p+1]=d[1],e[u]=!0,p++)}d=new Float32Array(6*p);n=0;for(t=p;nr;r++)p= +k[q[2*n+r]],g=6*n+3*r,d[g+0]=p.x,d[g+1]=p.y,d[g+2]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3))}else if(a.geometry instanceof THREE.BufferGeometry){if(void 0!==a.geometry.attributes.index){k=a.geometry.attributes.position.array;t=a.geometry.attributes.index.array;l=a.geometry.drawcalls;p=0;0===l.length&&(l=[{count:t.length,index:0,start:0}]);for(var q=new Uint32Array(2*t.length),s=0,v=l.length;sr;r++)d[0]= +g+t[n+r],d[1]=g+t[n+(r+1)%3],d.sort(f),u=d.toString(),void 0===e[u]&&(q[2*p]=d[0],q[2*p+1]=d[1],e[u]=!0,p++);d=new Float32Array(6*p);n=0;for(t=p;nr;r++)g=6*n+3*r,p=3*q[2*n+r],d[g+0]=k[p],d[g+1]=k[p+1],d[g+2]=k[p+2]}else for(k=a.geometry.attributes.position.array,p=k.length/3,q=p/3,d=new Float32Array(6*p),n=0,t=q;nr;r++)g=18*n+6*r,q=9*n+3*r,d[g+0]=k[q],d[g+1]=k[q+1],d[g+2]=k[q+2],p=9*n+(r+1)%3*3,d[g+3]=k[p],d[g+4]=k[p+1],d[g+5]=k[p+2];h.addAttribute("position",new THREE.BufferAttribute(d, 3))}THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.WireframeHelper.prototype=Object.create(THREE.Line.prototype);THREE.WireframeHelper.prototype.constructor=THREE.WireframeHelper;THREE.ImmediateRenderObject=function(){THREE.Object3D.call(this);this.render=function(a){}};THREE.ImmediateRenderObject.prototype=Object.create(THREE.Object3D.prototype);THREE.ImmediateRenderObject.prototype.constructor=THREE.ImmediateRenderObject; THREE.MorphBlendMesh=function(a,b){THREE.Mesh.call(this,a,b);this.animationsMap={};this.animationsList=[];var c=this.geometry.morphTargets.length;this.createAnimation("__default",0,c-1,c/1);this.setAnimationWeight("__default",1)};THREE.MorphBlendMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.MorphBlendMesh.prototype.constructor=THREE.MorphBlendMesh; THREE.MorphBlendMesh.prototype.createAnimation=function(a,b,c,d){b={startFrame:b,endFrame:c,length:c-b+1,fps:d,duration:(c-b)/d,lastFrame:0,currentFrame:0,active:!1,time:0,direction:1,weight:1,directionBackwards:!1,mirroredLoop:!1};this.animationsMap[a]=b;this.animationsList.push(b)}; From a0ee6bc7a10dbe826f664162c0393a51d73dc319 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 19:23:34 -0800 Subject: [PATCH 186/333] WebGLRenderer: Rescued Line pixelRatio. --- src/renderers/WebGLRenderer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index a3ca313cd5dbc1..9e20361669fd31 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2704,7 +2704,7 @@ THREE.WebGLRenderer = function ( parameters ) { var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - state.setLineWidth( material.linewidth ); + state.setLineWidth( material.linewidth * pixelRatio ); var index = geometry.attributes.index; @@ -3018,7 +3018,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material.wireframe ) { - state.setLineWidth( material.wireframeLinewidth ); + state.setLineWidth( material.wireframeLinewidth * pixelRatio ); if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer ); _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, type, 0 ); @@ -3042,7 +3042,7 @@ THREE.WebGLRenderer = function ( parameters ) { var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - state.setLineWidth( material.linewidth ); + state.setLineWidth( material.linewidth * pixelRatio ); _gl.drawArrays( mode, 0, geometryGroup.__webglLineCount ); From b15c13cf6a002b25b549a4d9d312680db9a0891b Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 19:28:56 -0800 Subject: [PATCH 187/333] WebGLState: -1 to null. --- src/renderers/webgl/WebGLState.js | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index 53f409bb01da19..2a706d2b84e3e1 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -7,19 +7,19 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { var newAttributes = new Uint8Array( 16 ); var enabledAttributes = new Uint8Array( 16 ); - var currentBlending = - 1; - var currentBlendEquation = - 1; - var currentBlendSrc = - 1; - var currentBlendDst = - 1; - var currentBlendEquationAlpha = - 1; - var currentBlendSrcAlpha = - 1; - var currentBlendDstAlpha = - 1; + var currentBlending = null; + var currentBlendEquation = null; + var currentBlendSrc = null; + var currentBlendDst = null; + var currentBlendEquationAlpha = null; + var currentBlendSrcAlpha = null; + var currentBlendDstAlpha = null; - var currentDepthTest = - 1; - var currentDepthWrite = - 1; + var currentDepthTest = null; + var currentDepthWrite = null; - var currentDoubleSided = - 1; - var currentFlipSided = - 1; + var currentDoubleSided = null; + var currentFlipSided = null; var currentLineWidth = null; @@ -268,11 +268,11 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { } - currentBlending = - 1; - currentDepthTest = - 1; - currentDepthWrite = - 1; - currentDoubleSided = - 1; - currentFlipSided = - 1; + currentBlending = null; + currentDepthTest = null; + currentDepthWrite = null; + currentDoubleSided = null; + currentFlipSided = null; }; From a0a155ee820e24bdda822fc42036b4138ffc81c2 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 19 Feb 2015 19:29:34 -0800 Subject: [PATCH 188/333] Updated builds. --- build/three.js | 38 +++++++-------- build/three.min.js | 112 ++++++++++++++++++++++----------------------- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/build/three.js b/build/three.js index 95c81887d1af5c..02873eaee2e201 100644 --- a/build/three.js +++ b/build/three.js @@ -20415,7 +20415,7 @@ THREE.WebGLRenderer = function ( parameters ) { var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - state.setLineWidth( material.linewidth ); + state.setLineWidth( material.linewidth * pixelRatio ); var index = geometry.attributes.index; @@ -20729,7 +20729,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material.wireframe ) { - state.setLineWidth( material.wireframeLinewidth ); + state.setLineWidth( material.wireframeLinewidth * pixelRatio ); if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer ); _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, type, 0 ); @@ -20753,7 +20753,7 @@ THREE.WebGLRenderer = function ( parameters ) { var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - state.setLineWidth( material.linewidth ); + state.setLineWidth( material.linewidth * pixelRatio ); _gl.drawArrays( mode, 0, geometryGroup.__webglLineCount ); @@ -24618,19 +24618,19 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { var newAttributes = new Uint8Array( 16 ); var enabledAttributes = new Uint8Array( 16 ); - var currentBlending = - 1; - var currentBlendEquation = - 1; - var currentBlendSrc = - 1; - var currentBlendDst = - 1; - var currentBlendEquationAlpha = - 1; - var currentBlendSrcAlpha = - 1; - var currentBlendDstAlpha = - 1; + var currentBlending = null; + var currentBlendEquation = null; + var currentBlendSrc = null; + var currentBlendDst = null; + var currentBlendEquationAlpha = null; + var currentBlendSrcAlpha = null; + var currentBlendDstAlpha = null; - var currentDepthTest = - 1; - var currentDepthWrite = - 1; + var currentDepthTest = null; + var currentDepthWrite = null; - var currentDoubleSided = - 1; - var currentFlipSided = - 1; + var currentDoubleSided = null; + var currentFlipSided = null; var currentLineWidth = null; @@ -24879,11 +24879,11 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { } - currentBlending = - 1; - currentDepthTest = - 1; - currentDepthWrite = - 1; - currentDoubleSided = - 1; - currentFlipSided = - 1; + currentBlending = null; + currentDepthTest = null; + currentDepthWrite = null; + currentDoubleSided = null; + currentFlipSided = null; }; diff --git a/build/three.min.js b/build/three.min.js index 82beae00acff75..6c7eff1ff43fdd 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -101,8 +101,8 @@ l=c*h,p=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=k+l*d;b[5]=a-p*d;b[9]=-c*g;b[2]=p-a*d a.order?(a=f*g,k=f*d,l=c*g,p=c*d,b[0]=g*h,b[4]=p-a*e,b[8]=l*e+k,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=k*e+l,b[10]=a-p*e):"XZY"===a.order&&(a=f*g,k=f*d,l=c*g,p=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+p,b[5]=f*h,b[9]=k*e-l,b[2]=l*e-k,b[6]=c*h,b[10]=p*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},setRotationFromQuaternion:function(a){THREE.warn("THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().");return this.makeRotationFromQuaternion(a)}, makeRotationFromQuaternion:function(a){var b=this.elements,c=a.x,d=a.y,e=a.z,f=a.w,g=c+c,h=d+d,k=e+e;a=c*g;var l=c*h,c=c*k,p=d*h,d=d*k,e=e*k,g=f*g,h=f*h,f=f*k;b[0]=1-(p+e);b[4]=l-f;b[8]=c+h;b[1]=l+f;b[5]=1-(a+e);b[9]=d-g;b[2]=c-h;b[6]=d+g;b[10]=1-(a+p);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},lookAt:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,f){var g=this.elements;c.subVectors(d,e).normalize();0===c.length()&&(c.z=1);a.crossVectors(f, c).normalize();0===a.length()&&(c.x+=1E-4,a.crossVectors(f,c).normalize());b.crossVectors(c,a);g[0]=a.x;g[4]=b.x;g[8]=c.x;g[1]=a.y;g[5]=b.y;g[9]=c.y;g[2]=a.z;g[6]=b.z;g[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(THREE.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements,e=this.elements,f=c[0],g=c[4],h=c[8], -k=c[12],l=c[1],p=c[5],q=c[9],n=c[13],t=c[2],s=c[6],r=c[10],u=c[14],v=c[3],x=c[7],F=c[11],c=c[15],w=d[0],y=d[4],A=d[8],E=d[12],G=d[1],z=d[5],D=d[9],H=d[13],U=d[2],M=d[6],I=d[10],L=d[14],P=d[3],N=d[7],R=d[11],d=d[15];e[0]=f*w+g*G+h*U+k*P;e[4]=f*y+g*z+h*M+k*N;e[8]=f*A+g*D+h*I+k*R;e[12]=f*E+g*H+h*L+k*d;e[1]=l*w+p*G+q*U+n*P;e[5]=l*y+p*z+q*M+n*N;e[9]=l*A+p*D+q*I+n*R;e[13]=l*E+p*H+q*L+n*d;e[2]=t*w+s*G+r*U+u*P;e[6]=t*y+s*z+r*M+u*N;e[10]=t*A+s*D+r*I+u*R;e[14]=t*E+s*H+r*L+u*d;e[3]=v*w+x*G+F*U+c*P;e[7]=v*y+ -x*z+F*M+c*N;e[11]=v*A+x*D+F*I+c*R;e[15]=v*E+x*H+F*L+c*d;return this},multiplyToArray:function(a,b,c){var d=this.elements;this.multiplyMatrices(a,b);c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[5]=d[5];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[11]=d[11];c[12]=d[12];c[13]=d[13];c[14]=d[14];c[15]=d[15];return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*= +k=c[12],l=c[1],p=c[5],q=c[9],n=c[13],t=c[2],s=c[6],r=c[10],u=c[14],v=c[3],x=c[7],F=c[11],c=c[15],w=d[0],y=d[4],A=d[8],E=d[12],G=d[1],z=d[5],D=d[9],I=d[13],U=d[2],M=d[6],H=d[10],L=d[14],P=d[3],N=d[7],R=d[11],d=d[15];e[0]=f*w+g*G+h*U+k*P;e[4]=f*y+g*z+h*M+k*N;e[8]=f*A+g*D+h*H+k*R;e[12]=f*E+g*I+h*L+k*d;e[1]=l*w+p*G+q*U+n*P;e[5]=l*y+p*z+q*M+n*N;e[9]=l*A+p*D+q*H+n*R;e[13]=l*E+p*I+q*L+n*d;e[2]=t*w+s*G+r*U+u*P;e[6]=t*y+s*z+r*M+u*N;e[10]=t*A+s*D+r*H+u*R;e[14]=t*E+s*I+r*L+u*d;e[3]=v*w+x*G+F*U+c*P;e[7]=v*y+ +x*z+F*M+c*N;e[11]=v*A+x*D+F*H+c*R;e[15]=v*E+x*I+F*L+c*d;return this},multiplyToArray:function(a,b,c){var d=this.elements;this.multiplyMatrices(a,b);c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[5]=d[5];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[11]=d[11];c[12]=d[12];c[13]=d[13];c[14]=d[14];c[15]=d[15];return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*= a;b[15]*=a;return this},multiplyVector3:function(a){THREE.warn("THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.");return a.applyProjection(this)},multiplyVector4:function(a){THREE.warn("THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)},multiplyVector3Array:function(a){THREE.warn("THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead."); return this.applyToVector3Array(a)},applyToVector3Array:function(){var a=new THREE.Vector3;return function(b,c,d){void 0===c&&(c=0);void 0===d&&(d=b.length);for(var e=0;eqa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hY;Y++)pa=H[Y],Na[Ra]=pa.x,Na[Ra+1]=pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=I.x,Na[Ra+1]=I.y,Na[Ra+2]=I.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER, +V=P[1],W=P[2],sa[Aa]=Ka.x,sa[Aa+1]=Ka.y,sa[Aa+2]=Ka.z,sa[Aa+3]=Ka.w,sa[Aa+4]=V.x,sa[Aa+5]=V.y,sa[Aa+6]=V.z,sa[Aa+7]=V.w,sa[Aa+8]=W.x,sa[Aa+9]=W.y,sa[Aa+10]=W.z,sa[Aa+11]=W.w,Aa+=12;m.bindBuffer(m.ARRAY_BUFFER,w.__webglTangentBuffer);m.bufferData(m.ARRAY_BUFFER,sa,x)}if(Mb){y=0;for(z=$.length;yY;Y++)pa=I[Y],Na[Ra]=pa.x,Na[Ra+1]=pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=H.x,Na[Ra+1]=H.y,Na[Ra+2]=H.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER, w.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Na,x)}if(vb&&Hb){y=0;for(z=$.length;yY;Y++)ab=U[Y],Ab[kb]=ab.x,Ab[kb+1]=ab.y,kb+=2;0Y;Y++)oa=O[Y],lb[yb]=oa.x,lb[yb+1]=oa.y,yb+=2;0ya;ya++)gb[ya]=!B.autoScaleCubemaps||Rb||Ib?Ib?X.image[ya].image:X.image[ya]:E(X.image[ya],qc);var Yb=gb[0],Zb=THREE.Math.isPowerOfTwo(Yb.width)&&THREE.Math.isPowerOfTwo(Yb.height),Wa=H(X.format),tb=H(X.type);A(m.TEXTURE_CUBE_MAP,X,Zb);for(ya=0;6>ya;ya++)if(Rb)for(var hb,$b=gb[ya].mipmaps,Fb= +m.bindTexture(m.TEXTURE_CUBE_MAP,X.image.__webglTextureCube);m.pixelStorei(m.UNPACK_FLIP_Y_WEBGL,X.flipY);for(var Rb=X instanceof THREE.CompressedTexture,Ib=X.image[0]instanceof THREE.DataTexture,gb=[],ya=0;6>ya;ya++)gb[ya]=!B.autoScaleCubemaps||Rb||Ib?Ib?X.image[ya].image:X.image[ya]:E(X.image[ya],qc);var Yb=gb[0],Zb=THREE.Math.isPowerOfTwo(Yb.width)&&THREE.Math.isPowerOfTwo(Yb.height),Wa=I(X.format),tb=I(X.type);A(m.TEXTURE_CUBE_MAP,X,Zb);for(ya=0;6>ya;ya++)if(Rb)for(var hb,$b=gb[ya].mipmaps,Fb= 0,Sb=$b.length;Fb=Wb&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Wb);Mb+=1;return a}function w(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function y(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,H(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,H(b.wrapT)),m.texParameteri(a, -m.TEXTURE_MAG_FILTER,H(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,H(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,D(b.magFilter)),m.texParameteri(a, +b;a.hemisphereLightDirection.needsUpdate=b}function F(){var a=Mb;a>=Wb&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Wb);Mb+=1;return a}function w(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function y(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,I(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,I(b.wrapT)),m.texParameteri(a, +m.TEXTURE_MAG_FILTER,I(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,I(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,D(b.magFilter)),m.texParameteri(a, m.TEXTURE_MIN_FILTER,D(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=da.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function G(a,b){m.bindRenderbuffer(m.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer? (m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_COMPONENT16,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_STENCIL,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a)):m.renderbufferStorage(m.RENDERBUFFER,m.RGBA4,b.width,b.height)}function z(a){a instanceof THREE.WebGLRenderTargetCube?(m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture), -m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function D(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function H(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT; +m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function D(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function I(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT; if(a===THREE.NearestFilter)return m.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return m.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return m.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return m.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return m.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return m.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return m.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return m.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return m.UNSIGNED_SHORT_5_5_5_1; if(a===THREE.UnsignedShort565Type)return m.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return m.BYTE;if(a===THREE.ShortType)return m.SHORT;if(a===THREE.UnsignedShortType)return m.UNSIGNED_SHORT;if(a===THREE.IntType)return m.INT;if(a===THREE.UnsignedIntType)return m.UNSIGNED_INT;if(a===THREE.FloatType)return m.FLOAT;b=da.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return m.ALPHA;if(a===THREE.RGBFormat)return m.RGB;if(a===THREE.RGBAFormat)return m.RGBA; if(a===THREE.LuminanceFormat)return m.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return m.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return m.FUNC_ADD;if(a===THREE.SubtractEquation)return m.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return m.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return m.ZERO;if(a===THREE.OneFactor)return m.ONE;if(a===THREE.SrcColorFactor)return m.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return m.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return m.SRC_ALPHA; if(a===THREE.OneMinusSrcAlphaFactor)return m.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return m.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return m.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return m.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return m.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return m.SRC_ALPHA_SATURATE;b=da.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT; if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=da.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b= -da.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var U=void 0!==a.canvas?a.canvas:document.createElement("canvas"),M=void 0!==a.context?a.context:null,I=1,L=void 0!==a.precision?a.precision:"highp",P=void 0!==a.alpha?a.alpha:!1,N=void 0!==a.depth?a.depth:!0,R=void 0!==a.stencil?a.stencil:!0,V=void 0!==a.antialias?a.antialias:!1,J=void 0!==a.premultipliedAlpha? +da.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var U=void 0!==a.canvas?a.canvas:document.createElement("canvas"),M=void 0!==a.context?a.context:null,H=1,L=void 0!==a.precision?a.precision:"highp",P=void 0!==a.alpha?a.alpha:!1,N=void 0!==a.depth?a.depth:!0,R=void 0!==a.stencil?a.stencil:!0,V=void 0!==a.antialias?a.antialias:!1,J=void 0!==a.premultipliedAlpha? a.premultipliedAlpha:!0,oa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,ja=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ha=new THREE.Color(0),O=0,ca=[],ba={},qa=[],Ka=[],Qa=[],Xa=[],Ya=[];this.domElement=U;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront; this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,Pa=[],ob=null,ab=null,ub=-1,ta="",vb=null,Mb=0,ib=0,bb=0,pb=U.width,qb=U.height,Xb=0,fc=0,cb=new THREE.Frustum,db=new THREE.Matrix4;new THREE.Matrix4;var wa=new THREE.Vector3,pa=new THREE.Vector3,Ob=!0,jc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0, colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},m;try{var Yb={alpha:P,depth:N,stencil:R,antialias:V,premultipliedAlpha:J,preserveDrawingBuffer:oa};m=M||U.getContext("webgl",Yb)||U.getContext("experimental-webgl",Yb);if(null===m){if(null!==U.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context."; -}U.addEventListener("webglcontextlost",function(a){a.preventDefault();Zb();lc();ba={}},!1)}catch(rc){THREE.error("THREE.WebGLRenderer: "+rc)}var W=new THREE.WebGLState(m,H);void 0===m.getShaderPrecisionFormat&&(m.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var da=new THREE.WebGLExtensions(m);da.get("OES_texture_float");da.get("OES_texture_float_linear");da.get("OES_texture_half_float");da.get("OES_texture_half_float_linear");da.get("OES_standard_derivatives");ja&& +}U.addEventListener("webglcontextlost",function(a){a.preventDefault();Zb();lc();ba={}},!1)}catch(rc){THREE.error("THREE.WebGLRenderer: "+rc)}var W=new THREE.WebGLState(m,I);void 0===m.getShaderPrecisionFormat&&(m.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var da=new THREE.WebGLExtensions(m);da.get("OES_texture_float");da.get("OES_texture_float_linear");da.get("OES_texture_half_float");da.get("OES_texture_half_float_linear");da.get("OES_standard_derivatives");ja&& da.get("EXT_frag_depth");var rb=function(a,b,c,d){!0===J&&(a*=d,b*=d,c*=d);m.clearColor(a,b,c,d)},lc=function(){m.clearColor(0,0,0,1);m.clearDepth(1);m.clearStencil(0);m.enable(m.DEPTH_TEST);m.depthFunc(m.LEQUAL);m.frontFace(m.CCW);m.cullFace(m.BACK);m.enable(m.CULL_FACE);m.enable(m.BLEND);m.blendEquation(m.FUNC_ADD);m.blendFunc(m.SRC_ALPHA,m.ONE_MINUS_SRC_ALPHA);m.viewport(ib,bb,pb,qb);rb(ha.r,ha.g,ha.b,O)},Zb=function(){vb=ob=null;ta="";ub=-1;Ob=!0;W.reset()};lc();this.context=m;this.state=W;var Wb= m.getParameter(m.MAX_TEXTURE_IMAGE_UNITS),sc=m.getParameter(m.MAX_VERTEX_TEXTURE_IMAGE_UNITS),tc=m.getParameter(m.MAX_TEXTURE_SIZE),qc=m.getParameter(m.MAX_CUBE_MAP_TEXTURE_SIZE),Vb=0f;f++){a.__webglFramebuffer[f]= +THREE.WebGLRenderTargetCube;if(a&&void 0===a.__webglFramebuffer){void 0===a.depthBuffer&&(a.depthBuffer=!0);void 0===a.stencilBuffer&&(a.stencilBuffer=!0);a.addEventListener("dispose",oc);a.__webglTexture=m.createTexture();B.info.memory.textures++;var c=THREE.Math.isPowerOfTwo(a.width)&&THREE.Math.isPowerOfTwo(a.height),d=I(a.format),e=I(a.type);if(b){a.__webglFramebuffer=[];a.__webglRenderbuffer=[];m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture);A(m.TEXTURE_CUBE_MAP,a,c);for(var f=0;6>f;f++){a.__webglFramebuffer[f]= m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,h,g.__webglTexture,0);G(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: m.createRenderbuffer(),m.bindTexture(m.TEXTURE_2D,a.__webglTexture),A(m.TEXTURE_2D,a,c),m.texImage2D(m.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=m.TEXTURE_2D,m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&m.framebufferRenderbuffer(m.FRAMEBUFFER, m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):G(a.__webglRenderbuffer,a),c&&m.generateMipmap(m.TEXTURE_2D);b?m.bindTexture(m.TEXTURE_CUBE_MAP,null):m.bindTexture(m.TEXTURE_2D,null);m.bindRenderbuffer(m.RENDERBUFFER,null);m.bindFramebuffer(m.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=pb,a=qb,d=ib,e=bb);b!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,b),m.viewport(d,e,c,a),ab=b);Xb=c;fc=a};this.readRenderTargetPixels= @@ -588,39 +588,39 @@ p);void 0!==q&&f.bindAttribLocation(g,0,q);f.linkProgram(g);q=f.getProgramInfoLo e.useVertexTexture?(q.push("boneTexture"),q.push("boneTextureWidth"),q.push("boneTextureHeight")):q.push("boneGlobalMatrices");e.logarithmicDepthBuffer&&q.push("logDepthBufFC");for(var w in h)q.push(w);h=q;w={};q=0;for(b=h.length;qL;L++)H[L]=new THREE.Vector3,z[L]=new THREE.Vector3;H=D.shadowCascadeNearZ[I];D=D.shadowCascadeFarZ[I];z[0].set(-1,-1,H);z[1].set(1,-1,H);z[2].set(-1,1,H);z[3].set(1,1,H);z[4].set(-1,-1,D);z[5].set(1,-1,D);z[6].set(-1,1,D);z[7].set(1,1,D);M.originalCamera=u;z=new THREE.Gyroscope;z.position.copy(A.shadowCascadeOffset);z.add(M);z.add(M.target);u.add(z);A.shadowCascadeArray[G]=M}I=A;H=G;D=I.shadowCascadeArray[H];D.position.copy(I.position); -D.target.position.copy(I.target.position);D.lookAt(D.target);D.shadowCameraVisible=I.shadowCameraVisible;D.shadowDarkness=I.shadowDarkness;D.shadowBias=I.shadowCascadeBias[H];z=I.shadowCascadeNearZ[H];I=I.shadowCascadeFarZ[H];D=D.pointsFrustum;D[0].z=z;D[1].z=z;D[2].z=z;D[3].z=z;D[4].z=I;D[5].z=I;D[6].z=I;D[7].z=I;U[E]=M;E++}else U[E]=A,E++;v=0;for(y=U.length;vL;L++)I[L]=new THREE.Vector3,z[L]=new THREE.Vector3;I=D.shadowCascadeNearZ[H];D=D.shadowCascadeFarZ[H];z[0].set(-1,-1,I);z[1].set(1,-1,I);z[2].set(-1,1,I);z[3].set(1,1,I);z[4].set(-1,-1,D);z[5].set(1,-1,D);z[6].set(-1,1,D);z[7].set(1,1,D);M.originalCamera=u;z=new THREE.Gyroscope;z.position.copy(A.shadowCascadeOffset);z.add(M);z.add(M.target);u.add(z);A.shadowCascadeArray[G]=M}H=A;I=G;D=H.shadowCascadeArray[I];D.position.copy(H.position); +D.target.position.copy(H.target.position);D.lookAt(D.target);D.shadowCameraVisible=H.shadowCameraVisible;D.shadowDarkness=H.shadowDarkness;D.shadowBias=H.shadowCascadeBias[I];z=H.shadowCascadeNearZ[I];H=H.shadowCascadeFarZ[I];D=D.pointsFrustum;D[0].z=z;D[1].z=z;D[2].z=z;D[3].z=z;D[4].z=H;D[5].z=H;D[6].z=H;D[7].z=H;U[E]=M;E++}else U[E]=A,E++;v=0;for(y=U.length;v -I;I++)H=D[I],H.copy(z[I]),H.unproject(G),H.applyMatrix4(E.matrixWorldInverse),H.xt.x&&(t.x=H.x),H.yt.y&&(t.y=H.y),H.zt.z&&(t.z=H.z);E.left=n.x;E.right=t.x;E.top=t.y;E.bottom=n.y;E.updateProjectionMatrix()}E=A.shadowMap;z=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);s.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(s);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& -(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();z.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);z.multiply(G.projectionMatrix);z.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(E);a.clear();r.length=0;e(c,c,G);A=0;for(E=r.length;A +H;H++)I=D[H],I.copy(z[H]),I.unproject(G),I.applyMatrix4(E.matrixWorldInverse),I.xt.x&&(t.x=I.x),I.yt.y&&(t.y=I.y),I.zt.z&&(t.z=I.z);E.left=n.x;E.right=t.x;E.top=t.y;E.bottom=n.y;E.updateProjectionMatrix()}E=A.shadowMap;z=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);s.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(s);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& +(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();z.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);z.multiply(G.projectionMatrix);z.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(E);a.clear();r.length=0;e(c,c,G);A=0;for(E=r.length;A 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); -w.compileShader(L);w.compileShader(P);w.attachShader(I,L);w.attachShader(I,P);w.linkProgram(I);E=I;v=w.getAttribLocation(E,"position");x=w.getAttribLocation(E,"uv");c=w.getUniformLocation(E,"uvOffset");d=w.getUniformLocation(E,"uvScale");e=w.getUniformLocation(E,"rotation");f=w.getUniformLocation(E,"scale");g=w.getUniformLocation(E,"color");h=w.getUniformLocation(E,"map");k=w.getUniformLocation(E,"opacity");l=w.getUniformLocation(E,"modelViewMatrix");p=w.getUniformLocation(E,"projectionMatrix");q= -w.getUniformLocation(E,"fogType");n=w.getUniformLocation(E,"fogDensity");t=w.getUniformLocation(E,"fogNear");s=w.getUniformLocation(E,"fogFar");r=w.getUniformLocation(E,"fogColor");u=w.getUniformLocation(E,"alphaTest");I=document.createElement("canvas");I.width=8;I.height=8;L=I.getContext("2d");L.fillStyle="white";L.fillRect(0,0,8,8);G=new THREE.Texture(I);G.needsUpdate=!0}w.useProgram(E);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, -y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(p,!1,M.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);L=I=0;(P=U.fog)?(w.uniform3f(r,P.color.r,P.color.g,P.color.b),P instanceof THREE.Fog?(w.uniform1f(t,P.near),w.uniform1f(s,P.far),w.uniform1i(q,1),L=I=1):P instanceof THREE.FogExp2&&(w.uniform1f(n,P.density),w.uniform1i(q,2),L=I=2)):(w.uniform1i(q,0),L=I=0);for(var P=0,N=b.length;P< -N;P++){var R=b[P];R._modelViewMatrix.multiplyMatrices(M.matrixWorldInverse,R.matrixWorld);R.z=-R._modelViewMatrix.elements[14]}b.sort(F);for(var V=[],P=0,N=b.length;Pe)return null;var f=[],g=[],h=[],k,l,p;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=l;e<=k&&(k=0);l=k+1;e<=l&&(l=0);p=l+1;e<=p&&(p=0);var n;a:{var t=n=void 0,s=void 0,r=void 0, -u=void 0,v=void 0,x=void 0,F=void 0,w=void 0,t=a[g[k]].x,s=a[g[k]].y,r=a[g[l]].x,u=a[g[l]].y,v=a[g[p]].x,x=a[g[p]].y;if(1E-10>(r-t)*(x-s)-(u-s)*(v-t))n=!1;else{var y=void 0,A=void 0,E=void 0,G=void 0,z=void 0,D=void 0,H=void 0,U=void 0,M=void 0,I=void 0,M=U=H=w=F=void 0,y=v-r,A=x-u,E=t-v,G=s-x,z=r-t,D=u-s;for(n=0;n(r-t)*(x-s)-(u-s)*(v-t))n=!1;else{var y=void 0,A=void 0,E=void 0,G=void 0,z=void 0,D=void 0,I=void 0,U=void 0,M=void 0,H=void 0,M=U=I=w=F=void 0,y=v-r,A=x-u,E=t-v,G=s-x,z=r-t,D=u-s;for(n=0;nG||G>E)return[];k=l*p-k*q;if(0>k||k>E)return[]}else{if(0d?[]:k==d?f?[]:[g]:a<=d?[g,h]: [g,l]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]); -if(!d)return!1;d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c -I){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(q=D;qf&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c +H){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(q=D;qh;h++)l=k[h].x+":"+k[h].y,l=p[l],void 0!==l&&(k[h]=l);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a* a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)}; THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()};THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve; @@ -715,7 +715,7 @@ f;d.nextKey=g}g.time>=this.currentTime?f.interpolate(g,this.currentTime):f.inter THREE.KeyFrameAnimation.prototype.getPrevKeyWith=function(a,b,c){b=this.data.hierarchy[b].keys;for(c=0<=c?c:c+b.length;0<=c;c--)if(b[c].hasTarget(a))return b[c];return b[b.length-1]};THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);a=this.duration/this.frames;var b=Math.floor(this.currentTime/a);b!=this.currentFrame&&(this.mesh.morphTargetInfluences[this.lastFrame]=0,this.mesh.morphTargetInfluences[this.currentFrame]= 1,this.mesh.morphTargetInfluences[b]=0,this.lastFrame=this.currentFrame,this.currentFrame=b);this.mesh.morphTargetInfluences[b]=this.currentTime%a/a;this.mesh.morphTargetInfluences[this.lastFrame]=1-this.mesh.morphTargetInfluences[b]}}}; -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,r){var u,v=h.widthSegments,x=h.heightSegments,F=e/2,w=f/2,y=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",x=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",v=h.depthSegments;var A=v+1,E=x+1,G=e/v,z=f/x,D=new THREE.Vector3;D[u]=0=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(O=a.length;0<=--O;){c=O;d=O-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;ed?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(O=a.length;0<=--O;){c=O;d=O-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;c Date: Fri, 20 Feb 2015 08:12:16 -0800 Subject: [PATCH 189/333] Fix EffectComposer reference to renderer. should be `this.renderer` --- examples/js/postprocessing/EffectComposer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/postprocessing/EffectComposer.js b/examples/js/postprocessing/EffectComposer.js index b675b7cb489c58..55a4702406d95a 100644 --- a/examples/js/postprocessing/EffectComposer.js +++ b/examples/js/postprocessing/EffectComposer.js @@ -110,7 +110,7 @@ THREE.EffectComposer.prototype = { renderTarget = this.renderTarget1.clone(); - var pixelRatio = renderer.getPixelRatio(); + var pixelRatio = this.renderer.getPixelRatio(); renderTarget.width = Math.floor( this.renderer.context.canvas.width / pixelRatio ); renderTarget.height = Math.floor( this.renderer.context.canvas.height / pixelRatio ); From 0eb4905fb60d9edc5b3ebd43465aa9b6c4c50245 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 20 Feb 2015 13:18:19 -0800 Subject: [PATCH 190/333] Editor: Published project now listens to window resize. --- editor/js/Menubar.File.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/editor/js/Menubar.File.js b/editor/js/Menubar.File.js index bfd4d48dbaea10..cef2075803bb6a 100644 --- a/editor/js/Menubar.File.js +++ b/editor/js/Menubar.File.js @@ -217,6 +217,10 @@ Menubar.File = function ( editor ) { '', ' document.body.appendChild( player.dom );', '', + ' window.addEventListener( \'resize\', function () {', + ' player.setSize( window.innerWidth, window.innerHeight );', + ' } );', + '', ' } );', '', ' ', From c223a4c4bd04cdb7f4fbad339187eea36b4fe857 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 20 Feb 2015 14:56:03 -0800 Subject: [PATCH 191/333] ObjectLoader: Handle empty json.image case. See b3b9d8bfdf78bbb832db5a50010e82a5ce6f1c43. --- src/loaders/ObjectLoader.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index d6f289077c8383..054af49d7d617e 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -48,15 +48,17 @@ THREE.ObjectLoader.prototype = { var geometries = this.parseGeometries( json.geometries ); - var images = this.parseImages( json.images, function () { - - if ( onLoad !== undefined ) onLoad( object ); - - } ); + var images = this.parseImages( json.images, onLoad ); var textures = this.parseTextures( json.textures, images ); var materials = this.parseMaterials( json.materials, textures ); var object = this.parseObject( json.object, geometries, materials ); + if ( json.images === undefined || json.images.length === 0 ) { + + if ( onLoad !== undefined ) onLoad( object ); + + } + return object; }, @@ -314,10 +316,6 @@ THREE.ObjectLoader.prototype = { } - } else { - - if ( onLoad !== undefined ) onLoad(); - } return images; From 589819d4f36277bc3942fc9bc5813aed583bce62 Mon Sep 17 00:00:00 2001 From: daron1337 Date: Mon, 23 Feb 2015 12:00:38 +0100 Subject: [PATCH 192/333] TrackballControls with new rotation mode --- examples/js/controls/TrackballControls.js | 205 ++++------------------ examples/misc_controls_trackball.html | 15 +- 2 files changed, 38 insertions(+), 182 deletions(-) diff --git a/examples/js/controls/TrackballControls.js b/examples/js/controls/TrackballControls.js index 241df9a8ee27df..4525da14a1d3e5 100644 --- a/examples/js/controls/TrackballControls.js +++ b/examples/js/controls/TrackballControls.js @@ -26,11 +26,9 @@ THREE.TrackballControls = function ( object, domElement ) { this.noRotate = false; this.noZoom = false; this.noPan = false; - this.noRoll = false; this.staticMoving = false; this.dynamicDampingFactor = 0.2; - this.cylindricalRotation = true; this.minDistance = 0; this.maxDistance = Infinity; @@ -50,9 +48,6 @@ THREE.TrackballControls = function ( object, domElement ) { _eye = new THREE.Vector3(), - _rotateStart = new THREE.Vector3(), - _rotateEnd = new THREE.Vector3(), - _movePrev = new THREE.Vector2(), _moveCurr = new THREE.Vector2(), @@ -141,7 +136,7 @@ THREE.TrackballControls = function ( object, domElement ) { vector.set( ( ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / ( _this.screen.width * 0.5 ) ), - ( ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / ( _this.screen.height * 0.5 ) / _this.screen.width * _this.screen.height ) + ( ( _this.screen.height + 2 * ( _this.screen.top - pageY ) ) / _this.screen.width ) // screen.width intentional ); return vector; @@ -149,56 +144,6 @@ THREE.TrackballControls = function ( object, domElement ) { }() ); - var getMouseProjectionOnBall = ( function () { - - var vector = new THREE.Vector3(); - var objectUp = new THREE.Vector3(); - var mouseOnBall = new THREE.Vector3(); - - return function ( pageX, pageY ) { - - mouseOnBall.set( - ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / ( _this.screen.width * 0.5 ), - ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / ( _this.screen.height * 0.5 ), - 0.0 - ); - - var length = mouseOnBall.length(); - - if ( _this.noRoll ) { - - if ( length < Math.SQRT1_2 ) { - - mouseOnBall.z = Math.sqrt( 1.0 - length * length ); - - } else { - - mouseOnBall.z = 0.5 / length; - - } - - } else if ( length > 1.0 ) { - - mouseOnBall.normalize(); - - } else { - - mouseOnBall.z = Math.sqrt( 1.0 - length * length ); - - } - - _eye.copy( _this.object.position ).sub( _this.target ); - - vector.copy( _this.object.up ).setLength( mouseOnBall.y ); - vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) ); - vector.add( _eye.setLength( mouseOnBall.z ) ); - - return vector; - - }; - - }() ); - this.rotateCamera = (function() { var axis = new THREE.Vector3(), @@ -211,80 +156,47 @@ THREE.TrackballControls = function ( object, domElement ) { return function () { - if ( _this.cylindricalRotation ) { - - moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 ); - angle = moveDirection.length(); - - if ( angle ) { - - _eye.copy( _this.object.position ).sub( _this.target ); - - eyeDirection.copy( _eye ).normalize(); - objectUpDirection.copy( _this.object.up ).normalize(); - objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize(); - - objectUpDirection.setLength( _moveCurr.y - _movePrev.y ); - objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x ); - - moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) ); - - axis.crossVectors( moveDirection, _eye ).normalize(); - - angle *= _this.rotateSpeed; - quaternion.setFromAxisAngle( axis, angle ); - - _eye.applyQuaternion( quaternion ); - _this.object.up.applyQuaternion( quaternion ); - - _lastAxis.copy( axis ); - _lastAngle = angle; - - } - else if ( !_this.staticMoving && _lastAngle ) { - - _lastAngle *= Math.sqrt( 1.0 - _this.dynamicDampingFactor ); - _eye.copy( _this.object.position ).sub( _this.target ); - quaternion.setFromAxisAngle( _lastAxis, _lastAngle ); - _eye.applyQuaternion( quaternion ); - _this.object.up.applyQuaternion( quaternion ); - - } - - _movePrev.copy( _moveCurr ); - - } else { - - angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() ); + moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 ); + angle = moveDirection.length(); - if ( angle ) { + if ( angle ) { - axis.crossVectors( _rotateStart, _rotateEnd ).normalize(); + _eye.copy( _this.object.position ).sub( _this.target ); - angle *= _this.rotateSpeed; + eyeDirection.copy( _eye ).normalize(); + objectUpDirection.copy( _this.object.up ).normalize(); + objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize(); - quaternion.setFromAxisAngle( axis, -angle ); + objectUpDirection.setLength( _moveCurr.y - _movePrev.y ); + objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x ); - _eye.applyQuaternion( quaternion ); - _this.object.up.applyQuaternion( quaternion ); + moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) ); - _rotateEnd.applyQuaternion( quaternion ); + axis.crossVectors( moveDirection, _eye ).normalize(); - if ( _this.staticMoving ) { + angle *= _this.rotateSpeed; + quaternion.setFromAxisAngle( axis, angle ); - _rotateStart.copy( _rotateEnd ); + _eye.applyQuaternion( quaternion ); + _this.object.up.applyQuaternion( quaternion ); - } else { + _lastAxis.copy( axis ); + _lastAngle = angle; - quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) ); - _rotateStart.applyQuaternion( quaternion ); + } - } + else if ( !_this.staticMoving && _lastAngle ) { - } + _lastAngle *= Math.sqrt( 1.0 - _this.dynamicDampingFactor ); + _eye.copy( _this.object.position ).sub( _this.target ); + quaternion.setFromAxisAngle( _lastAxis, _lastAngle ); + _eye.applyQuaternion( quaternion ); + _this.object.up.applyQuaternion( quaternion ); } + _movePrev.copy( _moveCurr ); + }; }()); @@ -491,17 +403,8 @@ THREE.TrackballControls = function ( object, domElement ) { if ( _state === STATE.ROTATE && !_this.noRotate ) { - if ( _this.cylindricalRotation ) { - - _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); - _movePrev.copy(_moveCurr); - - } else { - - _rotateStart.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) ); - _rotateEnd.copy( _rotateStart ); - - } + _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); + _movePrev.copy(_moveCurr); } else if ( _state === STATE.ZOOM && !_this.noZoom ) { @@ -531,16 +434,8 @@ THREE.TrackballControls = function ( object, domElement ) { if ( _state === STATE.ROTATE && !_this.noRotate ) { - if ( _this.cylindricalRotation ) { - - _movePrev.copy(_moveCurr); - _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); - - } else { - - _rotateEnd.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) ); - - } + _movePrev.copy(_moveCurr); + _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); } else if ( _state === STATE.ZOOM && !_this.noZoom ) { @@ -602,18 +497,8 @@ THREE.TrackballControls = function ( object, domElement ) { case 1: _state = STATE.TOUCH_ROTATE; - - if ( _this.cylindricalRotation ) { - - _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - _movePrev.copy(_moveCurr); - - } else { - - _rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - _rotateEnd.copy( _rotateStart ); - - } + _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); + _movePrev.copy(_moveCurr); break; case 2: @@ -647,16 +532,8 @@ THREE.TrackballControls = function ( object, domElement ) { switch ( event.touches.length ) { case 1: - if ( _this.cylindricalRotation ) { - - _movePrev.copy(_moveCurr); - _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - - } else { - - _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - - } + _movePrev.copy(_moveCurr); + _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); break; case 2: @@ -683,16 +560,8 @@ THREE.TrackballControls = function ( object, domElement ) { switch ( event.touches.length ) { case 1: - if ( _this.cylindricalRotation ) { - - _movePrev.copy(_moveCurr); - _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - - } else { - - _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - _rotateStart.copy( _rotateEnd ); - } + _movePrev.copy(_moveCurr); + _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); break; case 2: diff --git a/examples/misc_controls_trackball.html b/examples/misc_controls_trackball.html index d6a7dd4687b89b..910491a311c209 100644 --- a/examples/misc_controls_trackball.html +++ b/examples/misc_controls_trackball.html @@ -35,8 +35,7 @@
three.js - trackball controls example
- MOVE mouse & press LEFT/A: rotate, MIDDLE/S: zoom, RIGHT/D: pan
- R: switch from cylindrical (default) to spherical rotation + MOVE mouse & press LEFT/A: rotate, MIDDLE/S: zoom, RIGHT/D: pan
@@ -134,24 +133,12 @@ // window.addEventListener( 'resize', onWindowResize, false ); - window.addEventListener( 'keypress', onKeyPress, true); - // render(); } - function onKeyPress ( e ) { - - if ( e.keyCode === 114 ) { - - controls.cylindricalRotation = !controls.cylindricalRotation; - - } - - } - function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; From 8390b9694b8f33f09cbcdeabfc6c7f5c3e36a12e Mon Sep 17 00:00:00 2001 From: Arthur Silber Date: Mon, 23 Feb 2015 16:27:19 +0100 Subject: [PATCH 193/333] adding support for glColorMask (defined as material.colorWrite) - similar to material.depthWrite --- src/materials/Material.js | 2 ++ src/renderers/WebGLRenderer.js | 2 ++ src/renderers/webgl/WebGLState.js | 14 ++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/materials/Material.js b/src/materials/Material.js index ee7fa97a088646..9a3ca891e1c7f4 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -29,6 +29,8 @@ THREE.Material = function () { this.depthTest = true; this.depthWrite = true; + this.colorWrite = true; + this.polygonOffset = false; this.polygonOffsetFactor = 0; this.polygonOffsetUnits = 0; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 9e20361669fd31..25bdc57b14027e 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3417,6 +3417,7 @@ THREE.WebGLRenderer = function ( parameters ) { state.setDepthTest( true ); state.setDepthWrite( true ); + state.setColorWrite( true ); // _gl.finish(); @@ -4330,6 +4331,7 @@ THREE.WebGLRenderer = function ( parameters ) { state.setDepthTest( material.depthTest ); state.setDepthWrite( material.depthWrite ); + state.setColorWrite( material.colorWrite ); state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); } diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index 2a706d2b84e3e1..ef0d534941e51f 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -18,6 +18,8 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { var currentDepthTest = null; var currentDepthWrite = null; + var currentColorWrite = null; + var currentDoubleSided = null; var currentFlipSided = null; @@ -179,6 +181,17 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { }; + this.setColorWrite = function ( colorWrite ) { + + if ( currentColorWrite !== colorWrite ) { + + gl.colorMask( colorWrite, colorWrite, colorWrite, colorWrite ); + currentColorWrite = colorWrite; + + } + + }; + this.setDoubleSided = function ( doubleSided ) { if ( currentDoubleSided !== doubleSided ) { @@ -271,6 +284,7 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { currentBlending = null; currentDepthTest = null; currentDepthWrite = null; + currentColorWrite = null; currentDoubleSided = null; currentFlipSided = null; From 773cbbb2b1d3ea629d67e2e4be47827e9647f1d2 Mon Sep 17 00:00:00 2001 From: Arthur Silber Date: Mon, 23 Feb 2015 17:47:01 +0100 Subject: [PATCH 194/333] extend EdgesHelper to allow for a custom threshold angle --- src/extras/helpers/EdgesHelper.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/extras/helpers/EdgesHelper.js b/src/extras/helpers/EdgesHelper.js index ad1ce2451f6162..a2bcd59bc1ae74 100644 --- a/src/extras/helpers/EdgesHelper.js +++ b/src/extras/helpers/EdgesHelper.js @@ -2,9 +2,14 @@ * @author WestLangley / http://github.com/WestLangley */ -THREE.EdgesHelper = function ( object, hex ) { +THREE.EdgesHelper = function ( object, hex, thresholdAngle ) { var color = ( hex !== undefined ) ? hex : 0xffffff; + thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 170; + + thresholdAngle = thresholdAngle * 0.0175; //deg -> radian + var thresholdDot = Math.cos( thresholdAngle ); + var edge = [ 0, 0 ], hash = {}; var sortFunction = function ( a, b ) { return a - b }; @@ -67,7 +72,7 @@ THREE.EdgesHelper = function ( object, hex ) { var h = hash[ key ]; - if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) < 0.9999 ) { // hardwired const OK + if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) < thresholdDot ) { var vertex = vertices[ h.vert1 ]; coords[ index ++ ] = vertex.x; From ef98fac022be2d5f4c5175c862075456e2fed02b Mon Sep 17 00:00:00 2001 From: WestLangley Date: Tue, 24 Feb 2015 01:25:33 -0500 Subject: [PATCH 195/333] Make sure vertex normals are cloned --- examples/js/loaders/ColladaLoader.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index 127e33a47da94c..ea1f46ddf73a4b 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -3024,9 +3024,9 @@ THREE.ColladaLoader = function () { } else if ( vcount === 4 ) { - faces.push( new THREE.Face3( vs[0], vs[1], vs[3], [ns[0], ns[1], ns[3]], cs.length ? [cs[0], cs[1], cs[3]] : new THREE.Color() ) ); + faces.push( new THREE.Face3( vs[0], vs[1], vs[3], [ns[0].clone(), ns[1].clone(), ns[3].clone()], cs.length ? [cs[0], cs[1], cs[3]] : new THREE.Color() ) ); - faces.push( new THREE.Face3( vs[1], vs[2], vs[3], [ns[1], ns[2], ns[3]], cs.length ? [cs[1], cs[2], cs[3]] : new THREE.Color() ) ); + faces.push( new THREE.Face3( vs[1], vs[2], vs[3], [ns[1].clone(), ns[2].clone(), ns[3].clone()], cs.length ? [cs[1], cs[2], cs[3]] : new THREE.Color() ) ); } else if ( vcount > 4 && options.subdivideFaces ) { @@ -3039,7 +3039,7 @@ THREE.ColladaLoader = function () { // FIXME: normals don't seem to be quite right - faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ], clr ) ); + faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0].clone(), ns[k++].clone(), ns[k].clone() ], clr ) ); } From d6679ba3ee3a73bc16345359db1d8000426071e6 Mon Sep 17 00:00:00 2001 From: WestLangley Date: Tue, 24 Feb 2015 02:19:05 -0500 Subject: [PATCH 196/333] OrbitControls: Support OrthographicCamera Zooming --- examples/js/controls/OrbitControls.js | 47 ++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/examples/js/controls/OrbitControls.js b/examples/js/controls/OrbitControls.js index be5f768ec88da4..371499e7d9d8ca 100644 --- a/examples/js/controls/OrbitControls.js +++ b/examples/js/controls/OrbitControls.js @@ -37,10 +37,14 @@ THREE.OrbitControls = function ( object, domElement ) { this.noZoom = false; this.zoomSpeed = 1.0; - // Limits to how far you can dolly in and out + // Limits to how far you can dolly in and out ( PerspectiveCamera only ) this.minDistance = 0; this.maxDistance = Infinity; + // Limits to how far you can zoom in and out ( OrthographicCamera only ) + this.minZoom = 0; + this.maxZoom = Infinity; + // Set to true to disable this control this.noRotate = false; this.rotateSpeed = 1.0; @@ -112,6 +116,7 @@ THREE.OrbitControls = function ( object, domElement ) { this.target0 = this.target.clone(); this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; // so camera.up is the orbit axis @@ -180,7 +185,7 @@ THREE.OrbitControls = function ( object, domElement ) { var element = scope.domElement === document ? scope.domElement.body : scope.domElement; - if ( scope.object.fov !== undefined ) { + if ( scope.object instanceof THREE.PerspectiveCamera ) { // perspective var position = scope.object.position; @@ -194,7 +199,7 @@ THREE.OrbitControls = function ( object, domElement ) { scope.panLeft( 2 * deltaX * targetDistance / element.clientHeight ); scope.panUp( 2 * deltaY * targetDistance / element.clientHeight ); - } else if ( scope.object.top !== undefined ) { + } else if ( scope.object instanceof THREE.OrthographicCamera ) { // orthographic scope.panLeft( deltaX * (scope.object.right - scope.object.left) / element.clientWidth ); @@ -217,7 +222,21 @@ THREE.OrbitControls = function ( object, domElement ) { } - scale /= dollyScale; + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + scale /= dollyScale; + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom * dollyScale ) ); + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + + } }; @@ -229,7 +248,21 @@ THREE.OrbitControls = function ( object, domElement ) { } - scale *= dollyScale; + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + scale *= dollyScale; + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / dollyScale ) ); + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + + } }; @@ -315,6 +348,10 @@ THREE.OrbitControls = function ( object, domElement ) { this.target.copy( this.target0 ); this.object.position.copy( this.position0 ); + this.object.zoom = this.zoom0; + + this.object.updateProjectionMatrix(); + this.dispatchEvent( changeEvent ); this.update(); From 7978aefc143203583d0906d04f2eaa788002f3fc Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 24 Feb 2015 06:50:25 -0800 Subject: [PATCH 197/333] ObjectLoader: Fixed callback. See c223a4c4bd04cdb7f4fbad339187eea36b4fe857. --- src/loaders/ObjectLoader.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 054af49d7d617e..4b02c0a3051324 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -48,7 +48,11 @@ THREE.ObjectLoader.prototype = { var geometries = this.parseGeometries( json.geometries ); - var images = this.parseImages( json.images, onLoad ); + var images = this.parseImages( json.images, function () { + + if ( onLoad !== undefined ) onLoad( object ); + + } ); var textures = this.parseTextures( json.textures, images ); var materials = this.parseMaterials( json.materials, textures ); var object = this.parseObject( json.object, geometries, materials ); From e5cc53358c619c8aa7c9c26de137236d00b1fbf0 Mon Sep 17 00:00:00 2001 From: humbletim Date: Tue, 24 Feb 2015 10:53:11 -0500 Subject: [PATCH 198/333] Fix 'Math.sign' polyfill to match ES6 specs --- src/Three.js | 4 +++- test/unit/math/Math.js | 35 +++++++++++++++++++++++++++++ test/unit/unittests_sources.html | 1 + test/unit/unittests_three-math.html | 1 + test/unit/unittests_three.html | 1 + test/unit/unittests_three.min.html | 1 + 6 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 test/unit/math/Math.js diff --git a/src/Three.js b/src/Three.js index f415783be585d3..61cb895796ca63 100644 --- a/src/Three.js +++ b/src/Three.js @@ -16,9 +16,11 @@ if ( typeof module === 'object' ) { if ( Math.sign === undefined ) { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign + Math.sign = function ( x ) { - return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : 0; + return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : +x; }; diff --git a/test/unit/math/Math.js b/test/unit/math/Math.js new file mode 100644 index 00000000000000..24fab739537df9 --- /dev/null +++ b/test/unit/math/Math.js @@ -0,0 +1,35 @@ +/** + * @author humbletim / https://github.com/humbletim + */ + +module( "Math" ); + +//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign +//http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign +/* +20.2.2.29 Math.sign(x) + +Returns the sign of the x, indicating whether x is positive, negative or zero. + +If x is NaN, the result is NaN. +If x is -0, the result is -0. +If x is +0, the result is +0. +If x is negative and not -0, the result is -1. +If x is positive and not +0, the result is +1. +*/ + +test( "Math.sign/polyfill", function() { + + ok( isNaN( Math.sign(NaN) ) , "If x is NaN, the result is NaN."); + ok( isNaN( Math.sign(new THREE.Vector3()) ) , "If x is NaN, the result is NaN."); + ok( isNaN( Math.sign() ) , "If x is NaN, the result is NaN."); + ok( isNaN( Math.sign('--3') ) , "If x is NaN<'--3'>, the result is NaN."); + ok( Math.sign(-0) === -0 , "If x is -0, the result is -0."); + ok( Math.sign(+0) === +0 , "If x is +0, the result is +0."); + ok( Math.sign(-Infinity) === -1 , "If x is negative<-Infinity> and not -0, the result is -1."); + ok( Math.sign('-3') === -1 , "If x is negative<'-3'> and not -0, the result is -1."); + ok( Math.sign('-1e-10') === -1 , "If x is negative<'-1e-10'> and not -0, the result is -1."); + ok( Math.sign(+Infinity) === +1 , "If x is positive<+Infinity> and not +0, the result is +1."); + ok( Math.sign('+3') === +1 , "If x is positive<'+3'> and not +0, the result is +1."); + +}); diff --git a/test/unit/unittests_sources.html b/test/unit/unittests_sources.html index 82aabde1e81459..c92a60d9550926 100644 --- a/test/unit/unittests_sources.html +++ b/test/unit/unittests_sources.html @@ -45,6 +45,7 @@ + diff --git a/test/unit/unittests_three-math.html b/test/unit/unittests_three-math.html index 7bd8ac804f271f..5eaf7e6388e7ef 100644 --- a/test/unit/unittests_three-math.html +++ b/test/unit/unittests_three-math.html @@ -28,6 +28,7 @@ + diff --git a/test/unit/unittests_three.html b/test/unit/unittests_three.html index b02c16bec56ff9..e995d3025c5f5e 100644 --- a/test/unit/unittests_three.html +++ b/test/unit/unittests_three.html @@ -28,6 +28,7 @@ + diff --git a/test/unit/unittests_three.min.html b/test/unit/unittests_three.min.html index 5635fc5a0f5a95..34168123d13212 100644 --- a/test/unit/unittests_three.min.html +++ b/test/unit/unittests_three.min.html @@ -28,6 +28,7 @@ + From 43c5354f94492ad7a8a4379b449a63215267822d Mon Sep 17 00:00:00 2001 From: mese79 Date: Tue, 24 Feb 2015 20:07:01 +0330 Subject: [PATCH 199/333] add support for normal/bump scale --- src/loaders/ObjectLoader.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 4b02c0a3051324..dea8b86f120362 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -5,6 +5,7 @@ THREE.ObjectLoader = function ( manager ) { this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + this.texturePath = ''; }; @@ -14,7 +15,7 @@ THREE.ObjectLoader.prototype = { load: function ( url, onLoad, onProgress, onError ) { - if ( this.texturePath === undefined ) { + if ( this.texturePath === '' ) { this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 ); @@ -245,6 +246,9 @@ THREE.ObjectLoader.prototype = { if ( data.bumpMap !== undefined ) { material.bumpMap = getTexture( data.bumpMap ); + if ( data.bumpScale ) { + material.bumpScale = new THREE.Vector2( data.bumpScale, data.bumpScale ); + } } @@ -263,6 +267,9 @@ THREE.ObjectLoader.prototype = { if ( data.normalMap !== undefined ) { material.normalMap = getTexture( data.normalMap ); + if ( data.normalScale ) { + material.normalScale = new THREE.Vector2( data.normalScale, data.normalScale ); + } } From 932ee2d443e2661103629d82dac4ab936796275d Mon Sep 17 00:00:00 2001 From: mese79 Date: Tue, 24 Feb 2015 20:25:52 +0330 Subject: [PATCH 200/333] add support for texture folder --- .../blender/addons/io_three/__init__.py | 17 +++++++++++--- .../blender/addons/io_three/constants.py | 12 ++++++---- .../addons/io_three/exporter/__init__.py | 23 ++++--------------- .../addons/io_three/exporter/api/__init__.py | 10 -------- .../addons/io_three/exporter/api/material.py | 2 +- .../addons/io_three/exporter/api/texture.py | 9 +++++--- .../addons/io_three/exporter/geometry.py | 4 ++-- .../blender/addons/io_three/exporter/image.py | 3 ++- .../blender/addons/io_three/exporter/io.py | 1 + .../blender/addons/io_three/exporter/scene.py | 3 ++- 10 files changed, 40 insertions(+), 44 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 2c6da580f331e8..a8c7c2496dcebe 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -26,7 +26,8 @@ EnumProperty, BoolProperty, FloatProperty, - IntProperty + IntProperty, + StringProperty ) from . import constants @@ -41,7 +42,7 @@ bl_info = { 'name': "Three.js Format", 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", - 'version': (1, 2, 3), + 'version': (1, 2, 2), 'blender': (2, 7, 3), 'location': "File > Export", 'description': "Export Three.js formatted JSON files.", @@ -295,6 +296,7 @@ def save_settings_export(properties): constants.COMPRESSION: properties.option_compression, constants.INDENT: properties.option_indent, constants.COPY_TEXTURES: properties.option_copy_textures, + constants.TEXTURE_FOLDER: properties.option_texture_folder, constants.SCENE: properties.option_export_scene, #constants.EMBED_GEOMETRY: properties.option_embed_geometry, @@ -420,6 +422,10 @@ def restore_settings_export(properties): constants.COPY_TEXTURES, constants.EXPORT_OPTIONS[constants.COPY_TEXTURES]) + properties.option_texture_folder = settings.get( + constants.TEXTURE_FOLDER, + constants.EXPORT_OPTIONS[constants.TEXTURE_FOLDER]) + properties.option_embed_animation = settings.get( constants.EMBED_ANIMATION, constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION]) @@ -617,6 +623,9 @@ class ExportThree(bpy.types.Operator, ExportHelper): description="Copy textures", default=constants.EXPORT_OPTIONS[constants.COPY_TEXTURES]) + option_texture_folder = StringProperty(name="Texture folder", + description="add this folder to textures path", default="") + option_lights = BoolProperty( name="Lights", description="Export default scene lights", @@ -693,7 +702,6 @@ def execute(self, context): raise Exception("filename not set") settings = save_settings_export(self.properties) - settings['addon_version'] = bl_info['version'] filepath = self.filepath if settings[constants.COMPRESSION] == constants.MSGPACK: @@ -812,6 +820,9 @@ def draw(self, context): row = layout.row() row.prop(self.properties, 'option_copy_textures') + row = layout.row() + row.prop(self.properties, "option_texture_folder") + row = layout.row() row.prop(self.properties, 'option_scale') diff --git a/utils/exporters/blender/addons/io_three/constants.py b/utils/exporters/blender/addons/io_three/constants.py index b183cf0c54d2fd..3eddd7a54dfb01 100644 --- a/utils/exporters/blender/addons/io_three/constants.py +++ b/utils/exporters/blender/addons/io_three/constants.py @@ -63,6 +63,7 @@ FACE_MATERIALS = 'faceMaterials' SKINNING = 'skinning' COPY_TEXTURES = 'copyTextures' +TEXTURE_FOLDER = "texture_folder" ENABLE_PRECISION = 'enablePrecision' PRECISION = 'precision' DEFAULT_PRECISION = 6 @@ -91,18 +92,18 @@ EXPORT_OPTIONS = { FACES: True, VERTICES: True, - NORMALS: False, - UVS: False, + NORMALS: True, + UVS: True, COLORS: False, - MATERIALS: False, + MATERIALS: True, FACE_MATERIALS: False, SCALE: 1, FRAME_STEP: 1, FRAME_INDEX_AS_TIME: False, - SCENE: False, + SCENE: True, MIX_COLORS: False, COMPRESSION: None, - MAPS: False, + MAPS: True, ANIMATION: OFF, BONES: False, SKINNING: False, @@ -110,6 +111,7 @@ CAMERAS: False, LIGHTS: False, COPY_TEXTURES: True, + TEXTURE_FOLDER: "", LOGGING: DEBUG, ENABLE_PRECISION: True, PRECISION: DEFAULT_PRECISION, diff --git a/utils/exporters/blender/addons/io_three/exporter/__init__.py b/utils/exporters/blender/addons/io_three/exporter/__init__.py index 2f0cba4d9bf879..4acb0d7c1ae474 100644 --- a/utils/exporters/blender/addons/io_three/exporter/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/__init__.py @@ -1,7 +1,7 @@ import os import sys import traceback -from .. import constants, logger, exceptions, dialogs +from .. import constants, logger, exceptions from . import scene, geometry, api, base_classes @@ -9,10 +9,7 @@ def _error_handler(func): def inner(filepath, options, *args, **kwargs): level = options.get(constants.LOGGING, constants.DEBUG) - version = options.get('addon_version') logger.init('io_three.export.log', level=level) - if version is not None: - logger.debug("Addon Version %s", version) api.init() try: @@ -58,26 +55,16 @@ def export_scene(filepath, options): @_error_handler def export_geometry(filepath, options, node=None): - msg = "" - exception = None if node is None: node = api.active_object() if node is None: - msg = "Nothing selected" + msg = 'Nothing selected' logger.error(msg) - exception = exceptions.SelectionError + raise exceptions.SelectionError(msg) if node.type != 'MESH': - msg = "%s is not a valid mesh object" % node.name - logger.error(msg) - exception = exceptions.GeometryError + msg = 'Not a valid mesh object' + raise exceptions.GeometryError(msg) - if exception is not None: - if api.batch_mode(): - raise exception(msg) - else: - dialogs.error(msg) - return - mesh = api.object.mesh(node, options) parent = base_classes.BaseScene(filepath, options) geo = geometry.Geometry(mesh, parent) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py index a273c9d482eedc..fa120d47252632 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py @@ -13,16 +13,6 @@ def active_object(): return bpy.context.scene.objects.active -def batch_mode(): - """ - - :return: Whether or not the session is interactive - :rtype: bool - - """ - return bpy.context.area is None - - def init(): """Initializing the api module. Required first step before initializing the actual export process. diff --git a/utils/exporters/blender/addons/io_three/exporter/api/material.py b/utils/exporters/blender/addons/io_three/exporter/api/material.py index 0f227049c87026..e2dbb5c9c24712 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/material.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/material.py @@ -380,7 +380,7 @@ def _valid_textures(material): for texture in material.texture_slots: if not texture: continue - if texture.texture.type != IMAGE: + if texture.texture.type != IMAGE or not texture.use: continue logger.debug("Valid texture found %s", texture) yield texture diff --git a/utils/exporters/blender/addons/io_three/exporter/api/texture.py b/utils/exporters/blender/addons/io_three/exporter/api/texture.py index 7c020f59948fca..33088e9127a794 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/texture.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/texture.py @@ -170,6 +170,9 @@ def textures(): """ logger.debug("texture.textures()") - for texture in data.textures: - if texture.type == IMAGE: - yield texture.name + for mat in data.materials: + if mat.users == 0: + continue + for slot in mat.texture_slots: + if slot and slot.use and slot.texture.type == IMAGE: + yield slot.texture.name diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index 72c514df1331cf..53e171d239dee2 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -135,7 +135,7 @@ def copy(self, scene=True): return data - def copy_textures(self): + def copy_textures(self, texture_folder=""): """Copy the textures to the destination directory.""" logger.debug("Geometry().copy_textures()") if self.options.get(constants.COPY_TEXTURES): @@ -143,7 +143,7 @@ def copy_textures(self): if texture_registration: logger.info("%s has registered textures", self.node) io.copy_registered_textures( - os.path.dirname(self.scene.filepath), + os.path.join(os.path.dirname(self.scene.filepath), texture_folder), texture_registration) def parse(self): diff --git a/utils/exporters/blender/addons/io_three/exporter/image.py b/utils/exporters/blender/addons/io_three/exporter/image.py index 575b6506019b51..74f7a5b266463f 100644 --- a/utils/exporters/blender/addons/io_three/exporter/image.py +++ b/utils/exporters/blender/addons/io_three/exporter/image.py @@ -11,7 +11,8 @@ def __init__(self, node, parent): logger.debug("Image().__init__(%s)", node) base_classes.BaseNode.__init__(self, node, parent, constants.IMAGE) - self[constants.URL] = api.image.file_name(self.node) + texture_folder = self.scene.options.get(constants.TEXTURE_FOLDER, "") + self[constants.URL] = os.path.join(texture_folder, api.image.file_name(self.node)) @property def destination(self): diff --git a/utils/exporters/blender/addons/io_three/exporter/io.py b/utils/exporters/blender/addons/io_three/exporter/io.py index 69aab0e2502717..49231aa54f5ad9 100644 --- a/utils/exporters/blender/addons/io_three/exporter/io.py +++ b/utils/exporters/blender/addons/io_three/exporter/io.py @@ -14,6 +14,7 @@ def copy_registered_textures(dest, registration): """ logger.debug("io.copy_registered_textures(%s, %s)", dest, registration) + os.makedirs(dest, exist_ok=True) for value in registration.values(): copy(value['file_path'], dest) diff --git a/utils/exporters/blender/addons/io_three/exporter/scene.py b/utils/exporters/blender/addons/io_three/exporter/scene.py index c2521de5076f3b..6fbf3e3641e289 100644 --- a/utils/exporters/blender/addons/io_three/exporter/scene.py +++ b/utils/exporters/blender/addons/io_three/exporter/scene.py @@ -159,9 +159,10 @@ def write(self): io.dump(self.filepath, data, options=self.options) if self.options.get(constants.COPY_TEXTURES): + texture_folder = self.options.get(constants.TEXTURE_FOLDER) for geo in self[constants.GEOMETRIES]: logger.info("Copying textures from %s", geo.node) - geo.copy_textures() + geo.copy_textures(texture_folder) def _parse_geometries(self): """Locate all geometry nodes and parse them""" From 1998ee5fc09bbfffceb15794665e2da31cde0ba6 Mon Sep 17 00:00:00 2001 From: mese79 Date: Tue, 24 Feb 2015 20:41:08 +0330 Subject: [PATCH 201/333] add support for texture folder --- .../blender/addons/io_three/__init__.py | 3 ++- .../addons/io_three/exporter/__init__.py | 23 +++++++++++++++---- .../addons/io_three/exporter/api/__init__.py | 10 ++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index a8c7c2496dcebe..bf00287ac1d6c3 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -42,7 +42,7 @@ bl_info = { 'name': "Three.js Format", 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", - 'version': (1, 2, 2), + 'version': (1, 2, 3), 'blender': (2, 7, 3), 'location': "File > Export", 'description': "Export Three.js formatted JSON files.", @@ -702,6 +702,7 @@ def execute(self, context): raise Exception("filename not set") settings = save_settings_export(self.properties) + settings['addon_version'] = bl_info['version'] filepath = self.filepath if settings[constants.COMPRESSION] == constants.MSGPACK: diff --git a/utils/exporters/blender/addons/io_three/exporter/__init__.py b/utils/exporters/blender/addons/io_three/exporter/__init__.py index 4acb0d7c1ae474..90d6f871aad052 100644 --- a/utils/exporters/blender/addons/io_three/exporter/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/__init__.py @@ -1,7 +1,7 @@ import os import sys import traceback -from .. import constants, logger, exceptions +from .. import constants, logger, exceptions, dialogs from . import scene, geometry, api, base_classes @@ -9,7 +9,10 @@ def _error_handler(func): def inner(filepath, options, *args, **kwargs): level = options.get(constants.LOGGING, constants.DEBUG) + version = options.get('addon_version') logger.init('io_three.export.log', level=level) + if version is not None: + logger.debug("Addon Version %s", version) api.init() try: @@ -55,16 +58,26 @@ def export_scene(filepath, options): @_error_handler def export_geometry(filepath, options, node=None): + msg = "" + exception = None if node is None: node = api.active_object() if node is None: - msg = 'Nothing selected' + msg = "Nothing selected" logger.error(msg) - raise exceptions.SelectionError(msg) + exception = exceptions.SelectionError if node.type != 'MESH': - msg = 'Not a valid mesh object' - raise exceptions.GeometryError(msg) + msg = "%s is not a valid mesh object" % node.name + logger.error(msg) + exception = exceptions.GeometryError + if exception is not None: + if api.batch_mode(): + raise exception(msg) + else: + dialogs.error(msg) + return + mesh = api.object.mesh(node, options) parent = base_classes.BaseScene(filepath, options) geo = geometry.Geometry(mesh, parent) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py index fa120d47252632..e9b92efb723a85 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py @@ -13,6 +13,16 @@ def active_object(): return bpy.context.scene.objects.active +def batch_mode(): + """ + + :return: Whether or not the session is interactive + :rtype: bool + + """ + return bpy.context.area is None + + def init(): """Initializing the api module. Required first step before initializing the actual export process. From 0e6d3a7bc965d93f65c833349878366ef06bbcfe Mon Sep 17 00:00:00 2001 From: Arthur Silber Date: Wed, 25 Feb 2015 14:00:35 +0100 Subject: [PATCH 202/333] =?UTF-8?q?fixed=20wrong=20default=20value=20for?= =?UTF-8?q?=20EdgesHelper=20constructor,=20fixed=20edge=20case=20(angle=20?= =?UTF-8?q?of=200=C2=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/extras/helpers/EdgesHelper.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extras/helpers/EdgesHelper.js b/src/extras/helpers/EdgesHelper.js index a2bcd59bc1ae74..9de5b4785bcd5d 100644 --- a/src/extras/helpers/EdgesHelper.js +++ b/src/extras/helpers/EdgesHelper.js @@ -5,7 +5,7 @@ THREE.EdgesHelper = function ( object, hex, thresholdAngle ) { var color = ( hex !== undefined ) ? hex : 0xffffff; - thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 170; + thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 10; thresholdAngle = thresholdAngle * 0.0175; //deg -> radian var thresholdDot = Math.cos( thresholdAngle ); @@ -72,7 +72,7 @@ THREE.EdgesHelper = function ( object, hex, thresholdAngle ) { var h = hash[ key ]; - if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) < thresholdDot ) { + if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) { var vertex = vertices[ h.vert1 ]; coords[ index ++ ] = vertex.x; From 2931d474458b479331cb2a09982a233ef2b0ea6e Mon Sep 17 00:00:00 2001 From: Arthur Silber Date: Wed, 25 Feb 2015 14:10:40 +0100 Subject: [PATCH 203/333] adding documentation --- src/extras/helpers/EdgesHelper.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/extras/helpers/EdgesHelper.js b/src/extras/helpers/EdgesHelper.js index 9de5b4785bcd5d..1416ab909a388a 100644 --- a/src/extras/helpers/EdgesHelper.js +++ b/src/extras/helpers/EdgesHelper.js @@ -1,5 +1,10 @@ /** * @author WestLangley / http://github.com/WestLangley + * @param object THREE.Mesh whose geometry will be used + * @param hex line color + * @param thresholdAngle the minimum difference in degree between two + * faces needed to create an edge. A value of 10 means that an edge is only + * created if two face normals are at least at a 10° angle to one another */ THREE.EdgesHelper = function ( object, hex, thresholdAngle ) { From 3bb8cabba6185126c87f8154356c95f43baede94 Mon Sep 17 00:00:00 2001 From: Charles Abeling Date: Wed, 25 Feb 2015 10:39:13 -0600 Subject: [PATCH 204/333] Added EventDispatcher prototype Added EventDispatcher prototype and added renderfinish event --- examples/js/renderers/RaytracingRenderer.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/js/renderers/RaytracingRenderer.js b/examples/js/renderers/RaytracingRenderer.js index ca612a633d473f..94ea9a7eac6ee5 100644 --- a/examples/js/renderers/RaytracingRenderer.js +++ b/examples/js/renderers/RaytracingRenderer.js @@ -39,6 +39,8 @@ THREE.RaytracingRenderer = function ( parameters ) { var animationFrameId = null; + var dispatch = this.dispatchEvent.bind(this); + this.domElement = canvas; this.autoClear = true; @@ -456,7 +458,13 @@ THREE.RaytracingRenderer = function ( parameters ) { blockX = 0; blockY += blockSize; - if ( blockY >= canvasHeight ) return; + if ( blockY >= canvasHeight ) { + + dispatch( { type: "renderfinish" } ); + + return; + + } } @@ -532,4 +540,6 @@ THREE.RaytracingRenderer = function ( parameters ) { }; -}; \ No newline at end of file +}; + +THREE.EventDispatcher.prototype.apply(THREE.RaytracingRenderer.prototype); From 26a2dcb516d8687b2e0b4c1056be95e0b2e517c2 Mon Sep 17 00:00:00 2001 From: Charles Abeling Date: Wed, 25 Feb 2015 13:53:11 -0600 Subject: [PATCH 205/333] Change renderfinish event to complete --- examples/js/renderers/RaytracingRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/renderers/RaytracingRenderer.js b/examples/js/renderers/RaytracingRenderer.js index 94ea9a7eac6ee5..1653d2a0fc1871 100644 --- a/examples/js/renderers/RaytracingRenderer.js +++ b/examples/js/renderers/RaytracingRenderer.js @@ -460,7 +460,7 @@ THREE.RaytracingRenderer = function ( parameters ) { if ( blockY >= canvasHeight ) { - dispatch( { type: "renderfinish" } ); + dispatch( { type: "complete" } ); return; From 9a68b626b2ae4a85c9be2b448c440521ce391f62 Mon Sep 17 00:00:00 2001 From: gero3 Date: Wed, 25 Feb 2015 21:06:09 +0100 Subject: [PATCH 206/333] Update DirectionalLightHelper.html Some more correction of the documentation --- docs/api/extras/helpers/DirectionalLightHelper.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/api/extras/helpers/DirectionalLightHelper.html b/docs/api/extras/helpers/DirectionalLightHelper.html index 4b1d62f0972d96..80aa9e095a4e4c 100644 --- a/docs/api/extras/helpers/DirectionalLightHelper.html +++ b/docs/api/extras/helpers/DirectionalLightHelper.html @@ -17,7 +17,7 @@

[name]

Constructor

-

[name]([DirectionalLight:todo light], [page:Number size])

+

[name]([page:DirectionalLight light], [page:Number size])

light -- [page:DirectionalLight] -- Light to visualize
size -- dimensions of the plane @@ -32,18 +32,18 @@

Properties

[property:Line lightPlane]

- todo + Contains the line mesh showing the location of the directional light.

[property:DirectionalLight light]

- todo + Contains the directionalLight.

[property:Line targetLine]

- todo -
+ Contains the line mesh that shows the direction of the light. +

Methods

From 921a22043d00755bdbb5bf994b75f76571ee2aaf Mon Sep 17 00:00:00 2001 From: gero3 Date: Wed, 25 Feb 2015 21:09:54 +0100 Subject: [PATCH 207/333] Update CameraHelper.html --- docs/api/extras/helpers/CameraHelper.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/extras/helpers/CameraHelper.html b/docs/api/extras/helpers/CameraHelper.html index 1a6fd9f1f246bc..64d74380d55082 100644 --- a/docs/api/extras/helpers/CameraHelper.html +++ b/docs/api/extras/helpers/CameraHelper.html @@ -45,7 +45,7 @@

[property:Camera camera]

Methods

-

[method:todo update]()

+

[method:null update]()

Updates the helper based on the projectionMatrix of the camera.
From 685004fb782e3bddf2c3e7e4e945bf6ab0a2dd4c Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 25 Feb 2015 21:55:11 +0100 Subject: [PATCH 208/333] Docs: Lowercase T. See #6100. --- docs/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.html b/docs/index.html index b2d1624f909ffa..5b2f85dee1bb19 100644 --- a/docs/index.html +++ b/docs/index.html @@ -406,10 +406,10 @@

three.js / docs

if ( window.location.hash.length > 0 ) goToHash(); console.log([ - '_______ __', - '/ _______\\/ __\\__ ____ _____ _____', - '\\/__ __/ / /___\\/ ____\\/ _____\\/ _____\\', - ' / / / / / _ / / __/ / __ / / __ /_ __ _____', + ' __ __', + ' __/ __\\ / __\\__ ____ _____ _____', + '/ __/ /\\/ / /___\\/ ____\\/ _____\\/ _____\\', + '\\/_ __/ / _ / / __/ / __ / / __ /_ __ _____', '/ / / / / / / / / / / / ___/ / ___/\\ _\\/ __\\/ _____\\', '\\/__/ \\/__/\\/__/\\/__/ \\/_____/\\/_____/\\/__/ / / / ___/', ' / __/ / \\__ \\', From 3e2ae6d4517b8cff8eddb4fdcc8985f642ab1926 Mon Sep 17 00:00:00 2001 From: gero3 Date: Wed, 25 Feb 2015 21:58:05 +0100 Subject: [PATCH 209/333] Update HemisphereLightHelper.js cleanup some unused arguments --- src/extras/helpers/HemisphereLightHelper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extras/helpers/HemisphereLightHelper.js b/src/extras/helpers/HemisphereLightHelper.js index 5273af8300013f..469708f5cb1702 100644 --- a/src/extras/helpers/HemisphereLightHelper.js +++ b/src/extras/helpers/HemisphereLightHelper.js @@ -3,7 +3,7 @@ * @author mrdoob / http://mrdoob.com/ */ -THREE.HemisphereLightHelper = function ( light, sphereSize, arrowLength, domeSize ) { +THREE.HemisphereLightHelper = function ( light, sphereSize ) { THREE.Object3D.call( this ); From 55281262a18acec9b4169ef75073550d0033c1bb Mon Sep 17 00:00:00 2001 From: gero3 Date: Wed, 25 Feb 2015 22:15:12 +0100 Subject: [PATCH 210/333] Update HemisphereLightHelper.html --- .../extras/helpers/HemisphereLightHelper.html | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/api/extras/helpers/HemisphereLightHelper.html b/docs/api/extras/helpers/HemisphereLightHelper.html index 52987be41530bd..9b0f61695a628e 100644 --- a/docs/api/extras/helpers/HemisphereLightHelper.html +++ b/docs/api/extras/helpers/HemisphereLightHelper.html @@ -11,20 +11,18 @@

[name]

-
todo
+
Creates a visual aid for a [page:HemisphereLight HemisphereLight].

Constructor

-

[name]([page:todo light], [page:todo sphereSize], [page:todo arrowLength], [page:todo domeSize])

+

[name]([page:HemisphereLight light], [page:Number sphereSize])

- light -- todo
- sphereSize -- todo
- arrowLength -- todo
- domeSize -- todo + light -- The HemisphereLight.
+ sphereSize -- The size of the sphere that shows the location.
- todo + Creates an helper for the hemispherelight.
@@ -32,20 +30,20 @@

Properties

[property:Mesh lightSphere]

- todo + The sphere mesh that shows the location of the hemispherelight.

[property:HemisphereLight light]

- todo + Contains the HemisphereLight

Methods

-

[method:todo update]()

+

[method:null update]()

- todo + Updates the helper to match the position and direction of the [page:.light].
From 053a317c60f1f8c75b9502df72b38040a66436ff Mon Sep 17 00:00:00 2001 From: gero3 Date: Wed, 25 Feb 2015 22:16:04 +0100 Subject: [PATCH 211/333] Update HemisphereLightHelper.html --- docs/api/extras/helpers/HemisphereLightHelper.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/extras/helpers/HemisphereLightHelper.html b/docs/api/extras/helpers/HemisphereLightHelper.html index 9b0f61695a628e..070a2ae2735941 100644 --- a/docs/api/extras/helpers/HemisphereLightHelper.html +++ b/docs/api/extras/helpers/HemisphereLightHelper.html @@ -35,7 +35,7 @@

[property:Mesh lightSphere]

[property:HemisphereLight light]

- Contains the HemisphereLight + Contains the HemisphereLight.
From f933ee1b575d00a30df117689928faaa2695cf32 Mon Sep 17 00:00:00 2001 From: mese79 Date: Thu, 26 Feb 2015 01:39:45 +0330 Subject: [PATCH 212/333] change texture_folder to textureFolder and revert back default options --- utils/exporters/blender/addons/io_three/constants.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/constants.py b/utils/exporters/blender/addons/io_three/constants.py index 3eddd7a54dfb01..9fe357b2af98ff 100644 --- a/utils/exporters/blender/addons/io_three/constants.py +++ b/utils/exporters/blender/addons/io_three/constants.py @@ -63,7 +63,7 @@ FACE_MATERIALS = 'faceMaterials' SKINNING = 'skinning' COPY_TEXTURES = 'copyTextures' -TEXTURE_FOLDER = "texture_folder" +TEXTURE_FOLDER = "textureFolder" ENABLE_PRECISION = 'enablePrecision' PRECISION = 'precision' DEFAULT_PRECISION = 6 @@ -95,15 +95,15 @@ NORMALS: True, UVS: True, COLORS: False, - MATERIALS: True, + MATERIALS: False, FACE_MATERIALS: False, SCALE: 1, FRAME_STEP: 1, FRAME_INDEX_AS_TIME: False, - SCENE: True, + SCENE: False, MIX_COLORS: False, COMPRESSION: None, - MAPS: True, + MAPS: False, ANIMATION: OFF, BONES: False, SKINNING: False, From 9c126977821f9b5d41b0af354c3f859ba5c81db6 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 25 Feb 2015 23:16:49 +0100 Subject: [PATCH 213/333] Updated builds. --- build/three.js | 32 +++++-- build/three.min.js | 206 ++++++++++++++++++++++----------------------- 2 files changed, 130 insertions(+), 108 deletions(-) diff --git a/build/three.js b/build/three.js index 02873eaee2e201..63f55ee2bba388 100644 --- a/build/three.js +++ b/build/three.js @@ -18,9 +18,11 @@ if ( typeof module === 'object' ) { if ( Math.sign === undefined ) { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign + Math.sign = function ( x ) { - return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : 0; + return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : +x; }; @@ -12631,6 +12633,12 @@ THREE.ObjectLoader.prototype = { var materials = this.parseMaterials( json.materials, textures ); var object = this.parseObject( json.object, geometries, materials ); + if ( json.images === undefined || json.images.length === 0 ) { + + if ( onLoad !== undefined ) onLoad( object ); + + } + return object; }, @@ -12888,10 +12896,6 @@ THREE.ObjectLoader.prototype = { } - } else { - - if ( onLoad !== undefined ) onLoad(); - } return images; @@ -13399,6 +13403,8 @@ THREE.Material = function () { this.depthTest = true; this.depthWrite = true; + this.colorWrite = true; + this.polygonOffset = false; this.polygonOffsetFactor = 0; this.polygonOffsetUnits = 0; @@ -21128,6 +21134,7 @@ THREE.WebGLRenderer = function ( parameters ) { state.setDepthTest( true ); state.setDepthWrite( true ); + state.setColorWrite( true ); // _gl.finish(); @@ -22041,6 +22048,7 @@ THREE.WebGLRenderer = function ( parameters ) { state.setDepthTest( material.depthTest ); state.setDepthWrite( material.depthWrite ); + state.setColorWrite( material.colorWrite ); state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); } @@ -24629,6 +24637,8 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { var currentDepthTest = null; var currentDepthWrite = null; + var currentColorWrite = null; + var currentDoubleSided = null; var currentFlipSided = null; @@ -24790,6 +24800,17 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { }; + this.setColorWrite = function ( colorWrite ) { + + if ( currentColorWrite !== colorWrite ) { + + gl.colorMask( colorWrite, colorWrite, colorWrite, colorWrite ); + currentColorWrite = colorWrite; + + } + + }; + this.setDoubleSided = function ( doubleSided ) { if ( currentDoubleSided !== doubleSided ) { @@ -24882,6 +24903,7 @@ THREE.WebGLState = function ( gl, paramThreeToGL ) { currentBlending = null; currentDepthTest = null; currentDepthWrite = null; + currentColorWrite = null; currentDoubleSided = null; currentFlipSided = null; diff --git a/build/three.min.js b/build/three.min.js index 6c7eff1ff43fdd..6d25be8b02fbb4 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -1,5 +1,5 @@ // threejs.org/license -'use strict';var THREE={REVISION:"71dev"};"object"===typeof module&&(module.exports=THREE);void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0a?-1:0qa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cg;g++)n=x[k++],v=u[2*n],n=u[2*n+1],v=new THREE.Vector2(v,n),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],t.normal.set(F[q++],F[q++],F[q]),r.normal.copy(t.normal));if(s)for(d=0;4>d;d++)q=3*x[k++],s=new THREE.Vector3(F[q++], -F[q++],F[q]),2!==d&&t.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);p&&(p=x[k++],p=w[p],t.color.setHex(p),r.color.setHex(p));if(b)for(d=0;4>d;d++)p=x[k++],p=w[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&r.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(r)}else{t=new THREE.Face3;t.a=x[k++];t.b=x[k++];t.c=x[k++];h&&(h=x[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1], -v=new THREE.Vector2(v,n),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],t.normal.set(F[q++],F[q++],F[q]));if(s)for(d=0;3>d;d++)q=3*x[k++],s=new THREE.Vector3(F[q++],F[q++],F[q]),t.vertexNormals.push(s);p&&(p=x[k++],t.color.setHex(w[p]));if(b)for(d=0;3>d;d++)p=x[k++],t.vertexColors.push(new THREE.Color(w[p]));c.faces.push(t)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1],v=new THREE.Vector2(v,n),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],t.normal.set(D[q++],D[q++],D[q]),r.normal.copy(t.normal));if(s)for(d=0;4>d;d++)q=3*x[k++],s=new THREE.Vector3(D[q++], +D[q++],D[q]),2!==d&&t.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);p&&(p=x[k++],p=w[p],t.color.setHex(p),r.color.setHex(p));if(b)for(d=0;4>d;d++)p=x[k++],p=w[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&r.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(r)}else{t=new THREE.Face3;t.a=x[k++];t.b=x[k++];t.c=x[k++];h&&(h=x[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1], +v=new THREE.Vector2(v,n),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],t.normal.set(D[q++],D[q++],D[q]));if(s)for(d=0;3>d;d++)q=3*x[k++],s=new THREE.Vector3(D[q++],D[q++],D[q]),t.vertexNormals.push(s);p&&(p=x[k++],t.color.setHex(w[p]));if(b)for(d=0;3>d;d++)p=x[k++],t.vertexColors.push(new THREE.Color(w[p]));c.faces.push(t)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;df||(F=b.origin.distanceTo(p),Fd.far||e.push({distance:F,point:l.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, -object:this}))}}else for(n=n.position.array,g=0;gf||(F=b.origin.distanceTo(p),Fd.far||e.push({distance:F,point:l.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(F=b.origin.distanceTo(p),Fd.far||e.push({distance:F,point:l.clone().applyMatrix4(this.matrixWorld), +THREE.BufferGeometry){var n=g.attributes;if(void 0!==n.index){var t=n.index.array,n=n.position.array,s=g.offsets;0===s.length&&(s=[{start:0,count:t.length,index:0}]);for(var r=0;rf||(D=b.origin.distanceTo(p),Dd.far||e.push({distance:D,point:l.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, +object:this}))}}else for(n=n.position.array,g=0;gf||(D=b.origin.distanceTo(p),Dd.far||e.push({distance:D,point:l.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(D=b.origin.distanceTo(p),Dd.far||e.push({distance:D,point:l.clone().applyMatrix4(this.matrixWorld), index:g,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(a){void 0===a&&(a=new THREE.Line(this.geometry,this.material,this.mode));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype); THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0g.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=p.position.array,s=k=0,w=r.length;k -g.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(s=this.material instanceof THREE.MeshFaceMaterial,r=!0===s?this.material.materials:null,t=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:F,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.type="Bone";this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; +g.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(s=this.material instanceof THREE.MeshFaceMaterial,r=!0===s?this.material.materials:null,t=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:D,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.type="Bone";this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(this.boneTextureHeight=this.boneTextureWidth=a=256h&&(e[v].counter+=1,k=e[v].hash+"_"+e[v].counter,k in r||(q={id:Qb++,faces3:[],materialIndex:v,vertices:0,numMorphTargets:l,numMorphNormals:p},r[k]=q,t.push(q))); +4294967296:65535,k,e={},l=b.morphTargets.length,p=b.morphNormals.length,q,r={},t=[],s=0,w=b.faces.length;sh&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in r||(q={id:Qb++,faces3:[],materialIndex:u,vertices:0,numMorphTargets:l,numMorphNormals:p},r[k]=q,t.push(q))); r[k].faces3.push(s);r[k].vertices+=3}f[g]=t;b.groupsNeedUpdate=!1}f=Ua[b.id];g=0;for(d=f.length;gY;Y++)pa=I[Y],Na[Ra]=pa.x,Na[Ra+1]=pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=H.x,Na[Ra+1]=H.y,Na[Ra+2]=H.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER, -w.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Na,x)}if(vb&&Hb){y=0;for(z=$.length;yY;Y++)ab=U[Y],Ab[kb]=ab.x,Ab[kb+1]=ab.y,kb+=2;0Y;Y++)oa=O[Y],lb[yb]=oa.x,lb[yb+1]=oa.y,yb+=2;0Y;Y++)pa=I[Y],Na[Ra]=pa.x,Na[Ra+1]=pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=H.x,Na[Ra+1]=H.y,Na[Ra+2]=H.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER, +v.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Na,D)}if(vb&&Hb){y=0;for(z=$.length;yY;Y++)ab=U[Y],Ab[kb]=ab.x,Ab[kb+1]=ab.y,kb+=2;0Y;Y++)oa=O[Y],lb[yb]=oa.x,lb[yb+1]=oa.y,yb+=2;0ya;ya++)gb[ya]=!B.autoScaleCubemaps||Rb||Ib?Ib?X.image[ya].image:X.image[ya]:E(X.image[ya],qc);var Yb=gb[0],Zb=THREE.Math.isPowerOfTwo(Yb.width)&&THREE.Math.isPowerOfTwo(Yb.height),Wa=I(X.format),tb=I(X.type);A(m.TEXTURE_CUBE_MAP,X,Zb);for(ya=0;6>ya;ya++)if(Rb)for(var hb,$b=gb[ya].mipmaps,Fb= 0,Sb=$b.length;Fb=Wb&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Wb);Mb+=1;return a}function w(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function y(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,I(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,I(b.wrapT)),m.texParameteri(a, -m.TEXTURE_MAG_FILTER,I(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,I(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,D(b.magFilter)),m.texParameteri(a, -m.TEXTURE_MIN_FILTER,D(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=da.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1=Wb&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Wb);Mb+=1;return a}function w(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function y(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,I(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,I(b.wrapT)),m.texParameteri(a, +m.TEXTURE_MAG_FILTER,I(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,I(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,z(b.magFilter)),m.texParameteri(a, +m.TEXTURE_MIN_FILTER,z(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=da.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function G(a,b){m.bindRenderbuffer(m.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer? -(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_COMPONENT16,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_STENCIL,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a)):m.renderbufferStorage(m.RENDERBUFFER,m.RGBA4,b.width,b.height)}function z(a){a instanceof THREE.WebGLRenderTargetCube?(m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture), -m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function D(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function I(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT; +(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_COMPONENT16,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_STENCIL,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a)):m.renderbufferStorage(m.RENDERBUFFER,m.RGBA4,b.width,b.height)}function F(a){a instanceof THREE.WebGLRenderTargetCube?(m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture), +m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function z(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function I(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT; if(a===THREE.NearestFilter)return m.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return m.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return m.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return m.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return m.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return m.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return m.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return m.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return m.UNSIGNED_SHORT_5_5_5_1; if(a===THREE.UnsignedShort565Type)return m.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return m.BYTE;if(a===THREE.ShortType)return m.SHORT;if(a===THREE.UnsignedShortType)return m.UNSIGNED_SHORT;if(a===THREE.IntType)return m.INT;if(a===THREE.UnsignedIntType)return m.UNSIGNED_INT;if(a===THREE.FloatType)return m.FLOAT;b=da.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return m.ALPHA;if(a===THREE.RGBFormat)return m.RGB;if(a===THREE.RGBAFormat)return m.RGBA; if(a===THREE.LuminanceFormat)return m.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return m.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return m.FUNC_ADD;if(a===THREE.SubtractEquation)return m.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return m.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return m.ZERO;if(a===THREE.OneFactor)return m.ONE;if(a===THREE.SrcColorFactor)return m.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return m.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return m.SRC_ALPHA; @@ -557,10 +557,10 @@ m.vertexAttrib2fv(b.uv2,d.defaultAttributeValues.uv2));d.skinning&&0<=b.skinInde 3):f instanceof THREE.Line?(f=f.mode===THREE.LineStrip?m.LINE_STRIP:m.LINES,W.setLineWidth(d.linewidth*H),m.drawArrays(f,0,e.__webglLineCount),B.info.render.calls++):f instanceof THREE.PointCloud&&(m.drawArrays(m.POINTS,0,e.__webglParticleCount),B.info.render.calls++,B.info.render.points+=e.__webglParticleCount)}};this.render=function(a,b,c,d){if(!1===b instanceof THREE.Camera)THREE.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");else{var g=a.fog;ta="";ub=-1;vb=null; Ob=!0;!0===a.autoUpdate&&a.updateMatrixWorld();void 0===b.parent&&b.updateMatrixWorld();a.traverse(function(a){a instanceof THREE.SkinnedMesh&&a.skeleton.update()});b.matrixWorldInverse.getInverse(b.matrixWorld);db.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);cb.setFromMatrix(db);ca.length=0;Ka.length=0;Qa.length=0;Xa.length=0;Ya.length=0;h(a);!0===B.sortObjects&&(Ka.sort(e),Qa.sort(f));zc.render(a,b);B.info.render.calls=0;B.info.render.vertices=0;B.info.render.faces=0;B.info.render.points= 0;this.setRenderTarget(c);(this.autoClear||d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);d=0;for(var m=qa.length;df;f++){a.__webglFramebuffer[f]= m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,h,g.__webglTexture,0);G(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: @@ -577,7 +577,7 @@ THREE.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c] break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;default:d=a.getExtension(c)}null===d&&THREE.warn("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}; THREE.WebGLProgram=function(){var a=0;return function(b,c,d,e){var f=b.context,g=d.defines,h=d.__webglShader.uniforms,k=d.attributes,l=d.__webglShader.vertexShader,p=d.__webglShader.fragmentShader,q=d.index0AttributeName;void 0===q&&!0===e.morphTargets&&(q="position");var n="SHADOWMAP_TYPE_BASIC";e.shadowMapType===THREE.PCFShadowMap?n="SHADOWMAP_TYPE_PCF":e.shadowMapType===THREE.PCFSoftShadowMap&&(n="SHADOWMAP_TYPE_PCF_SOFT");var t="ENVMAP_TYPE_CUBE",s="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY"; if(e.envMap){switch(d.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:t="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:t="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:t="ENVMAP_TYPE_SPHERE"}switch(d.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:s="ENVMAP_MODE_REFRACTION"}switch(d.combine){case THREE.MultiplyOperation:r="ENVMAP_BLENDING_MULTIPLY"; -break;case THREE.MixOperation:r="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:r="ENVMAP_BLENDING_ADD"}}var u=0L;L++)I[L]=new THREE.Vector3,z[L]=new THREE.Vector3;I=D.shadowCascadeNearZ[H];D=D.shadowCascadeFarZ[H];z[0].set(-1,-1,I);z[1].set(1,-1,I);z[2].set(-1,1,I);z[3].set(1,1,I);z[4].set(-1,-1,D);z[5].set(1,-1,D);z[6].set(-1,1,D);z[7].set(1,1,D);M.originalCamera=u;z=new THREE.Gyroscope;z.position.copy(A.shadowCascadeOffset);z.add(M);z.add(M.target);u.add(z);A.shadowCascadeArray[G]=M}H=A;I=G;D=H.shadowCascadeArray[I];D.position.copy(H.position); -D.target.position.copy(H.target.position);D.lookAt(D.target);D.shadowCameraVisible=H.shadowCameraVisible;D.shadowDarkness=H.shadowDarkness;D.shadowBias=H.shadowCascadeBias[I];z=H.shadowCascadeNearZ[I];H=H.shadowCascadeFarZ[I];D=D.pointsFrustum;D[0].z=z;D[1].z=z;D[2].z=z;D[3].z=z;D[4].z=H;D[5].z=H;D[6].z=H;D[7].z=H;U[E]=M;E++}else U[E]=A,E++;v=0;for(y=U.length;vL;L++)I[L]=new THREE.Vector3,F[L]=new THREE.Vector3;I=z.shadowCascadeNearZ[H];z=z.shadowCascadeFarZ[H];F[0].set(-1,-1,I);F[1].set(1,-1,I);F[2].set(-1,1,I);F[3].set(1,1,I);F[4].set(-1,-1,z);F[5].set(1,-1,z);F[6].set(-1,1,z);F[7].set(1,1,z);M.originalCamera=v;F=new THREE.Gyroscope;F.position.copy(A.shadowCascadeOffset);F.add(M);F.add(M.target);v.add(F);A.shadowCascadeArray[G]=M}H=A;I=G;z=H.shadowCascadeArray[I];z.position.copy(H.position); +z.target.position.copy(H.target.position);z.lookAt(z.target);z.shadowCameraVisible=H.shadowCameraVisible;z.shadowDarkness=H.shadowDarkness;z.shadowBias=H.shadowCascadeBias[I];F=H.shadowCascadeNearZ[I];H=H.shadowCascadeFarZ[I];z=z.pointsFrustum;z[0].z=F;z[1].z=F;z[2].z=F;z[3].z=F;z[4].z=H;z[5].z=H;z[6].z=H;z[7].z=H;U[E]=M;E++}else U[E]=A,E++;u=0;for(y=U.length;u -H;H++)I=D[H],I.copy(z[H]),I.unproject(G),I.applyMatrix4(E.matrixWorldInverse),I.xt.x&&(t.x=I.x),I.yt.y&&(t.y=I.y),I.zt.z&&(t.z=I.z);E.left=n.x;E.right=t.x;E.top=t.y;E.bottom=n.y;E.updateProjectionMatrix()}E=A.shadowMap;z=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);s.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(s);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& -(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();z.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);z.multiply(G.projectionMatrix);z.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(E);a.clear();r.length=0;e(c,c,G);A=0;for(E=r.length;A +H;H++)I=z[H],I.copy(F[H]),I.unproject(G),I.applyMatrix4(E.matrixWorldInverse),I.xt.x&&(t.x=I.x),I.yt.y&&(t.y=I.y),I.zt.z&&(t.z=I.z);E.left=n.x;E.right=t.x;E.top=t.y;E.bottom=n.y;E.updateProjectionMatrix()}E=A.shadowMap;F=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);s.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(s);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& +(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();F.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);F.multiply(G.projectionMatrix);F.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(E);a.clear();r.length=0;e(c,c,G);A=0;for(E=r.length;A 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); w.compileShader(L);w.compileShader(P);w.attachShader(H,L);w.attachShader(H,P);w.linkProgram(H);E=H;v=w.getAttribLocation(E,"position");x=w.getAttribLocation(E,"uv");c=w.getUniformLocation(E,"uvOffset");d=w.getUniformLocation(E,"uvScale");e=w.getUniformLocation(E,"rotation");f=w.getUniformLocation(E,"scale");g=w.getUniformLocation(E,"color");h=w.getUniformLocation(E,"map");k=w.getUniformLocation(E,"opacity");l=w.getUniformLocation(E,"modelViewMatrix");p=w.getUniformLocation(E,"projectionMatrix");q= w.getUniformLocation(E,"fogType");n=w.getUniformLocation(E,"fogDensity");t=w.getUniformLocation(E,"fogNear");s=w.getUniformLocation(E,"fogFar");r=w.getUniformLocation(E,"fogColor");u=w.getUniformLocation(E,"alphaTest");H=document.createElement("canvas");H.width=8;H.height=8;L=H.getContext("2d");L.fillStyle="white";L.fillRect(0,0,8,8);G=new THREE.Texture(H);G.needsUpdate=!0}w.useProgram(E);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(p,!1,M.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);L=H=0;(P=U.fog)?(w.uniform3f(r,P.color.r,P.color.g,P.color.b),P instanceof THREE.Fog?(w.uniform1f(t,P.near),w.uniform1f(s,P.far),w.uniform1i(q,1),L=H=1):P instanceof THREE.FogExp2&&(w.uniform1f(n,P.density),w.uniform1i(q,2),L=H=2)):(w.uniform1i(q,0),L=H=0);for(var P=0,N=b.length;P< -N;P++){var R=b[P];R._modelViewMatrix.multiplyMatrices(M.matrixWorldInverse,R.matrixWorld);R.z=-R._modelViewMatrix.elements[14]}b.sort(F);for(var V=[],P=0,N=b.length;Pe)return null;var f=[],g=[],h=[],k,l,p;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=l;e<=k&&(k=0);l=k+1;e<=l&&(l=0);p=l+1;e<=p&&(p=0);var n;a:{var t=n=void 0,s=void 0,r=void 0, -u=void 0,v=void 0,x=void 0,F=void 0,w=void 0,t=a[g[k]].x,s=a[g[k]].y,r=a[g[l]].x,u=a[g[l]].y,v=a[g[p]].x,x=a[g[p]].y;if(1E-10>(r-t)*(x-s)-(u-s)*(v-t))n=!1;else{var y=void 0,A=void 0,E=void 0,G=void 0,z=void 0,D=void 0,I=void 0,U=void 0,M=void 0,H=void 0,M=U=I=w=F=void 0,y=v-r,A=x-u,E=t-v,G=s-x,z=r-t,D=u-s;for(n=0;n(r-t)*(x-s)-(u-s)*(v-t))n=!1;else{var y=void 0,A=void 0,E=void 0,G=void 0,F=void 0,z=void 0,I=void 0,U=void 0,M=void 0,H=void 0,M=U=I=w=D=void 0,y=v-r,A=x-u,E=t-v,G=s-x,F=r-t,z=u-s;for(n=0;nG||G>E)return[];k=l*p-k*q;if(0>k||k>E)return[]}else{if(0d?[]:k==d?f?[]:[g]:a<=d?[g,h]: [g,l]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]); -if(!d)return!1;d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c -H){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(q=D;qf&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c +H){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(q=z;qh;h++)l=k[h].x+":"+k[h].y,l=p[l],void 0!==l&&(k[h]=l);return q.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a* a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)}; THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()};THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve; @@ -715,27 +715,27 @@ f;d.nextKey=g}g.time>=this.currentTime?f.interpolate(g,this.currentTime):f.inter THREE.KeyFrameAnimation.prototype.getPrevKeyWith=function(a,b,c){b=this.data.hierarchy[b].keys;for(c=0<=c?c:c+b.length;0<=c;c--)if(b[c].hasTarget(a))return b[c];return b[b.length-1]};THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);a=this.duration/this.frames;var b=Math.floor(this.currentTime/a);b!=this.currentFrame&&(this.mesh.morphTargetInfluences[this.lastFrame]=0,this.mesh.morphTargetInfluences[this.currentFrame]= 1,this.mesh.morphTargetInfluences[b]=0,this.lastFrame=this.currentFrame,this.currentFrame=b);this.mesh.morphTargetInfluences[b]=this.currentTime%a/a;this.mesh.morphTargetInfluences[this.lastFrame]=1-this.mesh.morphTargetInfluences[b]}}}; -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,r){var u,v=h.widthSegments,x=h.heightSegments,F=e/2,w=f/2,y=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",x=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",v=h.depthSegments;var A=v+1,E=x+1,G=e/v,z=f/x,D=new THREE.Vector3;D[u]=0=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(O=a.length;0<=--O;){c=O;d=O-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;ed?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(O=a.length;0<=--O;){c=O;d=O-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;c Date: Wed, 25 Feb 2015 23:23:40 +0100 Subject: [PATCH 214/333] Editor: Added script syntax validator. --- editor/css/main.css | 16 + editor/index.html | 1 + editor/js/Script.js | 93 +- editor/js/libs/esprima.js | 4156 +++++++++++++++++++++++++++++++++++++ 4 files changed, 4262 insertions(+), 4 deletions(-) create mode 100644 editor/js/libs/esprima.js diff --git a/editor/css/main.css b/editor/css/main.css index 59d7904c66c9ed..8e4319c37717d1 100644 --- a/editor/css/main.css +++ b/editor/css/main.css @@ -67,6 +67,8 @@ textarea, input { outline: none; } /* osx */ display: none; } +/* CodeMirror */ + .CodeMirror { position: absolute !important; @@ -76,6 +78,20 @@ textarea, input { outline: none; } /* osx */ } + .CodeMirror .errorLine { + + background: rgba(255,0,0,0.25); + + } + + .CodeMirror .esprima-error { + + color: #f00; + text-align: right; + padding: 0px 20px; + + } + /* scene types */ .type { diff --git a/editor/index.html b/editor/index.html index 51544dfce46c3c..4ac1c041e8cd8b 100644 --- a/editor/index.html +++ b/editor/index.html @@ -41,6 +41,7 @@ + diff --git a/editor/js/Script.js b/editor/js/Script.js index 80fa696be5449b..abcb6d24924543 100644 --- a/editor/js/Script.js +++ b/editor/js/Script.js @@ -15,7 +15,7 @@ var Script = function ( editor ) { var header = new UI.Panel(); header.setPadding( '10px' ); container.add( header ); - + var title = new UI.Text().setColor( '#fff' ); header.add( title ); @@ -59,16 +59,101 @@ var Script = function ( editor ) { clearTimeout( delay ); delay = setTimeout( function () { - currentScript.source = codemirror.getValue(); + var value = codemirror.getValue(); + + if ( validate( value ) ) { + + currentScript.source = value; + signals.scriptChanged.dispatch( currentScript ); - signals.scriptChanged.dispatch( currentScript ); + } }, 300 ); }); + // validate + + var errorLines = []; + var widgets = []; + + var validate = function ( string ) { + + var syntax, errors; + + return codemirror.operation( function () { + + while ( errorLines.length > 0 ) { + + codemirror.removeLineClass( errorLines.shift(), 'background', 'errorLine' ); + + } + + for ( var i = 0; i < widgets.length; i ++ ) { + + codemirror.removeLineWidget( widgets[ i ] ); + + } + + widgets.length = 0; + + // + + try { + + syntax = esprima.parse( string, { tolerant: true } ); + errors = syntax.errors; + + for ( var i = 0; i < errors.length; i ++ ) { + + var error = errors[ i ]; + + var message = document.createElement( 'div' ); + message.className = 'esprima-error'; + message.textContent = error.message.replace(/Line [0-9]+: /, ''); + + var lineNumber = error.lineNumber - 1; + errorLines.push( lineNumber ); + + codemirror.addLineClass( lineNumber, 'background', 'errorLine' ); + + var widget = codemirror.addLineWidget( + lineNumber, + message + ); + + widgets.push( widget ); + + } + + } catch ( error ) { + + var message = document.createElement( 'div' ); + message.className = 'esprima-error'; + message.textContent = error.message.replace(/Line [0-9]+: /, ''); + + var lineNumber = error.lineNumber - 1; + errorLines.push( lineNumber ); + + codemirror.addLineClass( lineNumber, 'background', 'errorLine' ); + + var widget = codemirror.addLineWidget( + lineNumber, + message + ); + + widgets.push( widget ); + + } + + return errorLines.length === 0; + + }); + + }; + // - + signals.editorCleared.add( function () { container.setDisplay( 'none' ); diff --git a/editor/js/libs/esprima.js b/editor/js/libs/esprima.js new file mode 100644 index 00000000000000..a1f80c83e13445 --- /dev/null +++ b/editor/js/libs/esprima.js @@ -0,0 +1,4156 @@ +/* + Copyright (C) 2013 Ariya Hidayat + Copyright (C) 2013 Thaddee Tyl + Copyright (C) 2013 Mathias Bynens + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Mathias Bynens + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Kris Kowal + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +(function (root, factory) { + 'use strict'; + + // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, + // Rhino, and plain browser loading. + + /* istanbul ignore next */ + if (typeof define === 'function' && define.amd) { + define(['exports'], factory); + } else if (typeof exports !== 'undefined') { + factory(exports); + } else { + factory((root.esprima = {})); + } +}(this, function (exports) { + 'use strict'; + + var Token, + TokenName, + FnExprTokens, + Syntax, + PlaceHolders, + PropertyKind, + Messages, + Regex, + source, + strict, + index, + lineNumber, + lineStart, + length, + lookahead, + state, + extra; + + Token = { + BooleanLiteral: 1, + EOF: 2, + Identifier: 3, + Keyword: 4, + NullLiteral: 5, + NumericLiteral: 6, + Punctuator: 7, + StringLiteral: 8, + RegularExpression: 9 + }; + + TokenName = {}; + TokenName[Token.BooleanLiteral] = 'Boolean'; + TokenName[Token.EOF] = ''; + TokenName[Token.Identifier] = 'Identifier'; + TokenName[Token.Keyword] = 'Keyword'; + TokenName[Token.NullLiteral] = 'Null'; + TokenName[Token.NumericLiteral] = 'Numeric'; + TokenName[Token.Punctuator] = 'Punctuator'; + TokenName[Token.StringLiteral] = 'String'; + TokenName[Token.RegularExpression] = 'RegularExpression'; + + // A function following one of those tokens is an expression. + FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new', + 'return', 'case', 'delete', 'throw', 'void', + // assignment operators + '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', + '&=', '|=', '^=', ',', + // binary/unary operators + '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&', + '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=', + '<=', '<', '>', '!=', '!==']; + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + ArrowFunctionExpression: 'ArrowFunctionExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SwitchStatement: 'SwitchStatement', + SwitchCase: 'SwitchCase', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement' + }; + + PlaceHolders = { + ArrowParameterPlaceHolder: { + type: 'ArrowParameterPlaceHolder' + } + }; + + PropertyKind = { + Data: 1, + Get: 2, + Set: 4 + }; + + // Error messages should be identical to V8. + Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', + AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', + AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode' + }; + + // See also tools/generate-unicode-regex.py. + Regex = { + NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'), + NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]') + }; + + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + + function assert(condition, message) { + /* istanbul ignore if */ + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + + function isDecimalDigit(ch) { + return (ch >= 0x30 && ch <= 0x39); // 0..9 + } + + function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; + } + + function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; + } + + + // 7.2 White Space + + function isWhiteSpace(ch) { + return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); + } + + // 7.3 Line Terminators + + function isLineTerminator(ch) { + return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); + } + + // 7.6 Identifier Names and Identifiers + + function isIdentifierStart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); + } + + function isIdentifierPart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch >= 0x30 && ch <= 0x39) || // 0..9 + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); + } + + // 7.6.1.2 Future Reserved Words + + function isFutureReservedWord(id) { + switch (id) { + case 'class': + case 'enum': + case 'export': + case 'extends': + case 'import': + case 'super': + return true; + default: + return false; + } + } + + function isStrictModeReservedWord(id) { + switch (id) { + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'yield': + case 'let': + return true; + default: + return false; + } + } + + function isRestrictedWord(id) { + return id === 'eval' || id === 'arguments'; + } + + // 7.6.1.1 Keywords + + function isKeyword(id) { + if (strict && isStrictModeReservedWord(id)) { + return true; + } + + // 'const' is specialized as Keyword in V8. + // 'yield' and 'let' are for compatibility with SpiderMonkey and ES.next. + // Some others are from future reserved words. + + switch (id.length) { + case 2: + return (id === 'if') || (id === 'in') || (id === 'do'); + case 3: + return (id === 'var') || (id === 'for') || (id === 'new') || + (id === 'try') || (id === 'let'); + case 4: + return (id === 'this') || (id === 'else') || (id === 'case') || + (id === 'void') || (id === 'with') || (id === 'enum'); + case 5: + return (id === 'while') || (id === 'break') || (id === 'catch') || + (id === 'throw') || (id === 'const') || (id === 'yield') || + (id === 'class') || (id === 'super'); + case 6: + return (id === 'return') || (id === 'typeof') || (id === 'delete') || + (id === 'switch') || (id === 'export') || (id === 'import'); + case 7: + return (id === 'default') || (id === 'finally') || (id === 'extends'); + case 8: + return (id === 'function') || (id === 'continue') || (id === 'debugger'); + case 10: + return (id === 'instanceof'); + default: + return false; + } + } + + // 7.4 Comments + + function addComment(type, value, start, end, loc) { + var comment; + + assert(typeof start === 'number', 'Comment must have valid position'); + + // Because the way the actual token is scanned, often the comments + // (if any) are skipped twice during the lexical analysis. + // Thus, we need to skip adding a comment if the comment array already + // handled it. + if (state.lastCommentStart >= start) { + return; + } + state.lastCommentStart = start; + + comment = { + type: type, + value: value + }; + if (extra.range) { + comment.range = [start, end]; + } + if (extra.loc) { + comment.loc = loc; + } + extra.comments.push(comment); + if (extra.attachComment) { + extra.leadingComments.push(comment); + extra.trailingComments.push(comment); + } + } + + function skipSingleLineComment(offset) { + var start, loc, ch, comment; + + start = index - offset; + loc = { + start: { + line: lineNumber, + column: index - lineStart - offset + } + }; + + while (index < length) { + ch = source.charCodeAt(index); + ++index; + if (isLineTerminator(ch)) { + if (extra.comments) { + comment = source.slice(start + offset, index - 1); + loc.end = { + line: lineNumber, + column: index - lineStart - 1 + }; + addComment('Line', comment, start, index - 1, loc); + } + if (ch === 13 && source.charCodeAt(index) === 10) { + ++index; + } + ++lineNumber; + lineStart = index; + return; + } + } + + if (extra.comments) { + comment = source.slice(start + offset, index); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + addComment('Line', comment, start, index, loc); + } + } + + function skipMultiLineComment() { + var start, loc, ch, comment; + + if (extra.comments) { + start = index - 2; + loc = { + start: { + line: lineNumber, + column: index - lineStart - 2 + } + }; + } + + while (index < length) { + ch = source.charCodeAt(index); + if (isLineTerminator(ch)) { + if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) { + ++index; + } + ++lineNumber; + ++index; + lineStart = index; + if (index >= length) { + throwUnexpectedToken(); + } + } else if (ch === 0x2A) { + // Block comment ends with '*/'. + if (source.charCodeAt(index + 1) === 0x2F) { + ++index; + ++index; + if (extra.comments) { + comment = source.slice(start + 2, index - 2); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + addComment('Block', comment, start, index, loc); + } + return; + } + ++index; + } else { + ++index; + } + } + + throwUnexpectedToken(); + } + + function skipComment() { + var ch, start; + + start = (index === 0); + while (index < length) { + ch = source.charCodeAt(index); + + if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === 0x0D && source.charCodeAt(index) === 0x0A) { + ++index; + } + ++lineNumber; + lineStart = index; + start = true; + } else if (ch === 0x2F) { // U+002F is '/' + ch = source.charCodeAt(index + 1); + if (ch === 0x2F) { + ++index; + ++index; + skipSingleLineComment(2); + start = true; + } else if (ch === 0x2A) { // U+002A is '*' + ++index; + ++index; + skipMultiLineComment(); + } else { + break; + } + } else if (start && ch === 0x2D) { // U+002D is '-' + // U+003E is '>' + if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) { + // '-->' is a single-line comment + index += 3; + skipSingleLineComment(3); + } else { + break; + } + } else if (ch === 0x3C) { // U+003C is '<' + if (source.slice(index + 1, index + 4) === '!--') { + ++index; // `<` + ++index; // `!` + ++index; // `-` + ++index; // `-` + skipSingleLineComment(4); + } else { + break; + } + } else { + break; + } + } + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && isHexDigit(source[index])) { + ch = source[index++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanUnicodeCodePointEscape() { + var ch, code, cu1, cu2; + + ch = source[index]; + code = 0; + + // At least, one hex digit is required. + if (ch === '}') { + throwUnexpectedToken(); + } + + while (index < length) { + ch = source[index++]; + if (!isHexDigit(ch)) { + break; + } + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + + if (code > 0x10FFFF || ch !== '}') { + throwUnexpectedToken(); + } + + // UTF-16 Encoding + if (code <= 0xFFFF) { + return String.fromCharCode(code); + } + cu1 = ((code - 0x10000) >> 10) + 0xD800; + cu2 = ((code - 0x10000) & 1023) + 0xDC00; + return String.fromCharCode(cu1, cu2); + } + + function getEscapedIdentifier() { + var ch, id; + + ch = source.charCodeAt(index++); + id = String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + if (source.charCodeAt(index) !== 0x75) { + throwUnexpectedToken(); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { + throwUnexpectedToken(); + } + id = ch; + } + + while (index < length) { + ch = source.charCodeAt(index); + if (!isIdentifierPart(ch)) { + break; + } + ++index; + id += String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + id = id.substr(0, id.length - 1); + if (source.charCodeAt(index) !== 0x75) { + throwUnexpectedToken(); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { + throwUnexpectedToken(); + } + id += ch; + } + } + + return id; + } + + function getIdentifier() { + var start, ch; + + start = index++; + while (index < length) { + ch = source.charCodeAt(index); + if (ch === 0x5C) { + // Blackslash (U+005C) marks Unicode escape sequence. + index = start; + return getEscapedIdentifier(); + } + if (isIdentifierPart(ch)) { + ++index; + } else { + break; + } + } + + return source.slice(start, index); + } + + function scanIdentifier() { + var start, id, type; + + start = index; + + // Backslash (U+005C) starts an escaped character. + id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier(); + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + type = Token.Identifier; + } else if (isKeyword(id)) { + type = Token.Keyword; + } else if (id === 'null') { + type = Token.NullLiteral; + } else if (id === 'true' || id === 'false') { + type = Token.BooleanLiteral; + } else { + type = Token.Identifier; + } + + return { + type: type, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + + // 7.7 Punctuators + + function scanPunctuator() { + var start = index, + code = source.charCodeAt(index), + code2, + ch1 = source[index], + ch2, + ch3, + ch4; + + switch (code) { + + // Check for most common single-character punctuators. + case 0x2E: // . dot + case 0x28: // ( open bracket + case 0x29: // ) close bracket + case 0x3B: // ; semicolon + case 0x2C: // , comma + case 0x7B: // { open curly brace + case 0x7D: // } close curly brace + case 0x5B: // [ + case 0x5D: // ] + case 0x3A: // : + case 0x3F: // ? + case 0x7E: // ~ + ++index; + if (extra.tokenize) { + if (code === 0x28) { + extra.openParenToken = extra.tokens.length; + } else if (code === 0x7B) { + extra.openCurlyToken = extra.tokens.length; + } + } + return { + type: Token.Punctuator, + value: String.fromCharCode(code), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + default: + code2 = source.charCodeAt(index + 1); + + // '=' (U+003D) marks an assignment or comparison operator. + if (code2 === 0x3D) { + switch (code) { + case 0x2B: // + + case 0x2D: // - + case 0x2F: // / + case 0x3C: // < + case 0x3E: // > + case 0x5E: // ^ + case 0x7C: // | + case 0x25: // % + case 0x26: // & + case 0x2A: // * + index += 2; + return { + type: Token.Punctuator, + value: String.fromCharCode(code) + String.fromCharCode(code2), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + case 0x21: // ! + case 0x3D: // = + index += 2; + + // !== and === + if (source.charCodeAt(index) === 0x3D) { + ++index; + } + return { + type: Token.Punctuator, + value: source.slice(start, index), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + } + } + + // 4-character punctuator: >>>= + + ch4 = source.substr(index, 4); + + if (ch4 === '>>>=') { + index += 4; + return { + type: Token.Punctuator, + value: ch4, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 3-character punctuators: === !== >>> <<= >>= + + ch3 = ch4.substr(0, 3); + + if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') { + index += 3; + return { + type: Token.Punctuator, + value: ch3, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // Other 2-character punctuators: ++ -- << >> && || + ch2 = ch3.substr(0, 2); + + if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') { + index += 2; + return { + type: Token.Punctuator, + value: ch2, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 1-character punctuators: < > = ! + - * % & | ^ / + + if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + throwUnexpectedToken(); + } + + // 7.8.3 Numeric Literals + + function scanHexLiteral(start) { + var number = ''; + + while (index < length) { + if (!isHexDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (number.length === 0) { + throwUnexpectedToken(); + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwUnexpectedToken(); + } + + return { + type: Token.NumericLiteral, + value: parseInt('0x' + number, 16), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanBinaryLiteral(start) { + var ch, number; + + number = ''; + + while (index < length) { + ch = source[index]; + if (ch !== '0' && ch !== '1') { + break; + } + number += source[index++]; + } + + if (number.length === 0) { + // only 0b or 0B + throwUnexpectedToken(); + } + + if (index < length) { + ch = source.charCodeAt(index); + /* istanbul ignore else */ + if (isIdentifierStart(ch) || isDecimalDigit(ch)) { + throwUnexpectedToken(); + } + } + + return { + type: Token.NumericLiteral, + value: parseInt(number, 2), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanOctalLiteral(prefix, start) { + var number, octal; + + if (isOctalDigit(prefix)) { + octal = true; + number = '0' + source[index++]; + } else { + octal = false; + ++index; + number = ''; + } + + while (index < length) { + if (!isOctalDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (!octal && number.length === 0) { + // only 0o or 0O + throwUnexpectedToken(); + } + + if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { + throwUnexpectedToken(); + } + + return { + type: Token.NumericLiteral, + value: parseInt(number, 8), + octal: octal, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function isImplicitOctalLiteral() { + var i, ch; + + // Implicit octal, unless there is a non-octal digit. + // (Annex B.1.1 on Numeric Literals) + for (i = index + 1; i < length; ++i) { + ch = source[i]; + if (ch === '8' || ch === '9') { + return false; + } + if (!isOctalDigit(ch)) { + return true; + } + } + + return true; + } + + function scanNumericLiteral() { + var number, start, ch; + + ch = source[index]; + assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index; + number = ''; + if (ch !== '.') { + number = source[index++]; + ch = source[index]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + // Octal number in ES6 starts with '0o'. + // Binary number in ES6 starts with '0b'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + ++index; + return scanHexLiteral(start); + } + if (ch === 'b' || ch === 'B') { + ++index; + return scanBinaryLiteral(start); + } + if (ch === 'o' || ch === 'O') { + return scanOctalLiteral(ch, start); + } + + if (isOctalDigit(ch)) { + if (isImplicitOctalLiteral()) { + return scanOctalLiteral(ch, start); + } + } + } + + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === '.') { + number += source[index++]; + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === 'e' || ch === 'E') { + number += source[index++]; + + ch = source[index]; + if (ch === '+' || ch === '-') { + number += source[index++]; + } + if (isDecimalDigit(source.charCodeAt(index))) { + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + } else { + throwUnexpectedToken(); + } + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwUnexpectedToken(); + } + + return { + type: Token.NumericLiteral, + value: parseFloat(number), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.8.4 String Literals + + function scanStringLiteral() { + var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart; + startLineNumber = lineNumber; + startLineStart = lineStart; + + quote = source[index]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index; + ++index; + + while (index < length) { + ch = source[index++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source[index++]; + if (!ch || !isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'u': + case 'x': + if (source[index] === '{') { + ++index; + str += scanUnicodeCodePointEscape(); + } else { + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + str += unescaped; + } else { + index = restore; + str += ch; + } + } + break; + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + + default: + if (isOctalDigit(ch)) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + if (code !== 0) { + octal = true; + } + + if (index < length && isOctalDigit(source[index])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source[index++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + isOctalDigit(source[index])) { + code = code * 8 + '01234567'.indexOf(source[index++]); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + lineStart = index; + } + } else if (isLineTerminator(ch.charCodeAt(0))) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + throwUnexpectedToken(); + } + + return { + type: Token.StringLiteral, + value: str, + octal: octal, + startLineNumber: startLineNumber, + startLineStart: startLineStart, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function testRegExp(pattern, flags) { + var tmp = pattern, + value; + + if (flags.indexOf('u') >= 0) { + // Replace each astral symbol and every Unicode code point + // escape sequence with a single ASCII symbol to avoid throwing on + // regular expressions that are only valid in combination with the + // `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it + // would be replaced by `[x-b]` which throws an error. + tmp = tmp + .replace(/\\u\{([0-9a-fA-F]+)\}/g, function ($0, $1) { + if (parseInt($1, 16) <= 0x10FFFF) { + return 'x'; + } + throwError(Messages.InvalidRegExp); + }) + .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 'x'); + } + + // First, detect invalid regular expressions. + try { + value = new RegExp(tmp); + } catch (e) { + throwError(Messages.InvalidRegExp); + } + + // Return a regular expression object for this pattern-flag pair, or + // `null` in case the current environment doesn't support the flags it + // uses. + try { + return new RegExp(pattern, flags); + } catch (exception) { + return null; + } + } + + function scanRegExpBody() { + var ch, str, classMarker, terminated, body; + + ch = source[index]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source[index++]; + + classMarker = false; + terminated = false; + while (index < length) { + ch = source[index++]; + str += ch; + if (ch === '\\') { + ch = source[index++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch.charCodeAt(0))) { + throwError(Messages.UnterminatedRegExp); + } + str += ch; + } else if (isLineTerminator(ch.charCodeAt(0))) { + throwError(Messages.UnterminatedRegExp); + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } + } + } + + if (!terminated) { + throwError(Messages.UnterminatedRegExp); + } + + // Exclude leading and trailing slash. + body = str.substr(1, str.length - 2); + return { + value: body, + literal: str + }; + } + + function scanRegExpFlags() { + var ch, str, flags, restore; + + str = ''; + flags = ''; + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch.charCodeAt(0))) { + break; + } + + ++index; + if (ch === '\\' && index < length) { + ch = source[index]; + if (ch === 'u') { + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + flags += ch; + for (str += '\\u'; restore < index; ++restore) { + str += source[restore]; + } + } else { + index = restore; + flags += 'u'; + str += '\\u'; + } + tolerateUnexpectedToken(); + } else { + str += '\\'; + tolerateUnexpectedToken(); + } + } else { + flags += ch; + str += ch; + } + } + + return { + value: flags, + literal: str + }; + } + + function scanRegExp() { + var start, body, flags, value; + + lookahead = null; + skipComment(); + start = index; + + body = scanRegExpBody(); + flags = scanRegExpFlags(); + value = testRegExp(body.value, flags.value); + + if (extra.tokenize) { + return { + type: Token.RegularExpression, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + return { + literal: body.literal + flags.literal, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + start: start, + end: index + }; + } + + function collectRegex() { + var pos, loc, regex, token; + + skipComment(); + + pos = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + regex = scanRegExp(); + + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + /* istanbul ignore next */ + if (!extra.tokenize) { + // Pop the previous token, which is likely '/' or '/=' + if (extra.tokens.length > 0) { + token = extra.tokens[extra.tokens.length - 1]; + if (token.range[0] === pos && token.type === 'Punctuator') { + if (token.value === '/' || token.value === '/=') { + extra.tokens.pop(); + } + } + } + + extra.tokens.push({ + type: 'RegularExpression', + value: regex.literal, + regex: regex.regex, + range: [pos, index], + loc: loc + }); + } + + return regex; + } + + function isIdentifierName(token) { + return token.type === Token.Identifier || + token.type === Token.Keyword || + token.type === Token.BooleanLiteral || + token.type === Token.NullLiteral; + } + + function advanceSlash() { + var prevToken, + checkToken; + // Using the following algorithm: + // https://github.com/mozilla/sweet.js/wiki/design + prevToken = extra.tokens[extra.tokens.length - 1]; + if (!prevToken) { + // Nothing before that: it cannot be a division. + return collectRegex(); + } + if (prevToken.type === 'Punctuator') { + if (prevToken.value === ']') { + return scanPunctuator(); + } + if (prevToken.value === ')') { + checkToken = extra.tokens[extra.openParenToken - 1]; + if (checkToken && + checkToken.type === 'Keyword' && + (checkToken.value === 'if' || + checkToken.value === 'while' || + checkToken.value === 'for' || + checkToken.value === 'with')) { + return collectRegex(); + } + return scanPunctuator(); + } + if (prevToken.value === '}') { + // Dividing a function by anything makes little sense, + // but we have to check for that. + if (extra.tokens[extra.openCurlyToken - 3] && + extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { + // Anonymous function. + checkToken = extra.tokens[extra.openCurlyToken - 4]; + if (!checkToken) { + return scanPunctuator(); + } + } else if (extra.tokens[extra.openCurlyToken - 4] && + extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { + // Named function. + checkToken = extra.tokens[extra.openCurlyToken - 5]; + if (!checkToken) { + return collectRegex(); + } + } else { + return scanPunctuator(); + } + // checkToken determines whether the function is + // a declaration or an expression. + if (FnExprTokens.indexOf(checkToken.value) >= 0) { + // It is an expression. + return scanPunctuator(); + } + // It is a declaration. + return collectRegex(); + } + return collectRegex(); + } + if (prevToken.type === 'Keyword' && prevToken.value !== 'this') { + return collectRegex(); + } + return scanPunctuator(); + } + + function advance() { + var ch; + + skipComment(); + + if (index >= length) { + return { + type: Token.EOF, + lineNumber: lineNumber, + lineStart: lineStart, + start: index, + end: index + }; + } + + ch = source.charCodeAt(index); + + if (isIdentifierStart(ch)) { + return scanIdentifier(); + } + + // Very common: ( and ) and ; + if (ch === 0x28 || ch === 0x29 || ch === 0x3B) { + return scanPunctuator(); + } + + // String literal starts with single quote (U+0027) or double quote (U+0022). + if (ch === 0x27 || ch === 0x22) { + return scanStringLiteral(); + } + + + // Dot (.) U+002E can also start a floating-point number, hence the need + // to check the next character. + if (ch === 0x2E) { + if (isDecimalDigit(source.charCodeAt(index + 1))) { + return scanNumericLiteral(); + } + return scanPunctuator(); + } + + if (isDecimalDigit(ch)) { + return scanNumericLiteral(); + } + + // Slash (/) U+002F can also start a regex. + if (extra.tokenize && ch === 0x2F) { + return advanceSlash(); + } + + return scanPunctuator(); + } + + function collectToken() { + var loc, token, value, entry; + + skipComment(); + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + token = advance(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (token.type !== Token.EOF) { + value = source.slice(token.start, token.end); + entry = { + type: TokenName[token.type], + value: value, + range: [token.start, token.end], + loc: loc + }; + if (token.regex) { + entry.regex = { + pattern: token.regex.pattern, + flags: token.regex.flags + }; + } + extra.tokens.push(entry); + } + + return token; + } + + function lex() { + var token; + + token = lookahead; + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + return token; + } + + function peek() { + var pos, line, start; + + pos = index; + line = lineNumber; + start = lineStart; + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + index = pos; + lineNumber = line; + lineStart = start; + } + + function Position() { + this.line = lineNumber; + this.column = index - lineStart; + } + + function SourceLocation() { + this.start = new Position(); + this.end = null; + } + + function WrappingSourceLocation(startToken) { + if (startToken.type === Token.StringLiteral) { + this.start = { + line: startToken.startLineNumber, + column: startToken.start - startToken.startLineStart + }; + } else { + this.start = { + line: startToken.lineNumber, + column: startToken.start - startToken.lineStart + }; + } + this.end = null; + } + + function Node() { + // Skip comment. + index = lookahead.start; + if (lookahead.type === Token.StringLiteral) { + lineNumber = lookahead.startLineNumber; + lineStart = lookahead.startLineStart; + } else { + lineNumber = lookahead.lineNumber; + lineStart = lookahead.lineStart; + } + if (extra.range) { + this.range = [index, 0]; + } + if (extra.loc) { + this.loc = new SourceLocation(); + } + } + + function WrappingNode(startToken) { + if (extra.range) { + this.range = [startToken.start, 0]; + } + if (extra.loc) { + this.loc = new WrappingSourceLocation(startToken); + } + } + + WrappingNode.prototype = Node.prototype = { + + processComment: function () { + var lastChild, + leadingComments, + trailingComments, + bottomRight = extra.bottomRightStack, + i, + comment, + last = bottomRight[bottomRight.length - 1]; + + if (this.type === Syntax.Program) { + if (this.body.length > 0) { + return; + } + } + + if (extra.trailingComments.length > 0) { + trailingComments = []; + for (i = extra.trailingComments.length - 1; i >= 0; --i) { + comment = extra.trailingComments[i]; + if (comment.range[0] >= this.range[1]) { + trailingComments.unshift(comment); + extra.trailingComments.splice(i, 1); + } + } + extra.trailingComments = []; + } else { + if (last && last.trailingComments && last.trailingComments[0].range[0] >= this.range[1]) { + trailingComments = last.trailingComments; + delete last.trailingComments; + } + } + + // Eating the stack. + if (last) { + while (last && last.range[0] >= this.range[0]) { + lastChild = last; + last = bottomRight.pop(); + } + } + + if (lastChild) { + if (lastChild.leadingComments && lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= this.range[0]) { + this.leadingComments = lastChild.leadingComments; + lastChild.leadingComments = undefined; + } + } else if (extra.leadingComments.length > 0) { + leadingComments = []; + for (i = extra.leadingComments.length - 1; i >= 0; --i) { + comment = extra.leadingComments[i]; + if (comment.range[1] <= this.range[0]) { + leadingComments.unshift(comment); + extra.leadingComments.splice(i, 1); + } + } + } + + + if (leadingComments && leadingComments.length > 0) { + this.leadingComments = leadingComments; + } + if (trailingComments && trailingComments.length > 0) { + this.trailingComments = trailingComments; + } + + bottomRight.push(this); + }, + + finish: function () { + if (extra.range) { + this.range[1] = index; + } + if (extra.loc) { + this.loc.end = new Position(); + if (extra.source) { + this.loc.source = extra.source; + } + } + + if (extra.attachComment) { + this.processComment(); + } + }, + + finishArrayExpression: function (elements) { + this.type = Syntax.ArrayExpression; + this.elements = elements; + this.finish(); + return this; + }, + + finishArrowFunctionExpression: function (params, defaults, body, expression) { + this.type = Syntax.ArrowFunctionExpression; + this.id = null; + this.params = params; + this.defaults = defaults; + this.body = body; + this.rest = null; + this.generator = false; + this.expression = expression; + this.finish(); + return this; + }, + + finishAssignmentExpression: function (operator, left, right) { + this.type = Syntax.AssignmentExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishBinaryExpression: function (operator, left, right) { + this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishBlockStatement: function (body) { + this.type = Syntax.BlockStatement; + this.body = body; + this.finish(); + return this; + }, + + finishBreakStatement: function (label) { + this.type = Syntax.BreakStatement; + this.label = label; + this.finish(); + return this; + }, + + finishCallExpression: function (callee, args) { + this.type = Syntax.CallExpression; + this.callee = callee; + this.arguments = args; + this.finish(); + return this; + }, + + finishCatchClause: function (param, body) { + this.type = Syntax.CatchClause; + this.param = param; + this.body = body; + this.finish(); + return this; + }, + + finishConditionalExpression: function (test, consequent, alternate) { + this.type = Syntax.ConditionalExpression; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + this.finish(); + return this; + }, + + finishContinueStatement: function (label) { + this.type = Syntax.ContinueStatement; + this.label = label; + this.finish(); + return this; + }, + + finishDebuggerStatement: function () { + this.type = Syntax.DebuggerStatement; + this.finish(); + return this; + }, + + finishDoWhileStatement: function (body, test) { + this.type = Syntax.DoWhileStatement; + this.body = body; + this.test = test; + this.finish(); + return this; + }, + + finishEmptyStatement: function () { + this.type = Syntax.EmptyStatement; + this.finish(); + return this; + }, + + finishExpressionStatement: function (expression) { + this.type = Syntax.ExpressionStatement; + this.expression = expression; + this.finish(); + return this; + }, + + finishForStatement: function (init, test, update, body) { + this.type = Syntax.ForStatement; + this.init = init; + this.test = test; + this.update = update; + this.body = body; + this.finish(); + return this; + }, + + finishForInStatement: function (left, right, body) { + this.type = Syntax.ForInStatement; + this.left = left; + this.right = right; + this.body = body; + this.each = false; + this.finish(); + return this; + }, + + finishFunctionDeclaration: function (id, params, defaults, body) { + this.type = Syntax.FunctionDeclaration; + this.id = id; + this.params = params; + this.defaults = defaults; + this.body = body; + this.rest = null; + this.generator = false; + this.expression = false; + this.finish(); + return this; + }, + + finishFunctionExpression: function (id, params, defaults, body) { + this.type = Syntax.FunctionExpression; + this.id = id; + this.params = params; + this.defaults = defaults; + this.body = body; + this.rest = null; + this.generator = false; + this.expression = false; + this.finish(); + return this; + }, + + finishIdentifier: function (name) { + this.type = Syntax.Identifier; + this.name = name; + this.finish(); + return this; + }, + + finishIfStatement: function (test, consequent, alternate) { + this.type = Syntax.IfStatement; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + this.finish(); + return this; + }, + + finishLabeledStatement: function (label, body) { + this.type = Syntax.LabeledStatement; + this.label = label; + this.body = body; + this.finish(); + return this; + }, + + finishLiteral: function (token) { + this.type = Syntax.Literal; + this.value = token.value; + this.raw = source.slice(token.start, token.end); + if (token.regex) { + this.regex = token.regex; + } + this.finish(); + return this; + }, + + finishMemberExpression: function (accessor, object, property) { + this.type = Syntax.MemberExpression; + this.computed = accessor === '['; + this.object = object; + this.property = property; + this.finish(); + return this; + }, + + finishNewExpression: function (callee, args) { + this.type = Syntax.NewExpression; + this.callee = callee; + this.arguments = args; + this.finish(); + return this; + }, + + finishObjectExpression: function (properties) { + this.type = Syntax.ObjectExpression; + this.properties = properties; + this.finish(); + return this; + }, + + finishPostfixExpression: function (operator, argument) { + this.type = Syntax.UpdateExpression; + this.operator = operator; + this.argument = argument; + this.prefix = false; + this.finish(); + return this; + }, + + finishProgram: function (body) { + this.type = Syntax.Program; + this.body = body; + this.finish(); + return this; + }, + + finishProperty: function (kind, key, value, method, shorthand) { + this.type = Syntax.Property; + this.key = key; + this.value = value; + this.kind = kind; + this.method = method; + this.shorthand = shorthand; + this.finish(); + return this; + }, + + finishReturnStatement: function (argument) { + this.type = Syntax.ReturnStatement; + this.argument = argument; + this.finish(); + return this; + }, + + finishSequenceExpression: function (expressions) { + this.type = Syntax.SequenceExpression; + this.expressions = expressions; + this.finish(); + return this; + }, + + finishSwitchCase: function (test, consequent) { + this.type = Syntax.SwitchCase; + this.test = test; + this.consequent = consequent; + this.finish(); + return this; + }, + + finishSwitchStatement: function (discriminant, cases) { + this.type = Syntax.SwitchStatement; + this.discriminant = discriminant; + this.cases = cases; + this.finish(); + return this; + }, + + finishThisExpression: function () { + this.type = Syntax.ThisExpression; + this.finish(); + return this; + }, + + finishThrowStatement: function (argument) { + this.type = Syntax.ThrowStatement; + this.argument = argument; + this.finish(); + return this; + }, + + finishTryStatement: function (block, guardedHandlers, handlers, finalizer) { + this.type = Syntax.TryStatement; + this.block = block; + this.guardedHandlers = guardedHandlers; + this.handlers = handlers; + this.finalizer = finalizer; + this.finish(); + return this; + }, + + finishUnaryExpression: function (operator, argument) { + this.type = (operator === '++' || operator === '--') ? Syntax.UpdateExpression : Syntax.UnaryExpression; + this.operator = operator; + this.argument = argument; + this.prefix = true; + this.finish(); + return this; + }, + + finishVariableDeclaration: function (declarations, kind) { + this.type = Syntax.VariableDeclaration; + this.declarations = declarations; + this.kind = kind; + this.finish(); + return this; + }, + + finishVariableDeclarator: function (id, init) { + this.type = Syntax.VariableDeclarator; + this.id = id; + this.init = init; + this.finish(); + return this; + }, + + finishWhileStatement: function (test, body) { + this.type = Syntax.WhileStatement; + this.test = test; + this.body = body; + this.finish(); + return this; + }, + + finishWithStatement: function (object, body) { + this.type = Syntax.WithStatement; + this.object = object; + this.body = body; + this.finish(); + return this; + } + }; + + // Return true if there is a line terminator before the next token. + + function peekLineTerminator() { + var pos, line, start, found; + + pos = index; + line = lineNumber; + start = lineStart; + skipComment(); + found = lineNumber !== line; + index = pos; + lineNumber = line; + lineStart = start; + + return found; + } + + function createError(line, pos, description) { + var error = new Error('Line ' + line + ': ' + description); + error.index = pos; + error.lineNumber = line; + error.column = pos - lineStart + 1; + error.description = description; + return error; + } + + // Throw an exception + + function throwError(messageFormat) { + var args, msg; + + args = Array.prototype.slice.call(arguments, 1); + msg = messageFormat.replace(/%(\d)/g, + function (whole, idx) { + assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + } + ); + + throw createError(lineNumber, index, msg); + } + + function tolerateError(messageFormat) { + var args, msg, error; + + args = Array.prototype.slice.call(arguments, 1); + /* istanbul ignore next */ + msg = messageFormat.replace(/%(\d)/g, + function (whole, idx) { + assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + } + ); + + error = createError(lineNumber, index, msg); + if (extra.errors) { + extra.errors.push(error); + } else { + throw error; + } + } + + // Throw an exception because of the token. + + function unexpectedTokenError(token, message) { + var msg = Messages.UnexpectedToken; + + if (token) { + msg = message ? message : + (token.type === Token.EOF) ? Messages.UnexpectedEOS : + (token.type === Token.Identifier) ? Messages.UnexpectedIdentifier : + (token.type === Token.NumericLiteral) ? Messages.UnexpectedNumber : + (token.type === Token.StringLiteral) ? Messages.UnexpectedString : + Messages.UnexpectedToken; + + if (token.type === Token.Keyword) { + if (isFutureReservedWord(token.value)) { + msg = Messages.UnexpectedReserved; + } else if (strict && isStrictModeReservedWord(token.value)) { + msg = Messages.StrictReservedWord; + } + } + } + + msg = msg.replace('%0', token ? token.value : 'ILLEGAL'); + + return (token && typeof token.lineNumber === 'number') ? + createError(token.lineNumber, token.start, msg) : + createError(lineNumber, index, msg); + } + + function throwUnexpectedToken(token, message) { + throw unexpectedTokenError(token, message); + } + + function tolerateUnexpectedToken(token, message) { + var error = unexpectedTokenError(token, message); + if (extra.errors) { + extra.errors.push(error); + } else { + throw error; + } + } + + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + + function expect(value) { + var token = lex(); + if (token.type !== Token.Punctuator || token.value !== value) { + throwUnexpectedToken(token); + } + } + + /** + * @name expectCommaSeparator + * @description Quietly expect a comma when in tolerant mode, otherwise delegates + * to expect(value) + * @since 2.0 + */ + function expectCommaSeparator() { + var token; + + if (extra.errors) { + token = lookahead; + if (token.type === Token.Punctuator && token.value === ',') { + lex(); + } else if (token.type === Token.Punctuator && token.value === ';') { + lex(); + tolerateUnexpectedToken(token); + } else { + tolerateUnexpectedToken(token, Messages.UnexpectedToken); + } + } else { + expect(','); + } + } + + // Expect the next token to match the specified keyword. + // If not, an exception will be thrown. + + function expectKeyword(keyword) { + var token = lex(); + if (token.type !== Token.Keyword || token.value !== keyword) { + throwUnexpectedToken(token); + } + } + + // Return true if the next token matches the specified punctuator. + + function match(value) { + return lookahead.type === Token.Punctuator && lookahead.value === value; + } + + // Return true if the next token matches the specified keyword + + function matchKeyword(keyword) { + return lookahead.type === Token.Keyword && lookahead.value === keyword; + } + + // Return true if the next token is an assignment operator + + function matchAssign() { + var op; + + if (lookahead.type !== Token.Punctuator) { + return false; + } + op = lookahead.value; + return op === '=' || + op === '*=' || + op === '/=' || + op === '%=' || + op === '+=' || + op === '-=' || + op === '<<=' || + op === '>>=' || + op === '>>>=' || + op === '&=' || + op === '^=' || + op === '|='; + } + + function consumeSemicolon() { + var line, oldIndex = index, oldLineNumber = lineNumber, + oldLineStart = lineStart, oldLookahead = lookahead; + + // Catch the very common case first: immediately a semicolon (U+003B). + if (source.charCodeAt(index) === 0x3B || match(';')) { + lex(); + return; + } + + line = lineNumber; + skipComment(); + if (lineNumber !== line) { + index = oldIndex; + lineNumber = oldLineNumber; + lineStart = oldLineStart; + lookahead = oldLookahead; + return; + } + + if (lookahead.type !== Token.EOF && !match('}')) { + throwUnexpectedToken(lookahead); + } + } + + // Return true if provided expression is LeftHandSideExpression + + function isLeftHandSide(expr) { + return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression; + } + + // 11.1.4 Array Initialiser + + function parseArrayInitialiser() { + var elements = [], node = new Node(); + + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + elements.push(parseAssignmentExpression()); + + if (!match(']')) { + expect(','); + } + } + } + + lex(); + + return node.finishArrayExpression(elements); + } + + // 11.1.5 Object Initialiser + + function parsePropertyFunction(param, first) { + var previousStrict, body, node = new Node(); + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (first && strict && isRestrictedWord(param[0].name)) { + tolerateUnexpectedToken(first, Messages.StrictParamName); + } + strict = previousStrict; + return node.finishFunctionExpression(null, param, [], body); + } + + function parsePropertyMethodFunction() { + var previousStrict, param, method; + + previousStrict = strict; + strict = true; + param = parseParams(); + method = parsePropertyFunction(param.params); + strict = previousStrict; + + return method; + } + + function parseObjectPropertyKey() { + var token, node = new Node(); + + token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { + if (strict && token.octal) { + tolerateUnexpectedToken(token, Messages.StrictOctalLiteral); + } + return node.finishLiteral(token); + } + + return node.finishIdentifier(token.value); + } + + function parseObjectProperty() { + var token, key, id, value, param, node = new Node(); + + token = lookahead; + + if (token.type === Token.Identifier) { + + id = parseObjectPropertyKey(); + + // Property Assignment: Getter and Setter. + + if (token.value === 'get' && !(match(':') || match('('))) { + key = parseObjectPropertyKey(); + expect('('); + expect(')'); + value = parsePropertyFunction([]); + return node.finishProperty('get', key, value, false, false); + } + if (token.value === 'set' && !(match(':') || match('('))) { + key = parseObjectPropertyKey(); + expect('('); + token = lookahead; + if (token.type !== Token.Identifier) { + expect(')'); + tolerateUnexpectedToken(token); + value = parsePropertyFunction([]); + } else { + param = [ parseVariableIdentifier() ]; + expect(')'); + value = parsePropertyFunction(param, token); + } + return node.finishProperty('set', key, value, false, false); + } + if (match(':')) { + lex(); + value = parseAssignmentExpression(); + return node.finishProperty('init', id, value, false, false); + } + if (match('(')) { + value = parsePropertyMethodFunction(); + return node.finishProperty('init', id, value, true, false); + } + + value = id; + return node.finishProperty('init', id, value, false, true); + } + if (token.type === Token.EOF || token.type === Token.Punctuator) { + throwUnexpectedToken(token); + } else { + key = parseObjectPropertyKey(); + if (match(':')) { + lex(); + value = parseAssignmentExpression(); + return node.finishProperty('init', key, value, false, false); + } + if (match('(')) { + value = parsePropertyMethodFunction(); + return node.finishProperty('init', key, value, true, false); + } + throwUnexpectedToken(lex()); + } + } + + function parseObjectInitialiser() { + var properties = [], property, name, key, kind, map = {}, toString = String, node = new Node(); + + expect('{'); + + while (!match('}')) { + property = parseObjectProperty(); + + if (property.key.type === Syntax.Identifier) { + name = property.key.name; + } else { + name = toString(property.key.value); + } + kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; + + key = '$' + name; + if (Object.prototype.hasOwnProperty.call(map, key)) { + if (map[key] === PropertyKind.Data) { + if (strict && kind === PropertyKind.Data) { + tolerateError(Messages.StrictDuplicateProperty); + } else if (kind !== PropertyKind.Data) { + tolerateError(Messages.AccessorDataProperty); + } + } else { + if (kind === PropertyKind.Data) { + tolerateError(Messages.AccessorDataProperty); + } else if (map[key] & kind) { + tolerateError(Messages.AccessorGetSet); + } + } + map[key] |= kind; + } else { + map[key] = kind; + } + + properties.push(property); + + if (!match('}')) { + expectCommaSeparator(); + } + } + + expect('}'); + + return node.finishObjectExpression(properties); + } + + // 11.1.6 The Grouping Operator + + function parseGroupExpression() { + var expr; + + expect('('); + + if (match(')')) { + lex(); + return PlaceHolders.ArrowParameterPlaceHolder; + } + + ++state.parenthesisCount; + + expr = parseExpression(); + + expect(')'); + + return expr; + } + + + // 11.1 Primary Expressions + + function parsePrimaryExpression() { + var type, token, expr, node; + + if (match('(')) { + return parseGroupExpression(); + } + + if (match('[')) { + return parseArrayInitialiser(); + } + + if (match('{')) { + return parseObjectInitialiser(); + } + + type = lookahead.type; + node = new Node(); + + if (type === Token.Identifier) { + expr = node.finishIdentifier(lex().value); + } else if (type === Token.StringLiteral || type === Token.NumericLiteral) { + if (strict && lookahead.octal) { + tolerateUnexpectedToken(lookahead, Messages.StrictOctalLiteral); + } + expr = node.finishLiteral(lex()); + } else if (type === Token.Keyword) { + if (matchKeyword('function')) { + return parseFunctionExpression(); + } + if (matchKeyword('this')) { + lex(); + expr = node.finishThisExpression(); + } else { + throwUnexpectedToken(lex()); + } + } else if (type === Token.BooleanLiteral) { + token = lex(); + token.value = (token.value === 'true'); + expr = node.finishLiteral(token); + } else if (type === Token.NullLiteral) { + token = lex(); + token.value = null; + expr = node.finishLiteral(token); + } else if (match('/') || match('/=')) { + if (typeof extra.tokens !== 'undefined') { + expr = node.finishLiteral(collectRegex()); + } else { + expr = node.finishLiteral(scanRegExp()); + } + peek(); + } else { + throwUnexpectedToken(lex()); + } + + return expr; + } + + // 11.2 Left-Hand-Side Expressions + + function parseArguments() { + var args = []; + + expect('('); + + if (!match(')')) { + while (index < length) { + args.push(parseAssignmentExpression()); + if (match(')')) { + break; + } + expectCommaSeparator(); + } + } + + expect(')'); + + return args; + } + + function parseNonComputedProperty() { + var token, node = new Node(); + + token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpectedToken(token); + } + + return node.finishIdentifier(token.value); + } + + function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); + } + + function parseComputedMember() { + var expr; + + expect('['); + + expr = parseExpression(); + + expect(']'); + + return expr; + } + + function parseNewExpression() { + var callee, args, node = new Node(); + + expectKeyword('new'); + callee = parseLeftHandSideExpression(); + args = match('(') ? parseArguments() : []; + + return node.finishNewExpression(callee, args); + } + + function parseLeftHandSideExpressionAllowCall() { + var expr, args, property, startToken, previousAllowIn = state.allowIn; + + startToken = lookahead; + state.allowIn = true; + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + for (;;) { + if (match('.')) { + property = parseNonComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); + } else if (match('(')) { + args = parseArguments(); + expr = new WrappingNode(startToken).finishCallExpression(expr, args); + } else if (match('[')) { + property = parseComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); + } else { + break; + } + } + state.allowIn = previousAllowIn; + + return expr; + } + + function parseLeftHandSideExpression() { + var expr, property, startToken; + assert(state.allowIn, 'callee of new expression always allow in keyword.'); + + startToken = lookahead; + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + for (;;) { + if (match('[')) { + property = parseComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); + } else if (match('.')) { + property = parseNonComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); + } else { + break; + } + } + return expr; + } + + // 11.3 Postfix Expressions + + function parsePostfixExpression() { + var expr, token, startToken = lookahead; + + expr = parseLeftHandSideExpressionAllowCall(); + + if (lookahead.type === Token.Punctuator) { + if ((match('++') || match('--')) && !peekLineTerminator()) { + // 11.3.1, 11.3.2 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + tolerateError(Messages.StrictLHSPostfix); + } + + if (!isLeftHandSide(expr)) { + tolerateError(Messages.InvalidLHSInAssignment); + } + + token = lex(); + expr = new WrappingNode(startToken).finishPostfixExpression(token.value, expr); + } + } + + return expr; + } + + // 11.4 Unary Operators + + function parseUnaryExpression() { + var token, expr, startToken; + + if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { + expr = parsePostfixExpression(); + } else if (match('++') || match('--')) { + startToken = lookahead; + token = lex(); + expr = parseUnaryExpression(); + // 11.4.4, 11.4.5 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + tolerateError(Messages.StrictLHSPrefix); + } + + if (!isLeftHandSide(expr)) { + tolerateError(Messages.InvalidLHSInAssignment); + } + + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + } else if (match('+') || match('-') || match('~') || match('!')) { + startToken = lookahead; + token = lex(); + expr = parseUnaryExpression(); + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + startToken = lookahead; + token = lex(); + expr = parseUnaryExpression(); + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { + tolerateError(Messages.StrictDelete); + } + } else { + expr = parsePostfixExpression(); + } + + return expr; + } + + function binaryPrecedence(token, allowIn) { + var prec = 0; + + if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { + return 0; + } + + switch (token.value) { + case '||': + prec = 1; + break; + + case '&&': + prec = 2; + break; + + case '|': + prec = 3; + break; + + case '^': + prec = 4; + break; + + case '&': + prec = 5; + break; + + case '==': + case '!=': + case '===': + case '!==': + prec = 6; + break; + + case '<': + case '>': + case '<=': + case '>=': + case 'instanceof': + prec = 7; + break; + + case 'in': + prec = allowIn ? 7 : 0; + break; + + case '<<': + case '>>': + case '>>>': + prec = 8; + break; + + case '+': + case '-': + prec = 9; + break; + + case '*': + case '/': + case '%': + prec = 11; + break; + + default: + break; + } + + return prec; + } + + // 11.5 Multiplicative Operators + // 11.6 Additive Operators + // 11.7 Bitwise Shift Operators + // 11.8 Relational Operators + // 11.9 Equality Operators + // 11.10 Binary Bitwise Operators + // 11.11 Binary Logical Operators + + function parseBinaryExpression() { + var marker, markers, expr, token, prec, stack, right, operator, left, i; + + marker = lookahead; + left = parseUnaryExpression(); + if (left === PlaceHolders.ArrowParameterPlaceHolder) { + return left; + } + + token = lookahead; + prec = binaryPrecedence(token, state.allowIn); + if (prec === 0) { + return left; + } + token.prec = prec; + lex(); + + markers = [marker, lookahead]; + right = parseUnaryExpression(); + + stack = [left, token, right]; + + while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) { + + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + operator = stack.pop().value; + left = stack.pop(); + markers.pop(); + expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right); + stack.push(expr); + } + + // Shift. + token = lex(); + token.prec = prec; + stack.push(token); + markers.push(lookahead); + expr = parseUnaryExpression(); + stack.push(expr); + } + + // Final reduce to clean-up the stack. + i = stack.length - 1; + expr = stack[i]; + markers.pop(); + while (i > 1) { + expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr); + i -= 2; + } + + return expr; + } + + + // 11.12 Conditional Operator + + function parseConditionalExpression() { + var expr, previousAllowIn, consequent, alternate, startToken; + + startToken = lookahead; + + expr = parseBinaryExpression(); + if (expr === PlaceHolders.ArrowParameterPlaceHolder) { + return expr; + } + if (match('?')) { + lex(); + previousAllowIn = state.allowIn; + state.allowIn = true; + consequent = parseAssignmentExpression(); + state.allowIn = previousAllowIn; + expect(':'); + alternate = parseAssignmentExpression(); + + expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate); + } + + return expr; + } + + // [ES6] 14.2 Arrow Function + + function parseConciseBody() { + if (match('{')) { + return parseFunctionSourceElements(); + } + return parseAssignmentExpression(); + } + + function reinterpretAsCoverFormalsList(expressions) { + var i, len, param, params, defaults, defaultCount, options, rest, token; + + params = []; + defaults = []; + defaultCount = 0; + rest = null; + options = { + paramSet: {} + }; + + for (i = 0, len = expressions.length; i < len; i += 1) { + param = expressions[i]; + if (param.type === Syntax.Identifier) { + params.push(param); + defaults.push(null); + validateParam(options, param, param.name); + } else if (param.type === Syntax.AssignmentExpression) { + params.push(param.left); + defaults.push(param.right); + ++defaultCount; + validateParam(options, param.left, param.left.name); + } else { + return null; + } + } + + if (options.message === Messages.StrictParamDupe) { + token = strict ? options.stricted : options.firstRestricted; + throwUnexpectedToken(token, options.message); + } + + if (defaultCount === 0) { + defaults = []; + } + + return { + params: params, + defaults: defaults, + rest: rest, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + } + + function parseArrowFunctionExpression(options, node) { + var previousStrict, body; + + expect('=>'); + previousStrict = strict; + + body = parseConciseBody(); + + if (strict && options.firstRestricted) { + throwUnexpectedToken(options.firstRestricted, options.message); + } + if (strict && options.stricted) { + tolerateUnexpectedToken(options.stricted, options.message); + } + + strict = previousStrict; + + return node.finishArrowFunctionExpression(options.params, options.defaults, body, body.type !== Syntax.BlockStatement); + } + + // 11.13 Assignment Operators + + function parseAssignmentExpression() { + var oldParenthesisCount, token, expr, right, list, startToken; + + oldParenthesisCount = state.parenthesisCount; + + startToken = lookahead; + token = lookahead; + + expr = parseConditionalExpression(); + + if (expr === PlaceHolders.ArrowParameterPlaceHolder || match('=>')) { + if (state.parenthesisCount === oldParenthesisCount || + state.parenthesisCount === (oldParenthesisCount + 1)) { + if (expr.type === Syntax.Identifier) { + list = reinterpretAsCoverFormalsList([ expr ]); + } else if (expr.type === Syntax.AssignmentExpression) { + list = reinterpretAsCoverFormalsList([ expr ]); + } else if (expr.type === Syntax.SequenceExpression) { + list = reinterpretAsCoverFormalsList(expr.expressions); + } else if (expr === PlaceHolders.ArrowParameterPlaceHolder) { + list = reinterpretAsCoverFormalsList([]); + } + if (list) { + return parseArrowFunctionExpression(list, new WrappingNode(startToken)); + } + } + } + + if (matchAssign()) { + // LeftHandSideExpression + if (!isLeftHandSide(expr)) { + tolerateError(Messages.InvalidLHSInAssignment); + } + + // 11.13.1 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + tolerateUnexpectedToken(token, Messages.StrictLHSAssignment); + } + + token = lex(); + right = parseAssignmentExpression(); + expr = new WrappingNode(startToken).finishAssignmentExpression(token.value, expr, right); + } + + return expr; + } + + // 11.14 Comma Operator + + function parseExpression() { + var expr, startToken = lookahead, expressions; + + expr = parseAssignmentExpression(); + + if (match(',')) { + expressions = [expr]; + + while (index < length) { + if (!match(',')) { + break; + } + lex(); + expressions.push(parseAssignmentExpression()); + } + + expr = new WrappingNode(startToken).finishSequenceExpression(expressions); + } + + return expr; + } + + // 12.1 Block + + function parseStatementList() { + var list = [], + statement; + + while (index < length) { + if (match('}')) { + break; + } + statement = parseSourceElement(); + if (typeof statement === 'undefined') { + break; + } + list.push(statement); + } + + return list; + } + + function parseBlock() { + var block, node = new Node(); + + expect('{'); + + block = parseStatementList(); + + expect('}'); + + return node.finishBlockStatement(block); + } + + // 12.2 Variable Statement + + function parseVariableIdentifier() { + var token, node = new Node(); + + token = lex(); + + if (token.type !== Token.Identifier) { + if (strict && token.type === Token.Keyword && isStrictModeReservedWord(token.value)) { + tolerateUnexpectedToken(token, Messages.StrictReservedWord); + } else { + throwUnexpectedToken(token); + } + } + + return node.finishIdentifier(token.value); + } + + function parseVariableDeclaration(kind) { + var init = null, id, node = new Node(); + + id = parseVariableIdentifier(); + + // 12.2.1 + if (strict && isRestrictedWord(id.name)) { + tolerateError(Messages.StrictVarName); + } + + if (kind === 'const') { + expect('='); + init = parseAssignmentExpression(); + } else if (match('=')) { + lex(); + init = parseAssignmentExpression(); + } + + return node.finishVariableDeclarator(id, init); + } + + function parseVariableDeclarationList(kind) { + var list = []; + + do { + list.push(parseVariableDeclaration(kind)); + if (!match(',')) { + break; + } + lex(); + } while (index < length); + + return list; + } + + function parseVariableStatement(node) { + var declarations; + + expectKeyword('var'); + + declarations = parseVariableDeclarationList(); + + consumeSemicolon(); + + return node.finishVariableDeclaration(declarations, 'var'); + } + + // kind may be `const` or `let` + // Both are experimental and not in the specification yet. + // see http://wiki.ecmascript.org/doku.php?id=harmony:const + // and http://wiki.ecmascript.org/doku.php?id=harmony:let + function parseConstLetDeclaration(kind) { + var declarations, node = new Node(); + + expectKeyword(kind); + + declarations = parseVariableDeclarationList(kind); + + consumeSemicolon(); + + return node.finishVariableDeclaration(declarations, kind); + } + + // 12.3 Empty Statement + + function parseEmptyStatement() { + var node = new Node(); + expect(';'); + return node.finishEmptyStatement(); + } + + // 12.4 Expression Statement + + function parseExpressionStatement(node) { + var expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 12.5 If statement + + function parseIfStatement(node) { + var test, consequent, alternate; + + expectKeyword('if'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + consequent = parseStatement(); + + if (matchKeyword('else')) { + lex(); + alternate = parseStatement(); + } else { + alternate = null; + } + + return node.finishIfStatement(test, consequent, alternate); + } + + // 12.6 Iteration Statements + + function parseDoWhileStatement(node) { + var body, test, oldInIteration; + + expectKeyword('do'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + expectKeyword('while'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + if (match(';')) { + lex(); + } + + return node.finishDoWhileStatement(body, test); + } + + function parseWhileStatement(node) { + var test, body, oldInIteration; + + expectKeyword('while'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + return node.finishWhileStatement(test, body); + } + + function parseForVariableDeclaration() { + var token, declarations, node = new Node(); + + token = lex(); + declarations = parseVariableDeclarationList(); + + return node.finishVariableDeclaration(declarations, token.value); + } + + function parseForStatement(node) { + var init, test, update, left, right, body, oldInIteration, previousAllowIn = state.allowIn; + + init = test = update = null; + + expectKeyword('for'); + + expect('('); + + if (match(';')) { + lex(); + } else { + if (matchKeyword('var') || matchKeyword('let')) { + state.allowIn = false; + init = parseForVariableDeclaration(); + state.allowIn = previousAllowIn; + + if (init.declarations.length === 1 && matchKeyword('in')) { + lex(); + left = init; + right = parseExpression(); + init = null; + } + } else { + state.allowIn = false; + init = parseExpression(); + state.allowIn = previousAllowIn; + + if (matchKeyword('in')) { + // LeftHandSideExpression + if (!isLeftHandSide(init)) { + tolerateError(Messages.InvalidLHSInForIn); + } + + lex(); + left = init; + right = parseExpression(); + init = null; + } + } + + if (typeof left === 'undefined') { + expect(';'); + } + } + + if (typeof left === 'undefined') { + + if (!match(';')) { + test = parseExpression(); + } + expect(';'); + + if (!match(')')) { + update = parseExpression(); + } + } + + expect(')'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + return (typeof left === 'undefined') ? + node.finishForStatement(init, test, update, body) : + node.finishForInStatement(left, right, body); + } + + // 12.7 The continue statement + + function parseContinueStatement(node) { + var label = null, key; + + expectKeyword('continue'); + + // Optimize the most common form: 'continue;'. + if (source.charCodeAt(index) === 0x3B) { + lex(); + + if (!state.inIteration) { + throwError(Messages.IllegalContinue); + } + + return node.finishContinueStatement(null); + } + + if (peekLineTerminator()) { + if (!state.inIteration) { + throwError(Messages.IllegalContinue); + } + + return node.finishContinueStatement(null); + } + + if (lookahead.type === Token.Identifier) { + label = parseVariableIdentifier(); + + key = '$' + label.name; + if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { + throwError(Messages.UnknownLabel, label.name); + } + } + + consumeSemicolon(); + + if (label === null && !state.inIteration) { + throwError(Messages.IllegalContinue); + } + + return node.finishContinueStatement(label); + } + + // 12.8 The break statement + + function parseBreakStatement(node) { + var label = null, key; + + expectKeyword('break'); + + // Catch the very common case first: immediately a semicolon (U+003B). + if (source.charCodeAt(index) === 0x3B) { + lex(); + + if (!(state.inIteration || state.inSwitch)) { + throwError(Messages.IllegalBreak); + } + + return node.finishBreakStatement(null); + } + + if (peekLineTerminator()) { + if (!(state.inIteration || state.inSwitch)) { + throwError(Messages.IllegalBreak); + } + + return node.finishBreakStatement(null); + } + + if (lookahead.type === Token.Identifier) { + label = parseVariableIdentifier(); + + key = '$' + label.name; + if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { + throwError(Messages.UnknownLabel, label.name); + } + } + + consumeSemicolon(); + + if (label === null && !(state.inIteration || state.inSwitch)) { + throwError(Messages.IllegalBreak); + } + + return node.finishBreakStatement(label); + } + + // 12.9 The return statement + + function parseReturnStatement(node) { + var argument = null; + + expectKeyword('return'); + + if (!state.inFunctionBody) { + tolerateError(Messages.IllegalReturn); + } + + // 'return' followed by a space and an identifier is very common. + if (source.charCodeAt(index) === 0x20) { + if (isIdentifierStart(source.charCodeAt(index + 1))) { + argument = parseExpression(); + consumeSemicolon(); + return node.finishReturnStatement(argument); + } + } + + if (peekLineTerminator()) { + return node.finishReturnStatement(null); + } + + if (!match(';')) { + if (!match('}') && lookahead.type !== Token.EOF) { + argument = parseExpression(); + } + } + + consumeSemicolon(); + + return node.finishReturnStatement(argument); + } + + // 12.10 The with statement + + function parseWithStatement(node) { + var object, body; + + if (strict) { + // TODO(ikarienator): Should we update the test cases instead? + skipComment(); + tolerateError(Messages.StrictModeWith); + } + + expectKeyword('with'); + + expect('('); + + object = parseExpression(); + + expect(')'); + + body = parseStatement(); + + return node.finishWithStatement(object, body); + } + + // 12.10 The swith statement + + function parseSwitchCase() { + var test, consequent = [], statement, node = new Node(); + + if (matchKeyword('default')) { + lex(); + test = null; + } else { + expectKeyword('case'); + test = parseExpression(); + } + expect(':'); + + while (index < length) { + if (match('}') || matchKeyword('default') || matchKeyword('case')) { + break; + } + statement = parseStatement(); + consequent.push(statement); + } + + return node.finishSwitchCase(test, consequent); + } + + function parseSwitchStatement(node) { + var discriminant, cases, clause, oldInSwitch, defaultFound; + + expectKeyword('switch'); + + expect('('); + + discriminant = parseExpression(); + + expect(')'); + + expect('{'); + + cases = []; + + if (match('}')) { + lex(); + return node.finishSwitchStatement(discriminant, cases); + } + + oldInSwitch = state.inSwitch; + state.inSwitch = true; + defaultFound = false; + + while (index < length) { + if (match('}')) { + break; + } + clause = parseSwitchCase(); + if (clause.test === null) { + if (defaultFound) { + throwError(Messages.MultipleDefaultsInSwitch); + } + defaultFound = true; + } + cases.push(clause); + } + + state.inSwitch = oldInSwitch; + + expect('}'); + + return node.finishSwitchStatement(discriminant, cases); + } + + // 12.13 The throw statement + + function parseThrowStatement(node) { + var argument; + + expectKeyword('throw'); + + if (peekLineTerminator()) { + throwError(Messages.NewlineAfterThrow); + } + + argument = parseExpression(); + + consumeSemicolon(); + + return node.finishThrowStatement(argument); + } + + // 12.14 The try statement + + function parseCatchClause() { + var param, body, node = new Node(); + + expectKeyword('catch'); + + expect('('); + if (match(')')) { + throwUnexpectedToken(lookahead); + } + + param = parseVariableIdentifier(); + // 12.14.1 + if (strict && isRestrictedWord(param.name)) { + tolerateError(Messages.StrictCatchVariable); + } + + expect(')'); + body = parseBlock(); + return node.finishCatchClause(param, body); + } + + function parseTryStatement(node) { + var block, handlers = [], finalizer = null; + + expectKeyword('try'); + + block = parseBlock(); + + if (matchKeyword('catch')) { + handlers.push(parseCatchClause()); + } + + if (matchKeyword('finally')) { + lex(); + finalizer = parseBlock(); + } + + if (handlers.length === 0 && !finalizer) { + throwError(Messages.NoCatchOrFinally); + } + + return node.finishTryStatement(block, [], handlers, finalizer); + } + + // 12.15 The debugger statement + + function parseDebuggerStatement(node) { + expectKeyword('debugger'); + + consumeSemicolon(); + + return node.finishDebuggerStatement(); + } + + // 12 Statements + + function parseStatement() { + var type = lookahead.type, + expr, + labeledBody, + key, + node; + + if (type === Token.EOF) { + throwUnexpectedToken(lookahead); + } + + if (type === Token.Punctuator && lookahead.value === '{') { + return parseBlock(); + } + + node = new Node(); + + if (type === Token.Punctuator) { + switch (lookahead.value) { + case ';': + return parseEmptyStatement(node); + case '(': + return parseExpressionStatement(node); + default: + break; + } + } else if (type === Token.Keyword) { + switch (lookahead.value) { + case 'break': + return parseBreakStatement(node); + case 'continue': + return parseContinueStatement(node); + case 'debugger': + return parseDebuggerStatement(node); + case 'do': + return parseDoWhileStatement(node); + case 'for': + return parseForStatement(node); + case 'function': + return parseFunctionDeclaration(node); + case 'if': + return parseIfStatement(node); + case 'return': + return parseReturnStatement(node); + case 'switch': + return parseSwitchStatement(node); + case 'throw': + return parseThrowStatement(node); + case 'try': + return parseTryStatement(node); + case 'var': + return parseVariableStatement(node); + case 'while': + return parseWhileStatement(node); + case 'with': + return parseWithStatement(node); + default: + break; + } + } + + expr = parseExpression(); + + // 12.12 Labelled Statements + if ((expr.type === Syntax.Identifier) && match(':')) { + lex(); + + key = '$' + expr.name; + if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) { + throwError(Messages.Redeclaration, 'Label', expr.name); + } + + state.labelSet[key] = true; + labeledBody = parseStatement(); + delete state.labelSet[key]; + return node.finishLabeledStatement(expr, labeledBody); + } + + consumeSemicolon(); + + return node.finishExpressionStatement(expr); + } + + // 13 Function Definition + + function parseFunctionSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted, + oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesisCount, + node = new Node(); + + expect('{'); + + while (index < length) { + if (lookahead.type !== Token.StringLiteral) { + break; + } + token = lookahead; + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = source.slice(token.start + 1, token.end - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + oldLabelSet = state.labelSet; + oldInIteration = state.inIteration; + oldInSwitch = state.inSwitch; + oldInFunctionBody = state.inFunctionBody; + oldParenthesisCount = state.parenthesizedCount; + + state.labelSet = {}; + state.inIteration = false; + state.inSwitch = false; + state.inFunctionBody = true; + state.parenthesizedCount = 0; + + while (index < length) { + if (match('}')) { + break; + } + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + + expect('}'); + + state.labelSet = oldLabelSet; + state.inIteration = oldInIteration; + state.inSwitch = oldInSwitch; + state.inFunctionBody = oldInFunctionBody; + state.parenthesizedCount = oldParenthesisCount; + + return node.finishBlockStatement(sourceElements); + } + + function validateParam(options, param, name) { + var key = '$' + name; + if (strict) { + if (isRestrictedWord(name)) { + options.stricted = param; + options.message = Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = Messages.StrictParamDupe; + } + } else if (!options.firstRestricted) { + if (isRestrictedWord(name)) { + options.firstRestricted = param; + options.message = Messages.StrictParamName; + } else if (isStrictModeReservedWord(name)) { + options.firstRestricted = param; + options.message = Messages.StrictReservedWord; + } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.firstRestricted = param; + options.message = Messages.StrictParamDupe; + } + } + options.paramSet[key] = true; + } + + function parseParam(options) { + var token, param, def; + + token = lookahead; + param = parseVariableIdentifier(); + validateParam(options, token, token.value); + if (match('=')) { + lex(); + def = parseAssignmentExpression(); + ++options.defaultCount; + } + + options.params.push(param); + options.defaults.push(def); + + return !match(')'); + } + + function parseParams(firstRestricted) { + var options; + + options = { + params: [], + defaultCount: 0, + defaults: [], + firstRestricted: firstRestricted + }; + + expect('('); + + if (!match(')')) { + options.paramSet = {}; + while (index < length) { + if (!parseParam(options)) { + break; + } + expect(','); + } + } + + expect(')'); + + if (options.defaultCount === 0) { + options.defaults = []; + } + + return { + params: options.params, + defaults: options.defaults, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + } + + function parseFunctionDeclaration() { + var id, params = [], defaults = [], body, token, stricted, tmp, firstRestricted, message, previousStrict, node = new Node(); + + expectKeyword('function'); + token = lookahead; + id = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + tolerateUnexpectedToken(token, Messages.StrictFunctionName); + } + } else { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictFunctionName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } + } + + tmp = parseParams(firstRestricted); + params = tmp.params; + defaults = tmp.defaults; + stricted = tmp.stricted; + firstRestricted = tmp.firstRestricted; + if (tmp.message) { + message = tmp.message; + } + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (strict && firstRestricted) { + throwUnexpectedToken(firstRestricted, message); + } + if (strict && stricted) { + tolerateUnexpectedToken(stricted, message); + } + strict = previousStrict; + + return node.finishFunctionDeclaration(id, params, defaults, body); + } + + function parseFunctionExpression() { + var token, id = null, stricted, firstRestricted, message, tmp, + params = [], defaults = [], body, previousStrict, node = new Node(); + + expectKeyword('function'); + + if (!match('(')) { + token = lookahead; + id = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + tolerateUnexpectedToken(token, Messages.StrictFunctionName); + } + } else { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictFunctionName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } + } + } + + tmp = parseParams(firstRestricted); + params = tmp.params; + defaults = tmp.defaults; + stricted = tmp.stricted; + firstRestricted = tmp.firstRestricted; + if (tmp.message) { + message = tmp.message; + } + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (strict && firstRestricted) { + throwUnexpectedToken(firstRestricted, message); + } + if (strict && stricted) { + tolerateUnexpectedToken(stricted, message); + } + strict = previousStrict; + + return node.finishFunctionExpression(id, params, defaults, body); + } + + // 14 Program + + function parseSourceElement() { + if (lookahead.type === Token.Keyword) { + switch (lookahead.value) { + case 'const': + case 'let': + return parseConstLetDeclaration(lookahead.value); + case 'function': + return parseFunctionDeclaration(); + default: + return parseStatement(); + } + } + + if (lookahead.type !== Token.EOF) { + return parseStatement(); + } + } + + function parseSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted; + + while (index < length) { + token = lookahead; + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = source.slice(token.start + 1, token.end - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + while (index < length) { + sourceElement = parseSourceElement(); + /* istanbul ignore if */ + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + return sourceElements; + } + + function parseProgram() { + var body, node; + + skipComment(); + peek(); + node = new Node(); + strict = false; + + body = parseSourceElements(); + return node.finishProgram(body); + } + + function filterTokenLocation() { + var i, entry, token, tokens = []; + + for (i = 0; i < extra.tokens.length; ++i) { + entry = extra.tokens[i]; + token = { + type: entry.type, + value: entry.value + }; + if (entry.regex) { + token.regex = { + pattern: entry.regex.pattern, + flags: entry.regex.flags + }; + } + if (extra.range) { + token.range = entry.range; + } + if (extra.loc) { + token.loc = entry.loc; + } + tokens.push(token); + } + + extra.tokens = tokens; + } + + function tokenize(code, options) { + var toString, + tokens; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + + // Options matching. + options = options || {}; + + // Of course we collect tokens here. + options.tokens = true; + extra.tokens = []; + extra.tokenize = true; + // The following two fields are necessary to compute the Regex tokens. + extra.openParenToken = -1; + extra.openCurlyToken = -1; + + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (typeof options.comment === 'boolean' && options.comment) { + extra.comments = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + + try { + peek(); + if (lookahead.type === Token.EOF) { + return extra.tokens; + } + + lex(); + while (lookahead.type !== Token.EOF) { + try { + lex(); + } catch (lexError) { + if (extra.errors) { + extra.errors.push(lexError); + // We have to break on the first error + // to avoid infinite loops. + break; + } else { + throw lexError; + } + } + } + + filterTokenLocation(); + tokens = extra.tokens; + if (typeof extra.comments !== 'undefined') { + tokens.comments = extra.comments; + } + if (typeof extra.errors !== 'undefined') { + tokens.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + return tokens; + } + + function parse(code, options) { + var program, toString; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + parenthesisCount: 0, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + if (typeof options !== 'undefined') { + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment; + + if (extra.loc && options.source !== null && options.source !== undefined) { + extra.source = toString(options.source); + } + + if (typeof options.tokens === 'boolean' && options.tokens) { + extra.tokens = []; + } + if (typeof options.comment === 'boolean' && options.comment) { + extra.comments = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + if (extra.attachComment) { + extra.range = true; + extra.comments = []; + extra.bottomRightStack = []; + extra.trailingComments = []; + extra.leadingComments = []; + } + } + + try { + program = parseProgram(); + if (typeof extra.comments !== 'undefined') { + program.comments = extra.comments; + } + if (typeof extra.tokens !== 'undefined') { + filterTokenLocation(); + program.tokens = extra.tokens; + } + if (typeof extra.errors !== 'undefined') { + program.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + + return program; + } + + // Sync with *.json manifests. + exports.version = '2.0.0'; + + exports.tokenize = tokenize; + + exports.parse = parse; + + // Deep copy. + /* istanbul ignore next */ + exports.Syntax = (function () { + var name, types = {}; + + if (typeof Object.create === 'function') { + types = Object.create(null); + } + + for (name in Syntax) { + if (Syntax.hasOwnProperty(name)) { + types[name] = Syntax[name]; + } + } + + if (typeof Object.freeze === 'function') { + Object.freeze(types); + } + + return types; + }()); + +})); +/* vim: set sw=4 ts=4 et tw=80 : */ From 46b3f65602a6a976e73c6d085dd73c95a83f2483 Mon Sep 17 00:00:00 2001 From: Charles Abeling Date: Wed, 25 Feb 2015 17:11:30 -0600 Subject: [PATCH 215/333] Change bounded function to use function scope --- examples/js/renderers/RaytracingRenderer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/js/renderers/RaytracingRenderer.js b/examples/js/renderers/RaytracingRenderer.js index 1653d2a0fc1871..ee7c8837f1a83a 100644 --- a/examples/js/renderers/RaytracingRenderer.js +++ b/examples/js/renderers/RaytracingRenderer.js @@ -8,6 +8,8 @@ THREE.RaytracingRenderer = function ( parameters ) { console.log( 'THREE.RaytracingRenderer', THREE.REVISION ); parameters = parameters || {}; + + var scope = this; var canvas = document.createElement( 'canvas' ); var context = canvas.getContext( '2d', { @@ -39,8 +41,6 @@ THREE.RaytracingRenderer = function ( parameters ) { var animationFrameId = null; - var dispatch = this.dispatchEvent.bind(this); - this.domElement = canvas; this.autoClear = true; @@ -460,7 +460,7 @@ THREE.RaytracingRenderer = function ( parameters ) { if ( blockY >= canvasHeight ) { - dispatch( { type: "complete" } ); + scope.dispatchEvent( { type: "complete" } ); return; From 9446c31786a883d7ffb7889eb147a6aa5ba2564e Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 26 Feb 2015 01:08:23 +0100 Subject: [PATCH 216/333] Updated builds. --- build/three.js | 11 +++++++++-- build/three.min.js | 22 +++++++++++----------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/build/three.js b/build/three.js index 63f55ee2bba388..05aae368f971e6 100644 --- a/build/three.js +++ b/build/three.js @@ -12581,6 +12581,7 @@ THREE.MaterialLoader.prototype = { THREE.ObjectLoader = function ( manager ) { this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + this.texturePath = ''; }; @@ -12590,7 +12591,7 @@ THREE.ObjectLoader.prototype = { load: function ( url, onLoad, onProgress, onError ) { - if ( this.texturePath === undefined ) { + if ( this.texturePath === '' ) { this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 ); @@ -12821,6 +12822,9 @@ THREE.ObjectLoader.prototype = { if ( data.bumpMap !== undefined ) { material.bumpMap = getTexture( data.bumpMap ); + if ( data.bumpScale ) { + material.bumpScale = new THREE.Vector2( data.bumpScale, data.bumpScale ); + } } @@ -12839,6 +12843,9 @@ THREE.ObjectLoader.prototype = { if ( data.normalMap !== undefined ) { material.normalMap = getTexture( data.normalMap ); + if ( data.normalScale ) { + material.normalScale = new THREE.Vector2( data.normalScale, data.normalScale ); + } } @@ -33986,7 +33993,7 @@ THREE.GridHelper.prototype.setColors = function( colorCenterLine, colorGrid ) { * @author mrdoob / http://mrdoob.com/ */ -THREE.HemisphereLightHelper = function ( light, sphereSize, arrowLength, domeSize ) { +THREE.HemisphereLightHelper = function ( light, sphereSize ) { THREE.Object3D.call( this ); diff --git a/build/three.min.js b/build/three.min.js index 6d25be8b02fbb4..996d431b9b3166 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -277,18 +277,18 @@ THREE.BufferGeometryLoader.prototype={constructor:THREE.BufferGeometryLoader,loa a=a.boundingSphere;void 0!==a&&(c=new THREE.Vector3,void 0!==a.center&&c.fromArray(a.center),b.boundingSphere=new THREE.Sphere(c,a.radius));return b}};THREE.MaterialLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager}; THREE.MaterialLoader.prototype={constructor:THREE.MaterialLoader,load:function(a,b,c,d){var e=this,f=new THREE.XHRLoader(e.manager);f.setCrossOrigin(this.crossOrigin);f.load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},setCrossOrigin:function(a){this.crossOrigin=a},parse:function(a){var b=new THREE[a.type];void 0!==a.color&&b.color.setHex(a.color);void 0!==a.emissive&&b.emissive.setHex(a.emissive);void 0!==a.specular&&b.specular.setHex(a.specular);void 0!==a.shininess&&(b.shininess=a.shininess); void 0!==a.uniforms&&(b.uniforms=a.uniforms);void 0!==a.vertexShader&&(b.vertexShader=a.vertexShader);void 0!==a.fragmentShader&&(b.fragmentShader=a.fragmentShader);void 0!==a.vertexColors&&(b.vertexColors=a.vertexColors);void 0!==a.shading&&(b.shading=a.shading);void 0!==a.blending&&(b.blending=a.blending);void 0!==a.side&&(b.side=a.side);void 0!==a.opacity&&(b.opacity=a.opacity);void 0!==a.transparent&&(b.transparent=a.transparent);void 0!==a.wireframe&&(b.wireframe=a.wireframe);void 0!==a.size&& -(b.size=a.size);void 0!==a.sizeAttenuation&&(b.sizeAttenuation=a.sizeAttenuation);if(void 0!==a.materials)for(var c=0,d=a.materials.length;cb;b++)a.faces[b].color=this.colors[4>b?0:1];b=new THREE.MeshBasicMaterial({vertexColors:THREE.FaceColors,wireframe:!0});this.lightSphere=new THREE.Mesh(a,b);this.add(this.lightSphere); +THREE.HemisphereLightHelper=function(a,b){THREE.Object3D.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.colors=[new THREE.Color,new THREE.Color];var c=new THREE.SphereGeometry(b,4,2);c.applyMatrix((new THREE.Matrix4).makeRotationX(-Math.PI/2));for(var d=0;8>d;d++)c.faces[d].color=this.colors[4>d?0:1];d=new THREE.MeshBasicMaterial({vertexColors:THREE.FaceColors,wireframe:!0});this.lightSphere=new THREE.Mesh(c,d);this.add(this.lightSphere); this.update()};THREE.HemisphereLightHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.HemisphereLightHelper.prototype.constructor=THREE.HemisphereLightHelper;THREE.HemisphereLightHelper.prototype.dispose=function(){this.lightSphere.geometry.dispose();this.lightSphere.material.dispose()}; THREE.HemisphereLightHelper.prototype.update=function(){var a=new THREE.Vector3;return function(){this.colors[0].copy(this.light.color).multiplyScalar(this.light.intensity);this.colors[1].copy(this.light.groundColor).multiplyScalar(this.light.intensity);this.lightSphere.lookAt(a.setFromMatrixPosition(this.light.matrixWorld).negate());this.lightSphere.geometry.colorsNeedUpdate=!0}}(); THREE.PointLightHelper=function(a,b){this.light=a;this.light.updateMatrixWorld();var c=new THREE.SphereGeometry(b,4,2),d=new THREE.MeshBasicMaterial({wireframe:!0,fog:!1});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);THREE.Mesh.call(this,c,d);this.matrix=this.light.matrixWorld;this.matrixAutoUpdate=!1};THREE.PointLightHelper.prototype=Object.create(THREE.Mesh.prototype);THREE.PointLightHelper.prototype.constructor=THREE.PointLightHelper; From bde2a91316041e39a198d92255c701d4020bf4d4 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 26 Feb 2015 14:16:40 +0100 Subject: [PATCH 217/333] OrbitControls: Avoid unneeded dollying. Fixes #6144. --- examples/js/controls/OrbitControls.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/js/controls/OrbitControls.js b/examples/js/controls/OrbitControls.js index 371499e7d9d8ca..e150b589c64711 100644 --- a/examples/js/controls/OrbitControls.js +++ b/examples/js/controls/OrbitControls.js @@ -451,7 +451,7 @@ THREE.OrbitControls = function ( object, domElement ) { scope.dollyIn(); - } else { + } else if ( dollyDelta.y < 0 ) { scope.dollyOut(); @@ -510,7 +510,7 @@ THREE.OrbitControls = function ( object, domElement ) { scope.dollyOut(); - } else { + } else if ( delta < 0 ) { scope.dollyIn(); @@ -643,7 +643,7 @@ THREE.OrbitControls = function ( object, domElement ) { scope.dollyOut(); - } else { + } else if ( dollyDelta.y < 0 ) { scope.dollyIn(); From d81028993c7b43561cdf51d91779494a410b3de1 Mon Sep 17 00:00:00 2001 From: unconed Date: Thu, 26 Feb 2015 05:17:10 -0800 Subject: [PATCH 218/333] .renderOrder does not work - #5496 #5496 introduced a check for .renderOrder in painterSortStable. This is a property of the webglObject. It is never copied from the Object3D where it is defined and thus it does not work: https://github.com/mrdoob/three.js/commit/052f81ab6ed877935ad4657453752e9efa8018a4 The fix is to copy the property over when sorting and define it in webglObject as well. --- src/renderers/WebGLRenderer.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 25bdc57b14027e..857621ef2b667c 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3467,6 +3467,7 @@ THREE.WebGLRenderer = function ( parameters ) { _vector3.applyProjection( _projScreenMatrix ); webglObject.z = _vector3.z; + webglObject.renderOrder = object.renderOrder; } @@ -3887,7 +3888,8 @@ THREE.WebGLRenderer = function ( parameters ) { buffer: buffer, object: object, material: null, - z: 0 + z: 0, + renderOrder: 0 } ); @@ -3901,7 +3903,8 @@ THREE.WebGLRenderer = function ( parameters ) { object: object, opaque: null, transparent: null, - z: 0 + z: 0, + renderOrder: 0 } ); From 65e6cdd6903cefc2c96970adf97f61da411353f2 Mon Sep 17 00:00:00 2001 From: unconed Date: Thu, 26 Feb 2015 05:29:48 -0800 Subject: [PATCH 219/333] Do lookup directly in sort function --- src/renderers/WebGLRenderer.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 857621ef2b667c..a8f5695abe07bf 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3233,9 +3233,9 @@ THREE.WebGLRenderer = function ( parameters ) { function painterSortStable ( a, b ) { - if ( a.renderOrder !== b.renderOrder ) { + if ( a.object.renderOrder !== b.object.renderOrder ) { - return a.renderOrder - b.renderOrder; + return a.object.renderOrder - b.object.renderOrder; } else if ( a.material.id !== b.material.id ) { @@ -3255,9 +3255,9 @@ THREE.WebGLRenderer = function ( parameters ) { function reversePainterSortStable ( a, b ) { - if ( a.renderOrder !== b.renderOrder ) { + if ( a.object.renderOrder !== b.object.renderOrder ) { - return a.renderOrder - b.renderOrder; + return a.object.renderOrder - b.object.renderOrder; } if ( a.z !== b.z ) { @@ -3467,7 +3467,6 @@ THREE.WebGLRenderer = function ( parameters ) { _vector3.applyProjection( _projScreenMatrix ); webglObject.z = _vector3.z; - webglObject.renderOrder = object.renderOrder; } @@ -3888,8 +3887,7 @@ THREE.WebGLRenderer = function ( parameters ) { buffer: buffer, object: object, material: null, - z: 0, - renderOrder: 0 + z: 0 } ); @@ -3903,8 +3901,7 @@ THREE.WebGLRenderer = function ( parameters ) { object: object, opaque: null, transparent: null, - z: 0, - renderOrder: 0 + z: 0 } ); From 4dc5e9855af1f6869612fd23286084fa53fc76c0 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 26 Feb 2015 16:41:37 +0100 Subject: [PATCH 220/333] Editor: Updated Camera example. --- editor/examples/camera.app.json | 112 ++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 49 deletions(-) mode change 100644 => 100755 editor/examples/camera.app.json diff --git a/editor/examples/camera.app.json b/editor/examples/camera.app.json old mode 100644 new mode 100755 index 1ff8d5252c4338..e4c7905d84db2c --- a/editor/examples/camera.app.json +++ b/editor/examples/camera.app.json @@ -6,14 +6,14 @@ "generator": "ObjectExporter" }, "object": { - "uuid": "F0D8434F-4603-415B-8024-792FE97B9600", + "uuid": "C7FB195B-270E-47B4-95C9-1754652A9D11", "type": "PerspectiveCamera", "name": "Camera", "fov": 50, "aspect": 1.2252042007001167, "near": 0.1, "far": 100000, - "matrix": [0.9700406789779663,-5.500052080442686e-10,-0.24294254183769226,0,-0.04822639003396034,0.9800989627838135,-0.19256223738193512,0,0.23810774087905884,0.19850945472717285,0.950735867023468,0,159.0158233642578,132.5708465576172,634.9312744140625,1] + "matrix": [0.9700406789779663,-2.851828329042405e-9,-0.24294254183769226,0,-0.04822639003396034,0.9800989627838135,-0.1925622522830963,0,0.23810774087905884,0.19850945472717285,0.950735867023468,0,154.7735595703125,129.03408813476562,617.992431640625,1] } }, "scene": { @@ -23,6 +23,14 @@ "generator": "ObjectExporter" }, "geometries": [ + { + "uuid": "51BB3E54-D2DF-4576-9953-FB8E940588B5", + "type": "PlaneGeometry", + "width": 1000, + "height": 1000, + "widthSegments": 1, + "heightSegments": 1 + }, { "uuid": "D8E200D3-27BC-49F8-A5C5-7384206E70FE", "type": "BoxGeometry", @@ -43,14 +51,6 @@ "heightSegments": 1, "openEnded": false }, - { - "uuid": "51BB3E54-D2DF-4576-9953-FB8E940588B5", - "type": "PlaneGeometry", - "width": 1000, - "height": 1000, - "widthSegments": 1, - "heightSegments": 1 - }, { "uuid": "4DECFAB5-6FD1-4D84-9A29-565807B074EA", "type": "IcosahedronGeometry", @@ -59,25 +59,25 @@ }], "materials": [ { - "uuid": "B5943856-E404-45D9-A427-4774202C2CD0", + "uuid": "4AE8130E-B6A8-47BC-ACCF-060973C74044", "type": "MeshPhongMaterial", - "color": 37119, + "color": 16777215, "emissive": 0, "specular": 1118481, "shininess": 30 }, { - "uuid": "3F872310-2067-4BE4-9250-5B3F4E43797E", + "uuid": "B5943856-E404-45D9-A427-4774202C2CD0", "type": "MeshPhongMaterial", - "color": 15859456, + "color": 37119, "emissive": 0, "specular": 1118481, "shininess": 30 }, { - "uuid": "4AE8130E-B6A8-47BC-ACCF-060973C74044", + "uuid": "3F872310-2067-4BE4-9250-5B3F4E43797E", "type": "MeshPhongMaterial", - "color": 16777215, + "color": 15859456, "emissive": 0, "specular": 1118481, "shininess": 30 @@ -97,19 +97,34 @@ "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1], "children": [ { - "uuid": "60B69C58-4201-43FD-815E-AD2EDFBBD0CE", - "type": "PerspectiveCamera", - "name": "PerspectiveCamera 1", - "fov": 50, - "aspect": 1, - "near": 100, - "far": 10000, - "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,100,400,1] + "uuid": "B7CBBC6F-EC26-49B5-8D0D-67D9C535924B", + "type": "Group", + "name": "Dummy", + "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,100,400,1], + "children": [ + { + "uuid": "60B69C58-4201-43FD-815E-AD2EDFBBD0CE", + "type": "PerspectiveCamera", + "name": "PerspectiveCamera", + "fov": 50, + "aspect": 1, + "near": 100, + "far": 10000, + "matrix": [-1,0,-1.2246468525851679e-16,0,0,1,0,0,1.2246468525851679e-16,0,-1,0,0,0,0,1] + }] + }, + { + "uuid": "A460C230-DC88-4A8F-A3FB-AA0FE735F3ED", + "type": "Mesh", + "name": "Plane", + "geometry": "51BB3E54-D2DF-4576-9953-FB8E940588B5", + "material": "4AE8130E-B6A8-47BC-ACCF-060973C74044", + "matrix": [1,0,0,0,0,0.040785226970911026,-0.9991679191589355,0,0,0.9991679191589355,0.040785226970911026,0,0,-50,0,1] }, { "uuid": "26DAAD69-725D-43B7-AF9D-990A99DEF8C5", "type": "Mesh", - "name": "Box 1", + "name": "Box", "geometry": "D8E200D3-27BC-49F8-A5C5-7384206E70FE", "material": "B5943856-E404-45D9-A427-4774202C2CD0", "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] @@ -117,27 +132,18 @@ { "uuid": "AAAFF2D6-4725-4AFC-A9FE-26419B11011F", "type": "Mesh", - "name": "Cylinder 3", + "name": "Cylinder", "geometry": "25BA32DB-8B02-4ABA-A77C-69868C464A1A", "material": "3F872310-2067-4BE4-9250-5B3F4E43797E", "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,-130,-15,0,1] }, { - "uuid": "A460C230-DC88-4A8F-A3FB-AA0FE735F3ED", + "uuid": "B855E267-A266-4098-ACD6-6A1FDE7B88BA", "type": "Mesh", - "name": "Plane 4", - "geometry": "51BB3E54-D2DF-4576-9953-FB8E940588B5", - "material": "4AE8130E-B6A8-47BC-ACCF-060973C74044", - "matrix": [1,0,0,0,0,0.040785059332847595,-0.9991679191589355,0,0,0.9991679191589355,0.040785059332847595,0,0,-50,0,1] - }, - { - "uuid": "3412781E-27CC-43C3-A5DB-54C0C8E42ED6", - "type": "PointLight", - "name": "PointLight 2", - "color": 12773063, - "intensity": 1, - "distance": 0, - "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,88.12999725341797,8.3100004196167,125.44999694824219,1] + "name": "Icosahedron", + "geometry": "4DECFAB5-6FD1-4D84-9A29-565807B074EA", + "material": "E1826901-7922-4584-A25D-6D487E2C9BBD", + "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,130,-10,0,1] }, { "uuid": "E2939A7B-5E40-438A-8C1B-32126FBC6892", @@ -146,23 +152,31 @@ "color": 9474221, "intensity": 0.75, "distance": 0, + "decay": 1, "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,-93.86000061035156,127.12999725341797,-114.30000305175781,1] }, { - "uuid": "B855E267-A266-4098-ACD6-6A1FDE7B88BA", - "type": "Mesh", - "name": "Icosahedron 1", - "geometry": "4DECFAB5-6FD1-4D84-9A29-565807B074EA", - "material": "E1826901-7922-4584-A25D-6D487E2C9BBD", - "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,130,-10,0,1] + "uuid": "3412781E-27CC-43C3-A5DB-54C0C8E42ED6", + "type": "PointLight", + "name": "PointLight 2", + "color": 12773063, + "intensity": 1, + "distance": 0, + "decay": 1, + "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,88.12999725341797,8.3100004196167,125.44999694824219,1] }] } }, "scripts": { "60B69C58-4201-43FD-815E-AD2EDFBBD0CE": [ { - "name": "Camera Orbit", - "source": "player.setCamera( this );\n\nfunction update( event ) {\n\n\tvar time = event.time * 0.001;\n\n\tthis.position.x = Math.sin( time ) * 400;\n\tthis.position.z = Math.cos( time ) * 400;\n\tthis.lookAt( scene.position );\n\n}" + "name": "Player Camera", + "source": "player.setCamera( this );" + }], + "B7CBBC6F-EC26-49B5-8D0D-67D9C535924B": [ + { + "name": "Orbit", + "source": "function update( event ) {\n\n\tvar time = event.time * 0.001;\n\n\tthis.position.x = Math.sin( time ) * 400;\n\tthis.position.z = Math.cos( time ) * 400;\n\tthis.lookAt( scene.position );\n\n}" }] } -} +} \ No newline at end of file From e0261aed9f957a4c7e42983e92a5da587ba97f7f Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 26 Feb 2015 16:42:35 +0100 Subject: [PATCH 221/333] Updated builds. --- build/three.js | 8 +++--- build/three.min.js | 64 +++++++++++++++++++++++----------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/build/three.js b/build/three.js index 05aae368f971e6..1c40c2b5a9b187 100644 --- a/build/three.js +++ b/build/three.js @@ -20957,9 +20957,9 @@ THREE.WebGLRenderer = function ( parameters ) { function painterSortStable ( a, b ) { - if ( a.renderOrder !== b.renderOrder ) { + if ( a.object.renderOrder !== b.object.renderOrder ) { - return a.renderOrder - b.renderOrder; + return a.object.renderOrder - b.object.renderOrder; } else if ( a.material.id !== b.material.id ) { @@ -20979,9 +20979,9 @@ THREE.WebGLRenderer = function ( parameters ) { function reversePainterSortStable ( a, b ) { - if ( a.renderOrder !== b.renderOrder ) { + if ( a.object.renderOrder !== b.object.renderOrder ) { - return a.renderOrder - b.renderOrder; + return a.object.renderOrder - b.object.renderOrder; } if ( a.z !== b.z ) { diff --git a/build/three.min.js b/build/three.min.js index 996d431b9b3166..e566a0a7222d69 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -439,38 +439,38 @@ THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sa THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );\n\t#else\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n\t#endif\n}"].join("\n")}}; THREE.WebGLRenderer=function(a){function b(a){var b=a.geometry;a=a.material;var c=b.vertices.length;if(a.attributes){void 0===b.__webglCustomAttributesList&&(b.__webglCustomAttributesList=[]);for(var d in a.attributes){var e=a.attributes[d];if(!e.__webglInitialized||e.createUniqueBuffers){e.__webglInitialized=!0;var f=1;"v2"===e.type?f=2:"v3"===e.type?f=3:"v4"===e.type?f=4:"c"===e.type&&(f=3);e.size=f;e.array=new Float32Array(c*f);e.buffer=m.createBuffer();e.buffer.belongsToAttribute=d;e.needsUpdate= !0}b.__webglCustomAttributesList.push(e)}}}function c(a,b){return a.material instanceof THREE.MeshFaceMaterial?a.material.materials[b.materialIndex]:a.material}function d(a,b,c,d){c=c.attributes;var e=b.attributes;b=b.attributesKeys;for(var f=0,g=b.length;fh&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in r||(q={id:Qb++,faces3:[],materialIndex:u,vertices:0,numMorphTargets:l,numMorphNormals:p},r[k]=q,t.push(q))); -r[k].faces3.push(s);r[k].vertices+=3}f[g]=t;b.groupsNeedUpdate=!1}f=Ua[b.id];g=0;for(d=f.length;gY;Y++)pa=I[Y],Na[Ra]=pa.x,Na[Ra+1]=pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=H.x,Na[Ra+1]=H.y,Na[Ra+2]=H.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER, -v.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Na,D)}if(vb&&Hb){y=0;for(z=$.length;yY;Y++)ab=U[Y],Ab[kb]=ab.x,Ab[kb+1]=ab.y,kb+=2;0Y;Y++)oa=O[Y],lb[yb]=oa.x,lb[yb+1]=oa.y,yb+=2;0h&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in r||(q={id:Qb++,faces3:[],materialIndex:u,vertices:0, +numMorphTargets:l,numMorphNormals:p},r[k]=q,t.push(q)));r[k].faces3.push(s);r[k].vertices+=3}f[g]=t;b.groupsNeedUpdate=!1}f=Ua[b.id];g=0;for(d=f.length;gY;Y++)pa=I[Y],Na[Ra]=pa.x,Na[Ra+1]=pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=H.x,Na[Ra+1]=H.y, +Na[Ra+2]=H.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER,v.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Na,D)}if(vb&&Hb){y=0;for(z=$.length;yY;Y++)ab=U[Y],Ab[kb]=ab.x,Ab[kb+1]=ab.y,kb+=2;0Y;Y++)oa=O[Y],lb[yb]=oa.x,lb[yb+1]=oa.y,yb+=2;0 Date: Thu, 26 Feb 2015 17:55:00 +0100 Subject: [PATCH 222/333] VREffect: Using context.drawingBuffer*. Not sure how this was even working... --- examples/js/effects/VREffect.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/js/effects/VREffect.js b/examples/js/effects/VREffect.js index 1c48e2fedec66e..8cfdce1c921997 100644 --- a/examples/js/effects/VREffect.js +++ b/examples/js/effects/VREffect.js @@ -82,8 +82,8 @@ THREE.VREffect = function ( renderer, done ) { var leftEyeTranslation = this.leftEyeTranslation; var rightEyeTranslation = this.rightEyeTranslation; var renderer = this._renderer; - var rendererWidth = renderer.domElement.clientWidth; - var rendererHeight = renderer.domElement.clientHeight; + var rendererWidth = renderer.context.drawingBufferWidth; + var rendererHeight = renderer.context.drawingBufferHeight; var eyeDivisionLine = rendererWidth / 2; renderer.enableScissorTest( true ); From 5304312ac0a8b8db02c60be80d9466ab5e070a46 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 26 Feb 2015 17:58:45 +0100 Subject: [PATCH 223/333] Editor: Improved examples. --- editor/examples/arkanoid.app.json | 2 +- editor/examples/pong.app.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/examples/arkanoid.app.json b/editor/examples/arkanoid.app.json index b643cba08c2e34..0273a34e73a9e2 100755 --- a/editor/examples/arkanoid.app.json +++ b/editor/examples/arkanoid.app.json @@ -162,7 +162,7 @@ "31517222-A9A7-4EAF-B5F6-60751C0BABA3": [ { "name": "Game Logic", - "source": "var ball = this.getObjectByName( 'Ball' );\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = - 0.5;\ndirection.normalize();\n\nvar speed = new THREE.Vector3();\n\n//\n\nvar group = new THREE.Group();\nthis.add( group );\n\nvar paddle = this.getObjectByName( 'Paddle' );\ngroup.add( paddle );\n\nvar brick = this.getObjectByName( 'Brick' );\n\nfor ( var j = 0; j < 8; j ++ ) {\n\n\tvar material = new THREE.MeshPhongMaterial( { color: Math.random() * 0xffffff } );\n\n\tfor ( var i = 0; i < 12; i ++ ) {\n\t\t\n\t\tvar object = brick.clone();\n\t\tobject.material = material;\n\t\tobject.position.x = i * 22 - 120;\n\t\tobject.position.z = j * 14 - 120;\n\t\tgroup.add( object );\n\t\t\n\t}\n\t\n}\n\nbrick.visible = false;\n\n//\n\nvar raycaster = new THREE.Raycaster();\n\nfunction update( event ) {\n\t\n\tif ( ball.position.x < - 150 || ball.position.x > 150 ) direction.x = - direction.x;\n\tif ( ball.position.z < - 200 || ball.position.z > 200 ) direction.z = - direction.z;\n\n\tball.position.add( speed.copy( direction ).multiplyScalar( event.delta / 4 ) );\n\t\n\traycaster.set( ball.position, direction );\n\t\n\tvar intersections = raycaster.intersectObjects( group.children );\n\t\n\tif ( intersections.length > 0 ) {\n\t\n\t\tvar intersection = intersections[ 0 ];\n\t\t\n\t\tif ( intersection.distance < 5 ) {\n\t\t\t\n\t\t\tif ( intersection.object !== paddle ) {\n\n\t\t\t\tgroup.remove( intersection.object );\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tdirection.reflect( intersection.face.normal );\n\t\t\t\n\t\t}\n\t\t\n\t}\n\n}" + "source": "var ball = this.getObjectByName( 'Ball' );\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = - 0.5;\ndirection.normalize();\n\nvar speed = new THREE.Vector3();\n\n//\n\nvar group = new THREE.Group();\nthis.add( group );\n\nvar paddle = this.getObjectByName( 'Paddle' );\ngroup.add( paddle );\n\nvar brick = this.getObjectByName( 'Brick' );\n\nfor ( var j = 0; j < 8; j ++ ) {\n\n\tvar material = new THREE.MeshPhongMaterial( { color: Math.random() * 0xffffff } );\n\n\tfor ( var i = 0; i < 12; i ++ ) {\n\t\t\n\t\tvar object = brick.clone();\n\t\tobject.material = material;\n\t\tobject.position.x = i * 22 - 120;\n\t\tobject.position.z = j * 14 - 120;\n\t\tgroup.add( object );\n\t\t\n\t}\n\t\n}\n\nbrick.visible = false;\n\n//\n\nvar raycaster = new THREE.Raycaster();\n\nfunction update( event ) {\n\t\n\tif ( ball.position.x < - 150 || ball.position.x > 150 ) direction.x = - direction.x;\n\tif ( ball.position.z < - 200 || ball.position.z > 200 ) direction.z = - direction.z;\n\n\tball.position.x = Math.max( - 150, Math.min( 150, ball.position.x ) );\n\tball.position.z = Math.max( - 200, Math.min( 200, ball.position.z ) );\n\t\n\tball.position.add( speed.copy( direction ).multiplyScalar( event.delta / 4 ) );\n\t\n\traycaster.set( ball.position, direction );\n\t\n\tvar intersections = raycaster.intersectObjects( group.children );\n\t\n\tif ( intersections.length > 0 ) {\n\t\n\t\tvar intersection = intersections[ 0 ];\n\t\t\n\t\tif ( intersection.distance < 5 ) {\n\t\t\t\n\t\t\tif ( intersection.object !== paddle ) {\n\n\t\t\t\tgroup.remove( intersection.object );\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tdirection.reflect( intersection.face.normal );\n\t\t\t\n\t\t}\n\t\t\n\t}\n\n}" }] } } \ No newline at end of file diff --git a/editor/examples/pong.app.json b/editor/examples/pong.app.json index fd04fc724049eb..9b8a983c54e653 100755 --- a/editor/examples/pong.app.json +++ b/editor/examples/pong.app.json @@ -128,7 +128,7 @@ "31517222-A9A7-4EAF-B5F6-60751C0BABA3": [ { "name": "Game logic", - "source": "var ball = this.getObjectByName( 'Ball' );\n\nvar position = ball.position;\n\nvar velocity = new THREE.Vector3();\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = Math.random() - 0.5;\ndirection.normalize();\n\nvar pad1 = this.getObjectByName( 'Pad 1' );\nvar pad2 = this.getObjectByName( 'Pad 2' );\n\nvar raycaster = new THREE.Raycaster();\nvar objects = [ pad1, pad2 ];\n\n//\n\nfunction mousemove( event ) {\n\n\tpad1.position.z = ( event.clientX / player.width ) * 300 - 150;\n\tpad2.position.z = - pad1.position.z;\n\n}\n\nfunction update( event ) {\n\n\tif ( position.x < -300 || position.x > 300 ) {\n\t\t\n\t\tdirection.x = - direction.x;\n\t\t\n\t}\n\n\tif ( position.z < -200 || position.z > 200 ) {\n\t\t\n\t\tdirection.z = - direction.z;\n\t\t\n\t}\n\t\n\traycaster.set( position, direction );\n\t\n\tvar intersections = raycaster.intersectObjects( objects );\n\t\n\tif ( intersections.length > 0 ) {\n\n\t\tvar intersection = intersections[ 0 ];\n\t\t\n\t\tif ( intersection.distance < 10 ) {\n\t\t\t\n\t\t\tdirection.reflect( intersection.face.normal );\n\t\t\t\n\t\t}\n\t\t\n\t}\n\n\tposition.add( velocity.copy( direction ).multiplyScalar( event.delta / 2 ) );\n\n}" + "source": "var ball = this.getObjectByName( 'Ball' );\n\nvar position = ball.position;\n\nvar velocity = new THREE.Vector3();\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = Math.random() - 0.5;\ndirection.normalize();\n\nvar pad1 = this.getObjectByName( 'Pad 1' );\nvar pad2 = this.getObjectByName( 'Pad 2' );\n\nvar raycaster = new THREE.Raycaster();\nvar objects = [ pad1, pad2 ];\n\n//\n\nfunction mousemove( event ) {\n\n\tpad1.position.z = ( event.clientX / player.width ) * 300 - 150;\n\tpad2.position.z = - pad1.position.z;\n\n}\n\nfunction update( event ) {\n\t\n\tif ( position.x < -300 || position.x > 300 ) direction.x = - direction.x;\n\tif ( position.z < -200 || position.z > 200 ) direction.z = - direction.z;\n\t\n\tposition.x = Math.max( - 300, Math.min( 300, position.x ) );\n\tposition.z = Math.max( - 200, Math.min( 200, position.z ) );\n\t\n\traycaster.set( position, direction );\n\t\n\tvar intersections = raycaster.intersectObjects( objects );\n\t\n\tif ( intersections.length > 0 ) {\n\n\t\tvar intersection = intersections[ 0 ];\n\t\t\n\t\tif ( intersection.distance < 10 ) {\n\t\t\t\n\t\t\tdirection.reflect( intersection.face.normal );\n\t\t\t\n\t\t}\n\t\t\n\t}\n\n\tposition.add( velocity.copy( direction ).multiplyScalar( event.delta / 2 ) );\n\n}" }] } } \ No newline at end of file From 11092cdb2f47f8701e69e13ac5a003a90d2674c2 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 26 Feb 2015 17:59:16 +0100 Subject: [PATCH 224/333] Editor: VR workflow improvements. --- editor/js/Player.js | 4 ++-- editor/js/libs/app.js | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/editor/js/Player.js b/editor/js/Player.js index 72194b8a00242e..d5fdf308514923 100644 --- a/editor/js/Player.js +++ b/editor/js/Player.js @@ -19,7 +19,7 @@ var Player = function ( editor ) { if ( player.dom === undefined ) return; - player.setSize( container.dom.offsetWidth, container.dom.offsetHeight ); + player.setSize( container.dom.clientWidth, container.dom.clientHeight ); } ); @@ -29,7 +29,7 @@ var Player = function ( editor ) { player.setVR( editor.config.getKey( 'project/vr' ) ); player.load( editor.toJSON() ); - player.setSize( container.dom.offsetWidth, container.dom.offsetHeight ); + player.setSize( container.dom.clientWidth, container.dom.clientHeight ); player.play(); container.dom.appendChild( player.dom ); diff --git a/editor/js/libs/app.js b/editor/js/libs/app.js index 5e1bbdd389fa8b..36b25ecb0a8acd 100644 --- a/editor/js/libs/app.js +++ b/editor/js/libs/app.js @@ -79,6 +79,16 @@ var APP = { controls = new THREE.VRControls( camera ); renderer = new THREE.VREffect( renderer ); + document.addEventListener( 'keyup', function ( event ) { + + switch ( event.keyCode ) { + case 90: + controls.zeroSensor(); + break; + } + + } ); + this.dom.addEventListener( 'dblclick', function () { renderer.setFullScreen( true ); @@ -104,10 +114,7 @@ var APP = { this.setSize = function ( width, height ) { - if ( vr ) { - width = 1280; - height = 800; - } + if ( renderer._fullScreen ) return; this.width = width; this.height = height; From 48be885e6e3b747bd7922b2671f74623ac6c2af0 Mon Sep 17 00:00:00 2001 From: repsac Date: Thu, 26 Feb 2015 22:26:43 -0800 Subject: [PATCH 225/333] added quaternion normalization to rest export --- .../exporters/blender/addons/io_three/__init__.py | 10 ++++++---- .../exporters/blender/addons/io_three/constants.py | 9 +++++---- .../addons/io_three/exporter/api/__init__.py | 4 ++-- .../addons/io_three/exporter/api/animation.py | 1 + .../blender/addons/io_three/exporter/geometry.py | 14 ++++++++------ 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 4762f330d0600d..cd364fd58abbb7 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -42,7 +42,7 @@ bl_info = { 'name': "Three.js Format", 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", - 'version': (1, 2, 4), + 'version': (1, 3, 0), 'blender': (2, 7, 3), 'location': "File > Export", 'description': "Export Three.js formatted JSON files.", @@ -623,8 +623,10 @@ class ExportThree(bpy.types.Operator, ExportHelper): description="Copy textures", default=constants.EXPORT_OPTIONS[constants.COPY_TEXTURES]) - option_texture_folder = StringProperty(name="Texture folder", - description="add this folder to textures path", default="") + option_texture_folder = StringProperty( + name="Texture folder", + description="add this folder to textures path", + default=constants.EXPORT_OPTIONS[constants.TEXTURE_FOLDER]) option_lights = BoolProperty( name="Lights", @@ -822,7 +824,7 @@ def draw(self, context): row.prop(self.properties, 'option_copy_textures') row = layout.row() - row.prop(self.properties, "option_texture_folder") + row.prop(self.properties, 'option_texture_folder') row = layout.row() row.prop(self.properties, 'option_scale') diff --git a/utils/exporters/blender/addons/io_three/constants.py b/utils/exporters/blender/addons/io_three/constants.py index 9fe357b2af98ff..146ebee7b31c85 100644 --- a/utils/exporters/blender/addons/io_three/constants.py +++ b/utils/exporters/blender/addons/io_three/constants.py @@ -63,7 +63,7 @@ FACE_MATERIALS = 'faceMaterials' SKINNING = 'skinning' COPY_TEXTURES = 'copyTextures' -TEXTURE_FOLDER = "textureFolder" +TEXTURE_FOLDER = 'textureFolder' ENABLE_PRECISION = 'enablePrecision' PRECISION = 'precision' DEFAULT_PRECISION = 6 @@ -111,7 +111,7 @@ CAMERAS: False, LIGHTS: False, COPY_TEXTURES: True, - TEXTURE_FOLDER: "", + TEXTURE_FOLDER: '', LOGGING: DEBUG, ENABLE_PRECISION: True, PRECISION: DEFAULT_PRECISION, @@ -173,7 +173,7 @@ MATRIX = 'matrix' POSITION = 'position' QUATERNION = 'quaternion' -ROTATION ='rotation' +ROTATION = 'rotation' SCALE = 'scale' UV = 'uv' @@ -321,7 +321,8 @@ NORMAL_BLENDING = 'NormalBlending' -DBG_COLORS = (0xeeeeee, 0xee0000, 0x00ee00, 0x0000ee, 0xeeee00, 0x00eeee, 0xee00ee) +DBG_COLORS = (0xeeeeee, 0xee0000, 0x00ee00, 0x0000ee, + 0xeeee00, 0x00eeee, 0xee00ee) DOUBLE_SIDED = 'doubleSided' diff --git a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py index e9b92efb723a85..a273c9d482eedc 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py @@ -18,10 +18,10 @@ def batch_mode(): :return: Whether or not the session is interactive :rtype: bool - + """ return bpy.context.area is None - + def init(): """Initializing the api module. Required first step before diff --git a/utils/exporters/blender/addons/io_three/exporter/api/animation.py b/utils/exporters/blender/addons/io_three/exporter/api/animation.py index 76119d6cdaadab..3d3551181488b6 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/animation.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/animation.py @@ -89,6 +89,7 @@ def _parse_rest_action(action, armature, options, round_off, round_val): action, armature.matrix_world) rot, rchange = _rotation(bone, computed_frame, action, rotation_matrix) + rot = _normalize_quaternion(rot) if round_off: pos_x, pos_y, pos_z = utilities.round_off( diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index 53e171d239dee2..341c89063033fe 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -115,7 +115,7 @@ def metadata(self): def copy(self, scene=True): """Copy the geometry definitions to a standard dictionary. - :param scene: toggle for scene formatting + :param scene: toggle for scene formatting (Default value = True) :type scene: bool :rtype: dict @@ -135,16 +135,17 @@ def copy(self, scene=True): return data - def copy_textures(self, texture_folder=""): + def copy_textures(self, texture_folder=''): """Copy the textures to the destination directory.""" logger.debug("Geometry().copy_textures()") if self.options.get(constants.COPY_TEXTURES): texture_registration = self.register_textures() if texture_registration: logger.info("%s has registered textures", self.node) + dirname = os.path.dirname(self.scene.filepath) + full_path = os.path.join(dirname, texture_folder) io.copy_registered_textures( - os.path.join(os.path.dirname(self.scene.filepath), texture_folder), - texture_registration) + full_path, texture_registration) def parse(self): """Parse the current node""" @@ -169,7 +170,7 @@ def write(self, filepath=None): """Write the geometry definitions to disk. Uses the desitnation path of the scene. - :param filepath: optional output file path + :param filepath: optional output file path (Default value = None) :type filepath: str @@ -307,7 +308,8 @@ def _geometry_metadata(self, metadata): pass continue - if key in skip: continue + if key in skip: + continue metadata[key] = len(self[key]) From ff3fa630514461fecf01131ca155e4a757e2ae7b Mon Sep 17 00:00:00 2001 From: DodekaHydra Date: Fri, 27 Feb 2015 13:56:47 -0800 Subject: [PATCH 226/333] Additional parameter to allow linear color shift addRGB will shift all colors linearly, before applying exponential and multiplicative color shifts. addRGB vector takes values in range [-1, 1]. This is a small tweak to enable a much wider application of this shader code. --- examples/js/shaders/ColorCorrectionShader.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/js/shaders/ColorCorrectionShader.js b/examples/js/shaders/ColorCorrectionShader.js index 20da4696f7f9bc..122d5d599d3dca 100644 --- a/examples/js/shaders/ColorCorrectionShader.js +++ b/examples/js/shaders/ColorCorrectionShader.js @@ -1,6 +1,7 @@ /** * @author alteredq / http://alteredqualia.com/ * + * * Color correction */ @@ -10,7 +11,8 @@ THREE.ColorCorrectionShader = { "tDiffuse": { type: "t", value: null }, "powRGB": { type: "v3", value: new THREE.Vector3( 2, 2, 2 ) }, - "mulRGB": { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } + "mulRGB": { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }, + "addRGB": { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) } }, @@ -33,13 +35,14 @@ THREE.ColorCorrectionShader = { "uniform sampler2D tDiffuse;", "uniform vec3 powRGB;", "uniform vec3 mulRGB;", + "uniform vec3 addRGB;", "varying vec2 vUv;", "void main() {", "gl_FragColor = texture2D( tDiffuse, vUv );", - "gl_FragColor.rgb = mulRGB * pow( gl_FragColor.rgb, powRGB );", + "gl_FragColor.rgb = mulRGB * pow( (gl_FragColor.rgb + addRGB), powRGB );", "}" From 1764982ffe1d1c36dfb2342614f90f7921480aff Mon Sep 17 00:00:00 2001 From: DodekaHydra Date: Fri, 27 Feb 2015 13:58:54 -0800 Subject: [PATCH 227/333] Update ColorCorrectionShader.js --- examples/js/shaders/ColorCorrectionShader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/shaders/ColorCorrectionShader.js b/examples/js/shaders/ColorCorrectionShader.js index 122d5d599d3dca..1b9fc759b2b629 100644 --- a/examples/js/shaders/ColorCorrectionShader.js +++ b/examples/js/shaders/ColorCorrectionShader.js @@ -35,7 +35,7 @@ THREE.ColorCorrectionShader = { "uniform sampler2D tDiffuse;", "uniform vec3 powRGB;", "uniform vec3 mulRGB;", - "uniform vec3 addRGB;", + "uniform vec3 addRGB;", "varying vec2 vUv;", From ab7c0a8ac9673e854f5b684510e6c4faa87b2c4a Mon Sep 17 00:00:00 2001 From: repsac Date: Fri, 27 Feb 2015 15:59:17 -0800 Subject: [PATCH 228/333] Fixed a bug where None value was returned on geometries that had no morph targets when morph animation export was selected --- .../exporters/blender/addons/io_three/exporter/api/mesh.py | 2 +- .../exporters/blender/addons/io_three/exporter/geometry.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py index f770a5792ec43c..b7e87f9e26d2a2 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py @@ -340,7 +340,7 @@ def morph_targets(mesh, options): break else: logger.info("No valid morph data detected") - return + return [] manifest = [] for index, morph in enumerate(morphs): diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index 341c89063033fe..b446e436f3aad0 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -432,12 +432,12 @@ def _parse_geometry(self): self[constants.INFLUENCES_PER_VERTEX] = influences self[constants.SKIN_INDICES] = api.mesh.skin_indices( - self.node, bone_map, influences) + self.node, bone_map, influences) or [] self[constants.SKIN_WEIGHTS] = api.mesh.skin_weights( - self.node, bone_map, influences) + self.node, bone_map, influences) or [] if self.options.get(constants.MORPH_TARGETS): logger.info("Parsing %s", constants.MORPH_TARGETS) self[constants.MORPH_TARGETS] = api.mesh.morph_targets( - self.node, self.options) + self.node, self.options) or [] From 688cde2f6cbed70b2ce0ca74e13d585a22cca15f Mon Sep 17 00:00:00 2001 From: rkusa Date: Mon, 2 Mar 2015 11:53:57 +0100 Subject: [PATCH 229/333] add blender logging handlers only once --- .../blender/addons/io_three/logger.py | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/logger.py b/utils/exporters/blender/addons/io_three/logger.py index 5e15d265a433dd..0c888df86897ac 100644 --- a/utils/exporters/blender/addons/io_three/logger.py +++ b/utils/exporters/blender/addons/io_three/logger.py @@ -32,20 +32,21 @@ def init(filename, level=constants.DEBUG): LOGGER = logging.getLogger('Three.Export') LOGGER.setLevel(LEVELS[level]) - stream = logging.StreamHandler() - stream.setLevel(LEVELS[level]) + if not LOGGER.handlers: + stream = logging.StreamHandler() + stream.setLevel(LEVELS[level]) - format_ = '%(asctime)s - %(name)s - %(levelname)s: %(message)s' - formatter = logging.Formatter(format_) + format_ = '%(asctime)s - %(name)s - %(levelname)s: %(message)s' + formatter = logging.Formatter(format_) - stream.setFormatter(formatter) + stream.setFormatter(formatter) - file_handler = logging.FileHandler(LOG_FILE) - file_handler.setLevel(LEVELS[level]) - file_handler.setFormatter(formatter) + file_handler = logging.FileHandler(LOG_FILE) + file_handler.setLevel(LEVELS[level]) + file_handler.setFormatter(formatter) - LOGGER.addHandler(stream) - LOGGER.addHandler(file_handler) + LOGGER.addHandler(stream) + LOGGER.addHandler(file_handler) def info(*args): From 09de063fab78570fa10b4ecbc1b2bc17545f4738 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 2 Mar 2015 18:57:01 +0100 Subject: [PATCH 230/333] WebGLRenderer: Derivatives based FlatShading in MeshPhongMaterial. See #6117. --- src/renderers/WebGLRenderer.js | 2 ++ .../shaders/ShaderChunk/lights_phong_fragment.glsl | 13 ++++++++++++- src/renderers/webgl/WebGLProgram.js | 5 +++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index a8f5695abe07bf..a584d6942f78da 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -4165,6 +4165,8 @@ THREE.WebGLRenderer = function ( parameters ) { useFog: material.fog, fogExp: fog instanceof THREE.FogExp2, + flatShading: material.shading === THREE.FlatShading, + sizeAttenuation: material.sizeAttenuation, logarithmicDepthBuffer: _logarithmicDepthBuffer, diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index ddcbbdb00fd7d6..1c96d79ae2b20c 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,4 +1,15 @@ -vec3 normal = normalize( vNormal ); +#ifdef FLAT_SHADED + + vec3 fdx = dFdx( vViewPosition ); + vec3 fdy = dFdy( vViewPosition ); + vec3 normal = normalize( cross( fdx, fdy ) ); + +#else + + vec3 normal = normalize( vNormal ); + +#endif + vec3 viewPosition = normalize( vViewPosition ); #ifdef DOUBLE_SIDED diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 7e50e996ff2a0f..30b77aafe75c8a 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -267,7 +267,7 @@ THREE.WebGLProgram = ( function () { 'precision ' + parameters.precision + ' float;', 'precision ' + parameters.precision + ' int;', - ( parameters.bumpMap || parameters.normalMap ) ? '#extension GL_OES_standard_derivatives : enable' : '', + ( parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', customDefines, @@ -278,6 +278,7 @@ THREE.WebGLProgram = ( function () { '#define MAX_SHADOWS ' + parameters.maxShadows, + parameters.flatShading ? '#define FLAT_SHADED': '', parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '', _this.gammaInput ? '#define GAMMA_INPUT' : '', @@ -345,7 +346,7 @@ THREE.WebGLProgram = ( function () { THREE.error( 'THREE.WebGLProgram: shader error: ' + _gl.getError(), 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ), 'gl.getPRogramInfoLog', programLogInfo ); } - + if ( programLogInfo !== '' ) { THREE.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()' + programLogInfo ); From 9d72d80f3fb00d8e3532ace349c39eba2a8ff22a Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 2 Mar 2015 18:59:11 +0100 Subject: [PATCH 231/333] MeshNormalMaterial: Removed shading property. --- docs/api/materials/MeshNormalMaterial.html | 19 ++++++------------- src/materials/MeshNormalMaterial.js | 4 ---- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/docs/api/materials/MeshNormalMaterial.html b/docs/api/materials/MeshNormalMaterial.html index 37ca144e1b2e17..80b32009d5fad7 100644 --- a/docs/api/materials/MeshNormalMaterial.html +++ b/docs/api/materials/MeshNormalMaterial.html @@ -12,7 +12,7 @@

[name]

A material that maps the normal vectors to RGB colors.
- + @@ -21,10 +21,9 @@

Constructor

[name]([page:Object parameters])

- parameters is an object with one or more properties defining the material's appearance. + parameters is an object with one or more properties defining the material's appearance.
- shading -- How the triangles of a curved surface are rendered. Default is [page:Materials THREE.FlatShading].
wireframe -- Render geometry as wireframe. Default is false (i.e. render as smooth shaded).
wireframeLinewidth -- Controls wireframe thickness. Default is 1.
morphTargets -- Define whether the material uses morphTargets. Default is false.
@@ -34,25 +33,19 @@

[name]([page:Object parameters])

Properties

-

[property:number shading]

+

[property:boolean wireframe]

- How the triangles of a curved surface are rendered: as a smooth surface, as flat separate facets, or no shading at all.

- Options are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading](default) + Render geometry as wireframe. Default is false (i.e. render as smooth shaded).
-

[property:boolean wireframe]

-
- Render geometry as wireframe. Default is false (i.e. render as smooth shaded). -
-

[property:number wireframeLinewidth]

Controls wireframe thickness. Default is 1.

Due to limitations in the ANGLE layer, on Windows platforms linewidth will always be 1 regardless of the set value. -
+

[property:boolean morphTargets]

-
Define whether the material uses morphTargets. Default is false.
+
Define whether the material uses morphTargets. Default is false.

Methods

diff --git a/src/materials/MeshNormalMaterial.js b/src/materials/MeshNormalMaterial.js index 1839fc70394877..1895f002b59f5b 100644 --- a/src/materials/MeshNormalMaterial.js +++ b/src/materials/MeshNormalMaterial.js @@ -20,8 +20,6 @@ THREE.MeshNormalMaterial = function ( parameters ) { this.type = 'MeshNormalMaterial'; - this.shading = THREE.FlatShading; - this.wireframe = false; this.wireframeLinewidth = 1; @@ -40,8 +38,6 @@ THREE.MeshNormalMaterial.prototype.clone = function () { THREE.Material.prototype.clone.call( this, material ); - material.shading = this.shading; - material.wireframe = this.wireframe; material.wireframeLinewidth = this.wireframeLinewidth; From bfd29f459f9f97ff2bc907dc5b582d6f00d273ba Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 2 Mar 2015 19:34:54 +0100 Subject: [PATCH 232/333] WebGLRenderer: Avoid flat shading buffer creation when using MeshPhongMaterial and clean up. See #6117. --- examples/webgl_lights_pointlights.html | 2 +- src/materials/Material.js | 7 +++-- src/renderers/WebGLRenderer.js | 29 ++++++++++--------- .../ShaderChunk/lights_phong_fragment.glsl | 10 +++---- .../lights_phong_pars_fragment.glsl | 7 ++++- src/renderers/shaders/ShaderLib.js | 13 +++++++-- src/renderers/webgl/WebGLProgram.js | 5 +++- 7 files changed, 46 insertions(+), 27 deletions(-) diff --git a/examples/webgl_lights_pointlights.html b/examples/webgl_lights_pointlights.html index b33b3cacb2dbb0..20a3903ec93478 100644 --- a/examples/webgl_lights_pointlights.html +++ b/examples/webgl_lights_pointlights.html @@ -73,7 +73,7 @@ var callback = function( geometry ) { - object = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: 0x555555, specular: 0xffffff, shininess: 50, shading: THREE.SmoothShading } ) ); + object = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: 0x555555, specular: 0xffffff, shininess: 50 } ) ); object.scale.x = object.scale.y = object.scale.z = 0.80; scene.add( object ); diff --git a/src/materials/Material.js b/src/materials/Material.js index 9a3ca891e1c7f4..216c07b966a682 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -133,6 +133,7 @@ THREE.Material.prototype = { output.color = this.color.getHex(); output.emissive = this.emissive.getHex(); if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; + if ( this.shading !== THREE.SmoothShading ) output.shading = this.shading; if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; if ( this.side !== THREE.FrontSide ) output.side = this.side; @@ -143,12 +144,12 @@ THREE.Material.prototype = { output.specular = this.specular.getHex(); output.shininess = this.shininess; if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; + if ( this.shading !== THREE.SmoothShading ) output.shading = this.shading; if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; if ( this.side !== THREE.FrontSide ) output.side = this.side; } else if ( this instanceof THREE.MeshNormalMaterial ) { - if ( this.shading !== THREE.FlatShading ) output.shading = this.shading; if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; if ( this.side !== THREE.FrontSide ) output.side = this.side; @@ -162,10 +163,10 @@ THREE.Material.prototype = { output.size = this.size; output.sizeAttenuation = this.sizeAttenuation; output.color = this.color.getHex(); - + if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; - + } else if ( this instanceof THREE.ShaderMaterial ) { output.uniforms = this.uniforms; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index a584d6942f78da..998bbaccd203a9 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1179,13 +1179,13 @@ THREE.WebGLRenderer = function ( parameters ) { ? object.material.materials[ geometryGroup.materialIndex ] : object.material; - }; + } - function materialNeedsSmoothNormals ( material ) { + function materialNeedsFaceNormals ( material ) { - return material && material.shading !== undefined && material.shading === THREE.SmoothShading; + return material instanceof THREE.MeshPhongMaterial === false && material.shading === THREE.FlatShading; - }; + } // Buffer setting @@ -1526,7 +1526,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - var needsSmoothNormals = materialNeedsSmoothNormals( material ); + var needsFaceNormals = materialNeedsFaceNormals( material ); var f, fl, fi, face, vertexNormals, faceNormal, normal, @@ -1671,7 +1671,13 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material.morphNormals ) { - if ( needsSmoothNormals ) { + if ( needsFaceNormals ) { + + n1 = morphNormals[ vk ].faceNormals[ chf ]; + n2 = n1; + n3 = n1; + + } else { faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ]; @@ -1679,12 +1685,6 @@ THREE.WebGLRenderer = function ( parameters ) { n2 = faceVertexNormals.b; n3 = faceVertexNormals.c; - } else { - - n1 = morphNormals[ vk ].faceNormals[ chf ]; - n2 = n1; - n3 = n1; - } nka = morphNormalsArrays[ vk ]; @@ -1880,7 +1880,7 @@ THREE.WebGLRenderer = function ( parameters ) { vertexNormals = face.vertexNormals; faceNormal = face.normal; - if ( vertexNormals.length === 3 && needsSmoothNormals ) { + if ( vertexNormals.length === 3 && needsFaceNormals === false ) { for ( i = 0; i < 3; i ++ ) { @@ -2343,7 +2343,8 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer ); - if ( material.shading === THREE.FlatShading ) { + if ( material instanceof THREE.MeshPhongMaterial === false && + material.shading === THREE.FlatShading ) { var nx, ny, nz, nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz, diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 1c96d79ae2b20c..21486d256b3126 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,12 +1,12 @@ -#ifdef FLAT_SHADED +#ifndef FLAT_SHADED - vec3 fdx = dFdx( vViewPosition ); - vec3 fdy = dFdy( vViewPosition ); - vec3 normal = normalize( cross( fdx, fdy ) ); + vec3 normal = normalize( vNormal ); #else - vec3 normal = normalize( vNormal ); + vec3 fdx = dFdx( vViewPosition ); + vec3 fdy = dFdy( vViewPosition ); + vec3 normal = normalize( cross( fdx, fdy ) ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index cc78d8166e9cf8..28bb67544b1ffe 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -50,4 +50,9 @@ uniform vec3 ambientLightColor; #endif varying vec3 vViewPosition; -varying vec3 vNormal; + +#ifndef FLAT_SHADED + + varying vec3 vNormal; + +#endif diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 4b64670e4f8bfb..0bf4b13e2ef8eb 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -252,7 +252,12 @@ THREE.ShaderLib = { "#define PHONG", "varying vec3 vViewPosition;", - "varying vec3 vNormal;", + + "#ifndef FLAT_SHADED", + + " varying vec3 vNormal;", + + "#endif", THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "map_pars_vertex" ], @@ -276,8 +281,12 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "skinnormal_vertex" ], THREE.ShaderChunk[ "defaultnormal_vertex" ], + "#ifndef FLAT_SHADED", + " vNormal = normalize( transformedNormal );", + "#endif", + THREE.ShaderChunk[ "morphtarget_vertex" ], THREE.ShaderChunk[ "skinning_vertex" ], THREE.ShaderChunk[ "default_vertex" ], @@ -692,7 +701,7 @@ THREE.ShaderLib = { "vec3 direction = normalize( vWorldPosition );", "vec2 sampleUV;", "sampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );", - "sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", + "sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", "gl_FragColor = texture2D( tEquirect, sampleUV );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 30b77aafe75c8a..e57ad9ced43401 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -188,6 +188,8 @@ THREE.WebGLProgram = ( function () { parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.flatShading ? '#define FLAT_SHADED': '', + parameters.skinning ? '#define USE_SKINNING' : '', parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', @@ -278,7 +280,6 @@ THREE.WebGLProgram = ( function () { '#define MAX_SHADOWS ' + parameters.maxShadows, - parameters.flatShading ? '#define FLAT_SHADED': '', parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '', _this.gammaInput ? '#define GAMMA_INPUT' : '', @@ -300,6 +301,8 @@ THREE.WebGLProgram = ( function () { parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.flatShading ? '#define FLAT_SHADED': '', + parameters.metal ? '#define METAL' : '', parameters.wrapAround ? '#define WRAP_AROUND' : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', From 5cecfda6c19b531a7d17f16103ca15f22d440739 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 2 Mar 2015 19:35:34 +0100 Subject: [PATCH 233/333] Updated builds. --- build/three.js | 67 ++++++----- build/three.min.js | 275 +++++++++++++++++++++++---------------------- 2 files changed, 178 insertions(+), 164 deletions(-) diff --git a/build/three.js b/build/three.js index 1c40c2b5a9b187..38603363eda016 100644 --- a/build/three.js +++ b/build/three.js @@ -13514,6 +13514,7 @@ THREE.Material.prototype = { output.color = this.color.getHex(); output.emissive = this.emissive.getHex(); if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; + if ( this.shading !== THREE.SmoothShading ) output.shading = this.shading; if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; if ( this.side !== THREE.FrontSide ) output.side = this.side; @@ -13524,12 +13525,12 @@ THREE.Material.prototype = { output.specular = this.specular.getHex(); output.shininess = this.shininess; if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; + if ( this.shading !== THREE.SmoothShading ) output.shading = this.shading; if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; if ( this.side !== THREE.FrontSide ) output.side = this.side; } else if ( this instanceof THREE.MeshNormalMaterial ) { - if ( this.shading !== THREE.FlatShading ) output.shading = this.shading; if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; if ( this.side !== THREE.FrontSide ) output.side = this.side; @@ -13543,10 +13544,10 @@ THREE.Material.prototype = { output.size = this.size; output.sizeAttenuation = this.sizeAttenuation; output.color = this.color.getHex(); - + if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors; if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending; - + } else if ( this instanceof THREE.ShaderMaterial ) { output.uniforms = this.uniforms; @@ -14247,8 +14248,6 @@ THREE.MeshNormalMaterial = function ( parameters ) { this.type = 'MeshNormalMaterial'; - this.shading = THREE.FlatShading; - this.wireframe = false; this.wireframeLinewidth = 1; @@ -14267,8 +14266,6 @@ THREE.MeshNormalMaterial.prototype.clone = function () { THREE.Material.prototype.clone.call( this, material ); - material.shading = this.shading; - material.wireframe = this.wireframe; material.wireframeLinewidth = this.wireframeLinewidth; @@ -16586,7 +16583,7 @@ THREE.ShaderChunk[ 'lightmap_pars_vertex'] = "#ifdef USE_LIGHTMAP\n\n varying ve // File:src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_fragment'] = "vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n#endif\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n vec3 pointDiffuse = vec3( 0.0 );\n vec3 pointSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n vec3 spotDiffuse = vec3( 0.0 );\n vec3 spotSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n vec3 dirDiffuse = vec3( 0.0 );\n vec3 dirSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n vec3 hemiDiffuse = vec3( 0.0 );\n vec3 hemiSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n hemiDiffuse += diffuse * hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n totalDiffuse += dirDiffuse;\n totalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n totalDiffuse += hemiDiffuse;\n totalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n totalDiffuse += pointDiffuse;\n totalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n totalDiffuse += spotDiffuse;\n totalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif\n"; +THREE.ShaderChunk[ 'lights_phong_fragment'] = "#ifndef FLAT_SHADED\n\n vec3 normal = normalize( vNormal );\n\n#else\n\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n#endif\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n vec3 pointDiffuse = vec3( 0.0 );\n vec3 pointSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n vec3 spotDiffuse = vec3( 0.0 );\n vec3 spotSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n vec3 dirDiffuse = vec3( 0.0 );\n vec3 dirSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n vec3 hemiDiffuse = vec3( 0.0 );\n vec3 hemiSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n hemiDiffuse += diffuse * hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n totalDiffuse += dirDiffuse;\n totalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n totalDiffuse += hemiDiffuse;\n totalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n totalDiffuse += pointDiffuse;\n totalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n totalDiffuse += spotDiffuse;\n totalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl @@ -16702,7 +16699,7 @@ THREE.ShaderChunk[ 'defaultnormal_vertex'] = "#ifdef USE_SKINNING\n\n vec3 objec // File:src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_pars_fragment'] = "uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n uniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n varying vec3 vWorldPosition;\n\n#endif\n\n#ifdef WRAP_AROUND\n\n uniform vec3 wrapRGB;\n\n#endif\n\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;\n"; +THREE.ShaderChunk[ 'lights_phong_pars_fragment'] = "uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n uniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n varying vec3 vWorldPosition;\n\n#endif\n\n#ifdef WRAP_AROUND\n\n uniform vec3 wrapRGB;\n\n#endif\n\nvarying vec3 vViewPosition;\n\n#ifndef FLAT_SHADED\n\n varying vec3 vNormal;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/skinbase_vertex.glsl @@ -17192,7 +17189,12 @@ THREE.ShaderLib = { "#define PHONG", "varying vec3 vViewPosition;", - "varying vec3 vNormal;", + + "#ifndef FLAT_SHADED", + + " varying vec3 vNormal;", + + "#endif", THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "map_pars_vertex" ], @@ -17216,8 +17218,12 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "skinnormal_vertex" ], THREE.ShaderChunk[ "defaultnormal_vertex" ], + "#ifndef FLAT_SHADED", + " vNormal = normalize( transformedNormal );", + "#endif", + THREE.ShaderChunk[ "morphtarget_vertex" ], THREE.ShaderChunk[ "skinning_vertex" ], THREE.ShaderChunk[ "default_vertex" ], @@ -17632,7 +17638,7 @@ THREE.ShaderLib = { "vec3 direction = normalize( vWorldPosition );", "vec2 sampleUV;", "sampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );", - "sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", + "sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", "gl_FragColor = texture2D( tEquirect, sampleUV );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], @@ -18903,13 +18909,13 @@ THREE.WebGLRenderer = function ( parameters ) { ? object.material.materials[ geometryGroup.materialIndex ] : object.material; - }; + } - function materialNeedsSmoothNormals ( material ) { + function materialNeedsFaceNormals ( material ) { - return material && material.shading !== undefined && material.shading === THREE.SmoothShading; + return material instanceof THREE.MeshPhongMaterial === false && material.shading === THREE.FlatShading; - }; + } // Buffer setting @@ -19250,7 +19256,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - var needsSmoothNormals = materialNeedsSmoothNormals( material ); + var needsFaceNormals = materialNeedsFaceNormals( material ); var f, fl, fi, face, vertexNormals, faceNormal, normal, @@ -19395,7 +19401,13 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material.morphNormals ) { - if ( needsSmoothNormals ) { + if ( needsFaceNormals ) { + + n1 = morphNormals[ vk ].faceNormals[ chf ]; + n2 = n1; + n3 = n1; + + } else { faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ]; @@ -19403,12 +19415,6 @@ THREE.WebGLRenderer = function ( parameters ) { n2 = faceVertexNormals.b; n3 = faceVertexNormals.c; - } else { - - n1 = morphNormals[ vk ].faceNormals[ chf ]; - n2 = n1; - n3 = n1; - } nka = morphNormalsArrays[ vk ]; @@ -19604,7 +19610,7 @@ THREE.WebGLRenderer = function ( parameters ) { vertexNormals = face.vertexNormals; faceNormal = face.normal; - if ( vertexNormals.length === 3 && needsSmoothNormals ) { + if ( vertexNormals.length === 3 && needsFaceNormals === false ) { for ( i = 0; i < 3; i ++ ) { @@ -20067,7 +20073,8 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer ); - if ( material.shading === THREE.FlatShading ) { + if ( material instanceof THREE.MeshPhongMaterial === false && + material.shading === THREE.FlatShading ) { var nx, ny, nz, nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz, @@ -21889,6 +21896,8 @@ THREE.WebGLRenderer = function ( parameters ) { useFog: material.fog, fogExp: fog instanceof THREE.FogExp2, + flatShading: material.shading === THREE.FlatShading, + sizeAttenuation: material.sizeAttenuation, logarithmicDepthBuffer: _logarithmicDepthBuffer, @@ -24310,6 +24319,8 @@ THREE.WebGLProgram = ( function () { parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.flatShading ? '#define FLAT_SHADED': '', + parameters.skinning ? '#define USE_SKINNING' : '', parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', @@ -24389,7 +24400,7 @@ THREE.WebGLProgram = ( function () { 'precision ' + parameters.precision + ' float;', 'precision ' + parameters.precision + ' int;', - ( parameters.bumpMap || parameters.normalMap ) ? '#extension GL_OES_standard_derivatives : enable' : '', + ( parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', customDefines, @@ -24421,6 +24432,8 @@ THREE.WebGLProgram = ( function () { parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.flatShading ? '#define FLAT_SHADED': '', + parameters.metal ? '#define METAL' : '', parameters.wrapAround ? '#define WRAP_AROUND' : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', @@ -24467,7 +24480,7 @@ THREE.WebGLProgram = ( function () { THREE.error( 'THREE.WebGLProgram: shader error: ' + _gl.getError(), 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ), 'gl.getPRogramInfoLog', programLogInfo ); } - + if ( programLogInfo !== '' ) { THREE.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()' + programLogInfo ); diff --git a/build/three.min.js b/build/three.min.js index e566a0a7222d69..8526708eb4a103 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -298,12 +298,13 @@ THREE.Material=function(){Object.defineProperty(this,"id",{value:THREE.MaterialI !1;this.overdraw=this.alphaTest=this.polygonOffsetUnits=this.polygonOffsetFactor=0;this._needsUpdate=this.visible=!0}; THREE.Material.prototype={constructor:THREE.Material,get needsUpdate(){return this._needsUpdate},set needsUpdate(a){!0===a&&this.update();this._needsUpdate=a},setValues:function(a){if(void 0!==a)for(var b in a){var c=a[b];if(void 0===c)THREE.warn("THREE.Material: '"+b+"' parameter is undefined.");else if(b in this){var d=this[b];d instanceof THREE.Color?d.set(c):d instanceof THREE.Vector3&&c instanceof THREE.Vector3?d.copy(c):this[b]="overdraw"==b?Number(c):c}}},toJSON:function(){var a={metadata:{version:4.2, type:"material",generator:"MaterialExporter"},uuid:this.uuid,type:this.type};""!==this.name&&(a.name=this.name);this instanceof THREE.MeshBasicMaterial?(a.color=this.color.getHex(),this.vertexColors!==THREE.NoColors&&(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshLambertMaterial?(a.color=this.color.getHex(),a.emissive=this.emissive.getHex(),this.vertexColors!==THREE.NoColors&& -(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshPhongMaterial?(a.color=this.color.getHex(),a.emissive=this.emissive.getHex(),a.specular=this.specular.getHex(),a.shininess=this.shininess,this.vertexColors!==THREE.NoColors&&(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof -THREE.MeshNormalMaterial?(this.shading!==THREE.FlatShading&&(a.shading=this.shading),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshDepthMaterial?(this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.PointCloudMaterial?(a.size=this.size,a.sizeAttenuation=this.sizeAttenuation,a.color=this.color.getHex(),this.vertexColors!==THREE.NoColors&& -(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending)):this instanceof THREE.ShaderMaterial?(a.uniforms=this.uniforms,a.vertexShader=this.vertexShader,a.fragmentShader=this.fragmentShader):this instanceof THREE.SpriteMaterial&&(a.color=this.color.getHex());1>this.opacity&&(a.opacity=this.opacity);!1!==this.transparent&&(a.transparent=this.transparent);!1!==this.wireframe&&(a.wireframe=this.wireframe);return a},clone:function(a){void 0===a&&(a=new THREE.Material); -a.name=this.name;a.side=this.side;a.opacity=this.opacity;a.transparent=this.transparent;a.blending=this.blending;a.blendSrc=this.blendSrc;a.blendDst=this.blendDst;a.blendEquation=this.blendEquation;a.blendSrcAlpha=this.blendSrcAlpha;a.blendDstAlpha=this.blendDstAlpha;a.blendEquationAlpha=this.blendEquationAlpha;a.depthTest=this.depthTest;a.depthWrite=this.depthWrite;a.polygonOffset=this.polygonOffset;a.polygonOffsetFactor=this.polygonOffsetFactor;a.polygonOffsetUnits=this.polygonOffsetUnits;a.alphaTest= -this.alphaTest;a.overdraw=this.overdraw;a.visible=this.visible;return a},update:function(){this.dispatchEvent({type:"update"})},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Material.prototype);THREE.MaterialIdCount=0;THREE.LineBasicMaterial=function(a){THREE.Material.call(this);this.type="LineBasicMaterial";this.color=new THREE.Color(16777215);this.linewidth=1;this.linejoin=this.linecap="round";this.vertexColors=THREE.NoColors;this.fog=!0;this.setValues(a)}; -THREE.LineBasicMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineBasicMaterial.prototype.constructor=THREE.LineBasicMaterial;THREE.LineBasicMaterial.prototype.clone=function(){var a=new THREE.LineBasicMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.linewidth=this.linewidth;a.linecap=this.linecap;a.linejoin=this.linejoin;a.vertexColors=this.vertexColors;a.fog=this.fog;return a}; +(a.vertexColors=this.vertexColors),this.shading!==THREE.SmoothShading&&(a.shading=this.shading),this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshPhongMaterial?(a.color=this.color.getHex(),a.emissive=this.emissive.getHex(),a.specular=this.specular.getHex(),a.shininess=this.shininess,this.vertexColors!==THREE.NoColors&&(a.vertexColors=this.vertexColors),this.shading!==THREE.SmoothShading&&(a.shading=this.shading), +this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshNormalMaterial?(this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.MeshDepthMaterial?(this.blending!==THREE.NormalBlending&&(a.blending=this.blending),this.side!==THREE.FrontSide&&(a.side=this.side)):this instanceof THREE.PointCloudMaterial?(a.size=this.size,a.sizeAttenuation= +this.sizeAttenuation,a.color=this.color.getHex(),this.vertexColors!==THREE.NoColors&&(a.vertexColors=this.vertexColors),this.blending!==THREE.NormalBlending&&(a.blending=this.blending)):this instanceof THREE.ShaderMaterial?(a.uniforms=this.uniforms,a.vertexShader=this.vertexShader,a.fragmentShader=this.fragmentShader):this instanceof THREE.SpriteMaterial&&(a.color=this.color.getHex());1>this.opacity&&(a.opacity=this.opacity);!1!==this.transparent&&(a.transparent=this.transparent);!1!==this.wireframe&& +(a.wireframe=this.wireframe);return a},clone:function(a){void 0===a&&(a=new THREE.Material);a.name=this.name;a.side=this.side;a.opacity=this.opacity;a.transparent=this.transparent;a.blending=this.blending;a.blendSrc=this.blendSrc;a.blendDst=this.blendDst;a.blendEquation=this.blendEquation;a.blendSrcAlpha=this.blendSrcAlpha;a.blendDstAlpha=this.blendDstAlpha;a.blendEquationAlpha=this.blendEquationAlpha;a.depthTest=this.depthTest;a.depthWrite=this.depthWrite;a.polygonOffset=this.polygonOffset;a.polygonOffsetFactor= +this.polygonOffsetFactor;a.polygonOffsetUnits=this.polygonOffsetUnits;a.alphaTest=this.alphaTest;a.overdraw=this.overdraw;a.visible=this.visible;return a},update:function(){this.dispatchEvent({type:"update"})},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Material.prototype);THREE.MaterialIdCount=0; +THREE.LineBasicMaterial=function(a){THREE.Material.call(this);this.type="LineBasicMaterial";this.color=new THREE.Color(16777215);this.linewidth=1;this.linejoin=this.linecap="round";this.vertexColors=THREE.NoColors;this.fog=!0;this.setValues(a)};THREE.LineBasicMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineBasicMaterial.prototype.constructor=THREE.LineBasicMaterial; +THREE.LineBasicMaterial.prototype.clone=function(){var a=new THREE.LineBasicMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.linewidth=this.linewidth;a.linecap=this.linecap;a.linejoin=this.linejoin;a.vertexColors=this.vertexColors;a.fog=this.fog;return a}; THREE.LineDashedMaterial=function(a){THREE.Material.call(this);this.type="LineDashedMaterial";this.color=new THREE.Color(16777215);this.scale=this.linewidth=1;this.dashSize=3;this.gapSize=1;this.vertexColors=!1;this.fog=!0;this.setValues(a)};THREE.LineDashedMaterial.prototype=Object.create(THREE.Material.prototype);THREE.LineDashedMaterial.prototype.constructor=THREE.LineDashedMaterial; THREE.LineDashedMaterial.prototype.clone=function(){var a=new THREE.LineDashedMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.linewidth=this.linewidth;a.scale=this.scale;a.dashSize=this.dashSize;a.gapSize=this.gapSize;a.vertexColors=this.vertexColors;a.fog=this.fog;return a}; THREE.MeshBasicMaterial=function(a){THREE.Material.call(this);this.type="MeshBasicMaterial";this.color=new THREE.Color(16777215);this.envMap=this.alphaMap=this.specularMap=this.lightMap=this.map=null;this.combine=THREE.MultiplyOperation;this.reflectivity=1;this.refractionRatio=.98;this.fog=!0;this.shading=THREE.SmoothShading;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.vertexColors=THREE.NoColors;this.morphTargets=this.skinning=!1;this.setValues(a)}; @@ -319,8 +320,8 @@ THREE.MeshPhongMaterial=function(a){THREE.Material.call(this);this.type="MeshPho THREE.MeshPhongMaterial.prototype.clone=function(){var a=new THREE.MeshPhongMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.emissive.copy(this.emissive);a.specular.copy(this.specular);a.shininess=this.shininess;a.metal=this.metal;a.wrapAround=this.wrapAround;a.wrapRGB.copy(this.wrapRGB);a.map=this.map;a.lightMap=this.lightMap;a.bumpMap=this.bumpMap;a.bumpScale=this.bumpScale;a.normalMap=this.normalMap;a.normalScale.copy(this.normalScale);a.specularMap=this.specularMap; a.alphaMap=this.alphaMap;a.envMap=this.envMap;a.combine=this.combine;a.reflectivity=this.reflectivity;a.refractionRatio=this.refractionRatio;a.fog=this.fog;a.shading=this.shading;a.wireframe=this.wireframe;a.wireframeLinewidth=this.wireframeLinewidth;a.wireframeLinecap=this.wireframeLinecap;a.wireframeLinejoin=this.wireframeLinejoin;a.vertexColors=this.vertexColors;a.skinning=this.skinning;a.morphTargets=this.morphTargets;a.morphNormals=this.morphNormals;return a}; THREE.MeshDepthMaterial=function(a){THREE.Material.call(this);this.type="MeshDepthMaterial";this.wireframe=this.morphTargets=!1;this.wireframeLinewidth=1;this.setValues(a)};THREE.MeshDepthMaterial.prototype=Object.create(THREE.Material.prototype);THREE.MeshDepthMaterial.prototype.constructor=THREE.MeshDepthMaterial; -THREE.MeshDepthMaterial.prototype.clone=function(){var a=new THREE.MeshDepthMaterial;THREE.Material.prototype.clone.call(this,a);a.wireframe=this.wireframe;a.wireframeLinewidth=this.wireframeLinewidth;return a};THREE.MeshNormalMaterial=function(a){THREE.Material.call(this,a);this.type="MeshNormalMaterial";this.shading=THREE.FlatShading;this.wireframe=!1;this.wireframeLinewidth=1;this.morphTargets=!1;this.setValues(a)};THREE.MeshNormalMaterial.prototype=Object.create(THREE.Material.prototype); -THREE.MeshNormalMaterial.prototype.constructor=THREE.MeshNormalMaterial;THREE.MeshNormalMaterial.prototype.clone=function(){var a=new THREE.MeshNormalMaterial;THREE.Material.prototype.clone.call(this,a);a.shading=this.shading;a.wireframe=this.wireframe;a.wireframeLinewidth=this.wireframeLinewidth;return a};THREE.MeshFaceMaterial=function(a){this.uuid=THREE.Math.generateUUID();this.type="MeshFaceMaterial";this.materials=a instanceof Array?a:[]}; +THREE.MeshDepthMaterial.prototype.clone=function(){var a=new THREE.MeshDepthMaterial;THREE.Material.prototype.clone.call(this,a);a.wireframe=this.wireframe;a.wireframeLinewidth=this.wireframeLinewidth;return a};THREE.MeshNormalMaterial=function(a){THREE.Material.call(this,a);this.type="MeshNormalMaterial";this.wireframe=!1;this.wireframeLinewidth=1;this.morphTargets=!1;this.setValues(a)};THREE.MeshNormalMaterial.prototype=Object.create(THREE.Material.prototype); +THREE.MeshNormalMaterial.prototype.constructor=THREE.MeshNormalMaterial;THREE.MeshNormalMaterial.prototype.clone=function(){var a=new THREE.MeshNormalMaterial;THREE.Material.prototype.clone.call(this,a);a.wireframe=this.wireframe;a.wireframeLinewidth=this.wireframeLinewidth;return a};THREE.MeshFaceMaterial=function(a){this.uuid=THREE.Math.generateUUID();this.type="MeshFaceMaterial";this.materials=a instanceof Array?a:[]}; THREE.MeshFaceMaterial.prototype={constructor:THREE.MeshFaceMaterial,toJSON:function(){for(var a={metadata:{version:4.2,type:"material",generator:"MaterialExporter"},uuid:this.uuid,type:this.type,materials:[]},b=0,c=this.materials.length;b dashSize ) {\n\t\tdiscard;\n\t}\n\tgl_FragColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment, -THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3},opacity:{type:"f",value:1}},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float mNear;\nuniform float mFar;\nuniform float opacity;", -THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {",THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\tfloat color = 1.0 - smoothstep( mNear, mFar, depth );\n\tgl_FragColor = vec4( vec3( color ), opacity );\n}"].join("\n")},normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.common, -THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvNormal = normalize( normalMatrix * normal );",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",THREE.ShaderChunk.logdepthbuf_fragment, -"}"].join("\n")},cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;", -THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},equirect:{uniforms:{tEquirect:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", -THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\nvec3 direction = normalize( vWorldPosition );\nvec2 sampleUV;\nsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\nsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\ngl_FragColor = texture2D( tEquirect, sampleUV );",THREE.ShaderChunk.logdepthbuf_fragment, -"}"].join("\n")},depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"vec4 pack_depth( const in float depth ) {\n\tconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );\n\tres -= res.xxyz * bit_mask;\n\treturn res;\n}\nvoid main() {", -THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );\n\t#else\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n\t#endif\n}"].join("\n")}}; +shininess:{type:"f",value:30},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_phong_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex, +THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex, +"\tvViewPosition = -mvPosition.xyz;",THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_phong_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["#define PHONG\nuniform vec3 diffuse;\nuniform float opacity;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment, +THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.lights_phong_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.bumpmap_pars_fragment,THREE.ShaderChunk.normalmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = vec4( vec3( 1.0 ), opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.alphamap_fragment, +THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.lights_phong_fragment,THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},particle_basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.particle,THREE.UniformsLib.shadowmap]),vertexShader:["uniform float size;\nuniform float scale;", +THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.color_vertex,"\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / length( mvPosition.xyz ) );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\tgl_Position = projectionMatrix * mvPosition;",THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex, +THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 psColor;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_particle_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = vec4( psColor, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_particle_fragment,THREE.ShaderChunk.alphatest_fragment, +THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},dashed:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,{scale:{type:"f",value:1},dashSize:{type:"f",value:1},totalSize:{type:"f",value:2}}]),vertexShader:["uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {", +THREE.ShaderChunk.color_vertex,"\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment, +"void main() {\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tgl_FragColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3},opacity:{type:"f",value:1}},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.morphtarget_vertex, +THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float mNear;\nuniform float mFar;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {",THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\tfloat color = 1.0 - smoothstep( mNear, mFar, depth );\n\tgl_FragColor = vec4( vec3( color ), opacity );\n}"].join("\n")}, +normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvNormal = normalize( normalMatrix * normal );",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment, +"void main() {\n\tgl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex, +"}"].join("\n"),fragmentShader:["uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},equirect:{uniforms:{tEquirect:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex, +"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\nvec3 direction = normalize( vWorldPosition );\nvec2 sampleUV;\nsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\nsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\ngl_FragColor = texture2D( tEquirect, sampleUV );", +THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment, +"vec4 pack_depth( const in float depth ) {\n\tconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );\n\tres -= res.xxyz * bit_mask;\n\treturn res;\n}\nvoid main() {",THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );\n\t#else\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n\t#endif\n}"].join("\n")}}; THREE.WebGLRenderer=function(a){function b(a){var b=a.geometry;a=a.material;var c=b.vertices.length;if(a.attributes){void 0===b.__webglCustomAttributesList&&(b.__webglCustomAttributesList=[]);for(var d in a.attributes){var e=a.attributes[d];if(!e.__webglInitialized||e.createUniqueBuffers){e.__webglInitialized=!0;var f=1;"v2"===e.type?f=2:"v3"===e.type?f=3:"v4"===e.type?f=4:"c"===e.type&&(f=3);e.size=f;e.array=new Float32Array(c*f);e.buffer=m.createBuffer();e.buffer.belongsToAttribute=d;e.needsUpdate= !0}b.__webglCustomAttributesList.push(e)}}}function c(a,b){return a.material instanceof THREE.MeshFaceMaterial?a.material.materials[b.materialIndex]:a.material}function d(a,b,c,d){c=c.attributes;var e=b.attributes;b=b.attributesKeys;for(var f=0,g=b.length;fY;Y++)pa=I[Y],Na[Ra]=pa.x,Na[Ra+1]=pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=H.x,Na[Ra+1]=H.y, -Na[Ra+2]=H.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER,v.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Na,D)}if(vb&&Hb){y=0;for(z=$.length;yY;Y++)ab=U[Y],Ab[kb]=ab.x,Ab[kb+1]=ab.y,kb+=2;0Y;Y++)oa=O[Y],lb[yb]=oa.x,lb[yb+1]=oa.y,yb+=2;0ya;ya++)gb[ya]=!B.autoScaleCubemaps||Rb||Ib?Ib?X.image[ya].image:X.image[ya]:E(X.image[ya],qc);var Yb=gb[0],Zb=THREE.Math.isPowerOfTwo(Yb.width)&&THREE.Math.isPowerOfTwo(Yb.height),Wa=I(X.format),tb=I(X.type);A(m.TEXTURE_CUBE_MAP,X,Zb);for(ya=0;6>ya;ya++)if(Rb)for(var hb,$b=gb[ya].mipmaps,Fb= -0,Sb=$b.length;Fb=Wb&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Wb);Mb+=1;return a}function w(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)}function y(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,I(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,I(b.wrapT)),m.texParameteri(a, -m.TEXTURE_MAG_FILTER,I(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,I(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,z(b.magFilter)),m.texParameteri(a, -m.TEXTURE_MIN_FILTER,z(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=da.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function G(a,b){m.bindRenderbuffer(m.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer? -(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_COMPONENT16,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_STENCIL,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a)):m.renderbufferStorage(m.RENDERBUFFER,m.RGBA4,b.width,b.height)}function F(a){a instanceof THREE.WebGLRenderTargetCube?(m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture), -m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function z(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function I(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT; -if(a===THREE.NearestFilter)return m.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return m.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return m.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return m.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return m.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return m.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return m.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return m.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return m.UNSIGNED_SHORT_5_5_5_1; -if(a===THREE.UnsignedShort565Type)return m.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return m.BYTE;if(a===THREE.ShortType)return m.SHORT;if(a===THREE.UnsignedShortType)return m.UNSIGNED_SHORT;if(a===THREE.IntType)return m.INT;if(a===THREE.UnsignedIntType)return m.UNSIGNED_INT;if(a===THREE.FloatType)return m.FLOAT;b=da.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return m.ALPHA;if(a===THREE.RGBFormat)return m.RGB;if(a===THREE.RGBAFormat)return m.RGBA; -if(a===THREE.LuminanceFormat)return m.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return m.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return m.FUNC_ADD;if(a===THREE.SubtractEquation)return m.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return m.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return m.ZERO;if(a===THREE.OneFactor)return m.ONE;if(a===THREE.SrcColorFactor)return m.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return m.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return m.SRC_ALPHA; -if(a===THREE.OneMinusSrcAlphaFactor)return m.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return m.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return m.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return m.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return m.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return m.SRC_ALPHA_SATURATE;b=da.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT; -if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=da.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b= -da.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var U=void 0!==a.canvas?a.canvas:document.createElement("canvas"),M=void 0!==a.context?a.context:null,H=1,L=void 0!==a.precision?a.precision:"highp",P=void 0!==a.alpha?a.alpha:!1,N=void 0!==a.depth?a.depth:!0,R=void 0!==a.stencil?a.stencil:!0,V=void 0!==a.antialias?a.antialias:!1,J=void 0!==a.premultipliedAlpha? -a.premultipliedAlpha:!0,oa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,ja=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ha=new THREE.Color(0),O=0,ca=[],ba={},qa=[],Ka=[],Qa=[],Xa=[],Ya=[];this.domElement=U;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput=!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront; -this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,Pa=[],ob=null,ab=null,ub=-1,ta="",vb=null,Mb=0,ib=0,bb=0,pb=U.width,qb=U.height,Xb=0,fc=0,cb=new THREE.Frustum,db=new THREE.Matrix4;new THREE.Matrix4;var wa=new THREE.Vector3,pa=new THREE.Vector3,Ob=!0,jc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0, -colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},m;try{var Yb={alpha:P,depth:N,stencil:R,antialias:V,premultipliedAlpha:J,preserveDrawingBuffer:oa};m=M||U.getContext("webgl",Yb)||U.getContext("experimental-webgl",Yb);if(null===m){if(null!==U.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context."; -}U.addEventListener("webglcontextlost",function(a){a.preventDefault();Zb();lc();ba={}},!1)}catch(rc){THREE.error("THREE.WebGLRenderer: "+rc)}var W=new THREE.WebGLState(m,I);void 0===m.getShaderPrecisionFormat&&(m.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var da=new THREE.WebGLExtensions(m);da.get("OES_texture_float");da.get("OES_texture_float_linear");da.get("OES_texture_half_float");da.get("OES_texture_half_float_linear");da.get("OES_standard_derivatives");ja&& -da.get("EXT_frag_depth");var rb=function(a,b,c,d){!0===J&&(a*=d,b*=d,c*=d);m.clearColor(a,b,c,d)},lc=function(){m.clearColor(0,0,0,1);m.clearDepth(1);m.clearStencil(0);m.enable(m.DEPTH_TEST);m.depthFunc(m.LEQUAL);m.frontFace(m.CCW);m.cullFace(m.BACK);m.enable(m.CULL_FACE);m.enable(m.BLEND);m.blendEquation(m.FUNC_ADD);m.blendFunc(m.SRC_ALPHA,m.ONE_MINUS_SRC_ALPHA);m.viewport(ib,bb,pb,qb);rb(ha.r,ha.g,ha.b,O)},Zb=function(){vb=ob=null;ta="";ub=-1;Ob=!0;W.reset()};lc();this.context=m;this.state=W;var Wb= -m.getParameter(m.MAX_TEXTURE_IMAGE_UNITS),sc=m.getParameter(m.MAX_VERTEX_TEXTURE_IMAGE_UNITS),tc=m.getParameter(m.MAX_TEXTURE_SIZE),qc=m.getParameter(m.MAX_CUBE_MAP_TEXTURE_SIZE),Vb=0Y;Y++)pa=I[Y],Na[Ra]=pa.x,Na[Ra+1]= +pa.y,Na[Ra+2]=pa.z,Ra+=3;else for(Y=0;3>Y;Y++)Na[Ra]=H.x,Na[Ra+1]=H.y,Na[Ra+2]=H.z,Ra+=3;m.bindBuffer(m.ARRAY_BUFFER,v.__webglNormalBuffer);m.bufferData(m.ARRAY_BUFFER,Na,D)}if(vb&&Hb){y=0;for(z=$.length;yY;Y++)ab=U[Y],Ab[kb]=ab.x,Ab[kb+1]=ab.y,kb+=2;0Y;Y++)oa=O[Y],lb[yb]=oa.x,lb[yb+1]=oa.y, +yb+=2;0ya;ya++)gb[ya]=!B.autoScaleCubemaps||Rb||Ib?Ib? +X.image[ya].image:X.image[ya]:E(X.image[ya],qc);var Yb=gb[0],Zb=THREE.Math.isPowerOfTwo(Yb.width)&&THREE.Math.isPowerOfTwo(Yb.height),Wa=I(X.format),tb=I(X.type);A(m.TEXTURE_CUBE_MAP,X,Zb);for(ya=0;6>ya;ya++)if(Rb)for(var hb,$b=gb[ya].mipmaps,Fb=0,Sb=$b.length;Fb=Wb&&THREE.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Wb);Mb+=1;return a}function w(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getNormalMatrix(a._modelViewMatrix)} +function y(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a,b,c){c?(m.texParameteri(a,m.TEXTURE_WRAP_S,I(b.wrapS)),m.texParameteri(a,m.TEXTURE_WRAP_T,I(b.wrapT)),m.texParameteri(a,m.TEXTURE_MAG_FILTER,I(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,I(b.minFilter))):(m.texParameteri(a,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE),m.texParameteri(a,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+ +b.sourceFile+" )"),m.texParameteri(a,m.TEXTURE_MAG_FILTER,z(b.magFilter)),m.texParameteri(a,m.TEXTURE_MIN_FILTER,z(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&THREE.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));(c=da.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);THREE.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a} +function G(a,b){m.bindRenderbuffer(m.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_COMPONENT16,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(m.renderbufferStorage(m.RENDERBUFFER,m.DEPTH_STENCIL,b.width,b.height),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a)):m.renderbufferStorage(m.RENDERBUFFER,m.RGBA4,b.width,b.height)}function F(a){a instanceof +THREE.WebGLRenderTargetCube?(m.bindTexture(m.TEXTURE_CUBE_MAP,a.__webglTexture),m.generateMipmap(m.TEXTURE_CUBE_MAP),m.bindTexture(m.TEXTURE_CUBE_MAP,null)):(m.bindTexture(m.TEXTURE_2D,a.__webglTexture),m.generateMipmap(m.TEXTURE_2D),m.bindTexture(m.TEXTURE_2D,null))}function z(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?m.NEAREST:m.LINEAR}function I(a){var b;if(a===THREE.RepeatWrapping)return m.REPEAT;if(a===THREE.ClampToEdgeWrapping)return m.CLAMP_TO_EDGE; +if(a===THREE.MirroredRepeatWrapping)return m.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return m.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return m.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return m.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return m.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return m.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return m.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return m.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return m.UNSIGNED_SHORT_4_4_4_4; +if(a===THREE.UnsignedShort5551Type)return m.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return m.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return m.BYTE;if(a===THREE.ShortType)return m.SHORT;if(a===THREE.UnsignedShortType)return m.UNSIGNED_SHORT;if(a===THREE.IntType)return m.INT;if(a===THREE.UnsignedIntType)return m.UNSIGNED_INT;if(a===THREE.FloatType)return m.FLOAT;b=da.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return m.ALPHA; +if(a===THREE.RGBFormat)return m.RGB;if(a===THREE.RGBAFormat)return m.RGBA;if(a===THREE.LuminanceFormat)return m.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return m.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return m.FUNC_ADD;if(a===THREE.SubtractEquation)return m.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return m.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return m.ZERO;if(a===THREE.OneFactor)return m.ONE;if(a===THREE.SrcColorFactor)return m.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return m.ONE_MINUS_SRC_COLOR; +if(a===THREE.SrcAlphaFactor)return m.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return m.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return m.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return m.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return m.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return m.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return m.SRC_ALPHA_SATURATE;b=da.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT; +if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=da.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; +if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=da.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var U=void 0!==a.canvas?a.canvas:document.createElement("canvas"),M=void 0!==a.context?a.context:null,H=1,L=void 0!==a.precision?a.precision:"highp",P=void 0!==a.alpha?a.alpha:!1,N=void 0!==a.depth?a.depth:!0,R=void 0!==a.stencil? +a.stencil:!0,V=void 0!==a.antialias?a.antialias:!1,J=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,oa=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,ja=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,ha=new THREE.Color(0),O=0,ca=[],ba={},qa=[],Ka=[],Qa=[],Xa=[],Ya=[];this.domElement=U;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.shadowMapEnabled=this.gammaOutput=this.gammaInput= +!1;this.shadowMapType=THREE.PCFShadowMap;this.shadowMapCullFace=THREE.CullFaceFront;this.shadowMapCascade=this.shadowMapDebug=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};var B=this,Pa=[],ob=null,ab=null,ub=-1,ta="",vb=null,Mb=0,ib=0,bb=0,pb=U.width,qb=U.height,Xb=0,fc=0,cb=new THREE.Frustum,db=new THREE.Matrix4;new THREE.Matrix4;var wa=new THREE.Vector3,pa=new THREE.Vector3, +Ob=!0,jc={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},m;try{var Yb={alpha:P,depth:N,stencil:R,antialias:V,premultipliedAlpha:J,preserveDrawingBuffer:oa};m=M||U.getContext("webgl",Yb)||U.getContext("experimental-webgl",Yb);if(null===m){if(null!==U.getContext("webgl"))throw"Error creating WebGL context with your selected attributes."; +throw"Error creating WebGL context.";}U.addEventListener("webglcontextlost",function(a){a.preventDefault();Zb();lc();ba={}},!1)}catch(rc){THREE.error("THREE.WebGLRenderer: "+rc)}var W=new THREE.WebGLState(m,I);void 0===m.getShaderPrecisionFormat&&(m.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});var da=new THREE.WebGLExtensions(m);da.get("OES_texture_float");da.get("OES_texture_float_linear");da.get("OES_texture_half_float");da.get("OES_texture_half_float_linear"); +da.get("OES_standard_derivatives");ja&&da.get("EXT_frag_depth");var rb=function(a,b,c,d){!0===J&&(a*=d,b*=d,c*=d);m.clearColor(a,b,c,d)},lc=function(){m.clearColor(0,0,0,1);m.clearDepth(1);m.clearStencil(0);m.enable(m.DEPTH_TEST);m.depthFunc(m.LEQUAL);m.frontFace(m.CCW);m.cullFace(m.BACK);m.enable(m.CULL_FACE);m.enable(m.BLEND);m.blendEquation(m.FUNC_ADD);m.blendFunc(m.SRC_ALPHA,m.ONE_MINUS_SRC_ALPHA);m.viewport(ib,bb,pb,qb);rb(ha.r,ha.g,ha.b,O)},Zb=function(){vb=ob=null;ta="";ub=-1;Ob=!0;W.reset()}; +lc();this.context=m;this.state=W;var Wb=m.getParameter(m.MAX_TEXTURE_IMAGE_UNITS),sc=m.getParameter(m.MAX_VERTEX_TEXTURE_IMAGE_UNITS),tc=m.getParameter(m.MAX_TEXTURE_SIZE),qc=m.getParameter(m.MAX_CUBE_MAP_TEXTURE_SIZE),Vb=0h.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),n.length=h.length);h=0;for(l=n.length;hd.numSupportedMorphTargets? -(k.sort(g),k.length=d.numSupportedMorphTargets):k.length>d.numSupportedMorphNormals?k.sort(g):0===k.length&&k.push([0,0]);for(var h=0,p=d.numSupportedMorphTargets;hf;f++){a.__webglFramebuffer[f]= -m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,h,g.__webglTexture,0);G(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer: -m.createRenderbuffer(),m.bindTexture(m.TEXTURE_2D,a.__webglTexture),A(m.TEXTURE_2D,a,c),m.texImage2D(m.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=m.TEXTURE_2D,m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&m.framebufferRenderbuffer(m.FRAMEBUFFER, -m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):G(a.__webglRenderbuffer,a),c&&m.generateMipmap(m.TEXTURE_2D);b?m.bindTexture(m.TEXTURE_CUBE_MAP,null):m.bindTexture(m.TEXTURE_2D,null);m.bindRenderbuffer(m.RENDERBUFFER,null);m.bindFramebuffer(m.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=pb,a=qb,d=ib,e=bb);b!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,b),m.viewport(d,e,c,a),ab=b);Xb=c;fc=a};this.readRenderTargetPixels= -function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;a.__webglFramebuffer!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),g=!0);m.checkFramebufferStatus(m.FRAMEBUFFER)=== -m.FRAMEBUFFER_COMPLETE?m.readPixels(b,c,d,e,m.RGBA,m.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&m.bindFramebuffer(m.FRAMEBUFFER,ab)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; -this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; +a.positionArray,m.DYNAMIC_DRAW),W.enableAttribute(b.attributes.position),m.vertexAttribPointer(b.attributes.position,3,m.FLOAT,!1,0,0));if(a.hasNormals){m.bindBuffer(m.ARRAY_BUFFER,a.__webglNormalBuffer);if(!1===c instanceof THREE.MeshPhongMaterial&&c.shading===THREE.FlatShading){var d,e,f,g,h,k,n,l,p,q,r,s=3*a.count;for(r=0;rh.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."), +n.length=h.length);h=0;for(l=n.length;hd.numSupportedMorphTargets?(k.sort(g),k.length=d.numSupportedMorphTargets):k.length>d.numSupportedMorphNormals?k.sort(g):0===k.length&&k.push([0,0]);for(var h=0,p=d.numSupportedMorphTargets;hf;f++){a.__webglFramebuffer[f]=m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0, +h,g.__webglTexture,0);G(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:m.createRenderbuffer(),m.bindTexture(m.TEXTURE_2D,a.__webglTexture),A(m.TEXTURE_2D,a,c),m.texImage2D(m.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=m.TEXTURE_2D,m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,d,a.__webglTexture, +0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):G(a.__webglRenderbuffer,a),c&&m.generateMipmap(m.TEXTURE_2D);b?m.bindTexture(m.TEXTURE_CUBE_MAP,null):m.bindTexture(m.TEXTURE_2D,null);m.bindRenderbuffer(m.RENDERBUFFER,null);m.bindFramebuffer(m.FRAMEBUFFER,null)}a? +(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=pb,a=qb,d=ib,e=bb);b!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,b),m.viewport(d,e,c,a),ab=b);Xb=c;fc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); +else{var g=!1;a.__webglFramebuffer!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),g=!0);m.checkFramebufferStatus(m.FRAMEBUFFER)===m.FRAMEBUFFER_COMPLETE?m.readPixels(b,c,d,e,m.RGBA,m.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&m.bindFramebuffer(m.FRAMEBUFFER,ab)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}; +this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){this.width=a;this.height=b},clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps; @@ -579,12 +580,12 @@ THREE.WebGLProgram=function(){var a=0;return function(b,c,d,e){var f=b.context,g if(e.envMap){switch(d.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:t="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:t="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:t="ENVMAP_TYPE_SPHERE"}switch(d.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:s="ENVMAP_MODE_REFRACTION"}switch(d.combine){case THREE.MultiplyOperation:r="ENVMAP_BLENDING_MULTIPLY"; break;case THREE.MixOperation:r="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:r="ENVMAP_BLENDING_ADD"}}var u=0 Date: Mon, 2 Mar 2015 20:11:48 +0100 Subject: [PATCH 234/333] ColorCorrectionShader: Clean up. --- examples/js/shaders/ColorCorrectionShader.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/js/shaders/ColorCorrectionShader.js b/examples/js/shaders/ColorCorrectionShader.js index 1b9fc759b2b629..5d5253df2e7732 100644 --- a/examples/js/shaders/ColorCorrectionShader.js +++ b/examples/js/shaders/ColorCorrectionShader.js @@ -1,7 +1,6 @@ /** * @author alteredq / http://alteredqualia.com/ * - * * Color correction */ @@ -12,7 +11,7 @@ THREE.ColorCorrectionShader = { "tDiffuse": { type: "t", value: null }, "powRGB": { type: "v3", value: new THREE.Vector3( 2, 2, 2 ) }, "mulRGB": { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }, - "addRGB": { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) } + "addRGB": { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) } }, @@ -35,14 +34,14 @@ THREE.ColorCorrectionShader = { "uniform sampler2D tDiffuse;", "uniform vec3 powRGB;", "uniform vec3 mulRGB;", - "uniform vec3 addRGB;", + "uniform vec3 addRGB;", "varying vec2 vUv;", "void main() {", "gl_FragColor = texture2D( tDiffuse, vUv );", - "gl_FragColor.rgb = mulRGB * pow( (gl_FragColor.rgb + addRGB), powRGB );", + "gl_FragColor.rgb = mulRGB * pow( ( gl_FragColor.rgb + addRGB ), powRGB );", "}" From ce09b694d8f6642bded8e11e43980a35c7e922dd Mon Sep 17 00:00:00 2001 From: rkusa Date: Mon, 23 Feb 2015 08:20:55 +0100 Subject: [PATCH 235/333] ObjectLoader: support absolute and data urls --- src/loaders/ObjectLoader.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 054af49d7d617e..ad5290be143f7e 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -311,8 +311,9 @@ THREE.ObjectLoader.prototype = { for ( var i = 0, l = json.length; i < l; i ++ ) { var image = json[ i ]; + var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url; - images[ image.uuid ] = loadImage( scope.texturePath + image.url ); + images[ image.uuid ] = loadImage( path ); } From 64fce03e7c48389f9a501635a7c468cec532587d Mon Sep 17 00:00:00 2001 From: Boris Smus Date: Tue, 3 Mar 2015 09:37:54 -0800 Subject: [PATCH 236/333] Update VREffect.js Fix for iOS, which doesn't have canvas.webkitRequestFullscreen. --- examples/js/effects/VREffect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/effects/VREffect.js b/examples/js/effects/VREffect.js index 8cfdce1c921997..324862850128fe 100644 --- a/examples/js/effects/VREffect.js +++ b/examples/js/effects/VREffect.js @@ -165,7 +165,7 @@ THREE.VREffect = function ( renderer, done ) { } if ( canvas.mozRequestFullScreen ) { canvas.mozRequestFullScreen( { vrDisplay: vrHMD } ); - } else { + } else if ( canvas.webkitRequestFullscreen ) { canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } ); } }; From 0ed4b40b1b73355d10f40daa82e08f2176007169 Mon Sep 17 00:00:00 2001 From: Boris Smus Date: Tue, 3 Mar 2015 09:37:57 -0800 Subject: [PATCH 237/333] Update VREffect.js Fix for iOS, which doesn't have canvas.webkitRequestFullscreen. --- examples/js/effects/VREffect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/effects/VREffect.js b/examples/js/effects/VREffect.js index 8cfdce1c921997..324862850128fe 100644 --- a/examples/js/effects/VREffect.js +++ b/examples/js/effects/VREffect.js @@ -165,7 +165,7 @@ THREE.VREffect = function ( renderer, done ) { } if ( canvas.mozRequestFullScreen ) { canvas.mozRequestFullScreen( { vrDisplay: vrHMD } ); - } else { + } else if ( canvas.webkitRequestFullscreen ) { canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } ); } }; From 3faa627256f2f3b6bd0d43b9f997c86884645f74 Mon Sep 17 00:00:00 2001 From: rkusa Date: Wed, 4 Mar 2015 09:56:10 +0100 Subject: [PATCH 238/333] fix blender export for mesh visible on multiple layers --- .../blender/addons/io_three/exporter/api/object.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/api/object.py b/utils/exporters/blender/addons/io_three/exporter/api/object.py index 6e6934b48f886c..ab7d40dcc609d8 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/object.py @@ -502,12 +502,15 @@ def _on_visible_layer(obj, visible_layers): :param visible_layers: """ - is_visible = True + is_visible = False for index, layer in enumerate(obj.layers): - if layer and index not in visible_layers: - logger.info('%s is on a hidden layer', obj.name) - is_visible = False + if layer and index in visible_layers: + is_visible = True break + + if not is_visible: + logger.info('%s is on a hidden layer', obj.name) + return is_visible From e2b015e11b17b01005f65ccde56c022cd6a045df Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Mar 2015 14:56:10 +0100 Subject: [PATCH 239/333] Editor: Improved VR support. --- editor/js/Editor.js | 3 +++ editor/js/Player.js | 1 - editor/js/libs/app.js | 44 +++++++++++++++++++++++++++++-------------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/editor/js/Editor.js b/editor/js/Editor.js index d5a45fa20601e9..34412e6561f3ad 100644 --- a/editor/js/Editor.js +++ b/editor/js/Editor.js @@ -470,6 +470,9 @@ Editor.prototype = { return { + project: { + vr: this.config.getKey( 'project/vr' ) + }, camera: this.camera.toJSON(), scene: this.scene.toJSON(), scripts: this.scripts diff --git a/editor/js/Player.js b/editor/js/Player.js index d5fdf308514923..3b8fe27fe35c85 100644 --- a/editor/js/Player.js +++ b/editor/js/Player.js @@ -27,7 +27,6 @@ var Player = function ( editor ) { container.setDisplay( '' ); - player.setVR( editor.config.getKey( 'project/vr' ) ); player.load( editor.toJSON() ); player.setSize( container.dom.clientWidth, container.dom.clientHeight ); player.play(); diff --git a/editor/js/libs/app.js b/editor/js/libs/app.js index 36b25ecb0a8acd..04ec67ca354e3d 100644 --- a/editor/js/libs/app.js +++ b/editor/js/libs/app.js @@ -22,12 +22,15 @@ var APP = { this.load = function ( json ) { + vr = json.project.vr; + renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setClearColor( 0x000000 ); renderer.setPixelRatio( window.devicePixelRatio ); + this.dom = renderer.domElement; - camera = loader.parse( json.camera ); - scene = loader.parse( json.scene ); + this.setScene( loader.parse( json.scene ) ); + this.setCamera( loader.parse( json.camera ) ); events = { keydown: [], @@ -72,10 +75,30 @@ var APP = { } - this.dom = renderer.domElement; + }; + + this.setCamera = function ( value ) { + + camera = value; + camera.aspect = this.width / this.height; + camera.updateProjectionMatrix(); + if ( vr === true ) { + if ( camera.parent === undefined ) { + + // camera needs to be in the scene so camera2 matrix updates + + scene.add( camera ); + + } + + var camera2 = camera.clone(); + camera.add( camera2 ); + + camera = camera2; + controls = new THREE.VRControls( camera ); renderer = new THREE.VREffect( renderer ); @@ -94,23 +117,16 @@ var APP = { renderer.setFullScreen( true ); } ); - } - }; - - this.setCamera = function ( value ) { - - camera = value; - camera.aspect = this.width / this.height; - camera.updateProjectionMatrix(); + } }; - this.setVR = function ( value ) { + this.setScene = function ( value ) { - vr = value; + scene = value; - }; + }, this.setSize = function ( width, height ) { From 8cb8e20452107b37086b66bce794b281c424ba6d Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Mar 2015 14:56:24 +0100 Subject: [PATCH 240/333] Minor clean up. --- .../shaders/ShaderChunk/bumpmap_pars_fragment.glsl | 8 ++++---- .../shaders/ShaderChunk/normalmap_pars_fragment.glsl | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl index 51a26a77428723..c901f0b0135cc5 100644 --- a/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl @@ -3,10 +3,10 @@ uniform sampler2D bumpMap; uniform float bumpScale; - // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen - // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html + // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen + // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html - // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) + // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) vec2 dHdxy_fwd() { @@ -37,4 +37,4 @@ } -#endif \ No newline at end of file +#endif diff --git a/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl index 1cb3b42fcd1c86..54b93eb59fb3d4 100644 --- a/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl @@ -3,8 +3,8 @@ uniform sampler2D normalMap; uniform vec2 normalScale; - // Per-Pixel Tangent Space Normal Mapping - // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html + // Per-Pixel Tangent Space Normal Mapping + // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { From 1b0ac10c96ab534f9a13ba9f269086fab36f967e Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Mar 2015 15:18:27 +0100 Subject: [PATCH 241/333] WebGLRenderer: Fixed MeshPhongMaterial+FlatShaded+Flip/DoubleSide. See #6117. --- .../shaders/ShaderChunk/lights_phong_fragment.glsl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 21486d256b3126..2ca32b93138b2d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -2,6 +2,12 @@ vec3 normal = normalize( vNormal ); + #ifdef DOUBLE_SIDED + + normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) ); + + #endif + #else vec3 fdx = dFdx( vViewPosition ); @@ -12,12 +18,6 @@ vec3 viewPosition = normalize( vViewPosition ); -#ifdef DOUBLE_SIDED - - normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) ); - -#endif - #ifdef USE_NORMALMAP normal = perturbNormal2Arb( -vViewPosition, normal ); From 120c8952b0bf9b87fd6d6ae4afb3606aecdd6f27 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Mar 2015 15:19:05 +0100 Subject: [PATCH 242/333] Updated builds. --- build/three.js | 9 +++++---- build/three.min.js | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/build/three.js b/build/three.js index 38603363eda016..122cd84739060b 100644 --- a/build/three.js +++ b/build/three.js @@ -12898,8 +12898,9 @@ THREE.ObjectLoader.prototype = { for ( var i = 0, l = json.length; i < l; i ++ ) { var image = json[ i ]; + var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url; - images[ image.uuid ] = loadImage( scope.texturePath + image.url ); + images[ image.uuid ] = loadImage( path ); } @@ -16583,7 +16584,7 @@ THREE.ShaderChunk[ 'lightmap_pars_vertex'] = "#ifdef USE_LIGHTMAP\n\n varying ve // File:src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_fragment'] = "#ifndef FLAT_SHADED\n\n vec3 normal = normalize( vNormal );\n\n#else\n\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n#endif\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n vec3 pointDiffuse = vec3( 0.0 );\n vec3 pointSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n vec3 spotDiffuse = vec3( 0.0 );\n vec3 spotSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n vec3 dirDiffuse = vec3( 0.0 );\n vec3 dirSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n vec3 hemiDiffuse = vec3( 0.0 );\n vec3 hemiSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n hemiDiffuse += diffuse * hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n totalDiffuse += dirDiffuse;\n totalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n totalDiffuse += hemiDiffuse;\n totalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n totalDiffuse += pointDiffuse;\n totalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n totalDiffuse += spotDiffuse;\n totalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif\n"; +THREE.ShaderChunk[ 'lights_phong_fragment'] = "#ifndef FLAT_SHADED\n\n vec3 normal = normalize( vNormal );\n\n #ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n #endif\n\n#else\n\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n vec3 pointDiffuse = vec3( 0.0 );\n vec3 pointSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n vec3 spotDiffuse = vec3( 0.0 );\n vec3 spotSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n vec3 dirDiffuse = vec3( 0.0 );\n vec3 dirSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n vec3 hemiDiffuse = vec3( 0.0 );\n vec3 hemiSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n hemiDiffuse += diffuse * hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n totalDiffuse += dirDiffuse;\n totalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n totalDiffuse += hemiDiffuse;\n totalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n totalDiffuse += pointDiffuse;\n totalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n totalDiffuse += spotDiffuse;\n totalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl @@ -16603,7 +16604,7 @@ THREE.ShaderChunk[ 'logdepthbuf_fragment'] = "#if defined(USE_LOGDEPTHBUF) && de // File:src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl -THREE.ShaderChunk[ 'normalmap_pars_fragment'] = "#ifdef USE_NORMALMAP\n\n uniform sampler2D normalMap;\n uniform vec2 normalScale;\n\n // Per-Pixel Tangent Space Normal Mapping\n // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html\n\n vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\n vec3 q0 = dFdx( eye_pos.xyz );\n vec3 q1 = dFdy( eye_pos.xyz );\n vec2 st0 = dFdx( vUv.st );\n vec2 st1 = dFdy( vUv.st );\n\n vec3 S = normalize( q0 * st1.t - q1 * st0.t );\n vec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n vec3 N = normalize( surf_norm );\n\n vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n mapN.xy = normalScale * mapN.xy;\n mat3 tsn = mat3( S, T, N );\n return normalize( tsn * mapN );\n\n }\n\n#endif\n"; +THREE.ShaderChunk[ 'normalmap_pars_fragment'] = "#ifdef USE_NORMALMAP\n\n uniform sampler2D normalMap;\n uniform vec2 normalScale;\n\n // Per-Pixel Tangent Space Normal Mapping\n // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html\n\n vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\n vec3 q0 = dFdx( eye_pos.xyz );\n vec3 q1 = dFdy( eye_pos.xyz );\n vec2 st0 = dFdx( vUv.st );\n vec2 st1 = dFdy( vUv.st );\n\n vec3 S = normalize( q0 * st1.t - q1 * st0.t );\n vec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n vec3 N = normalize( surf_norm );\n\n vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n mapN.xy = normalScale * mapN.xy;\n mat3 tsn = mat3( S, T, N );\n return normalize( tsn * mapN );\n\n }\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/lights_phong_pars_vertex.glsl @@ -16691,7 +16692,7 @@ THREE.ShaderChunk[ 'fog_fragment'] = "#ifdef USE_FOG\n\n #ifdef USE_LOGDEPTHBUF_ // File:src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl -THREE.ShaderChunk[ 'bumpmap_pars_fragment'] = "#ifdef USE_BUMPMAP\n\n uniform sampler2D bumpMap;\n uniform float bumpScale;\n\n // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen\n // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html\n\n // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)\n\n vec2 dHdxy_fwd() {\n\n vec2 dSTdx = dFdx( vUv );\n vec2 dSTdy = dFdy( vUv );\n\n float Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\n return vec2( dBx, dBy );\n\n }\n\n vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\n vec3 vSigmaX = dFdx( surf_pos );\n vec3 vSigmaY = dFdy( surf_pos );\n vec3 vN = surf_norm; // normalized\n\n vec3 R1 = cross( vSigmaY, vN );\n vec3 R2 = cross( vN, vSigmaX );\n\n float fDet = dot( vSigmaX, R1 );\n\n vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n return normalize( abs( fDet ) * surf_norm - vGrad );\n\n }\n\n#endif"; +THREE.ShaderChunk[ 'bumpmap_pars_fragment'] = "#ifdef USE_BUMPMAP\n\n uniform sampler2D bumpMap;\n uniform float bumpScale;\n\n // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen\n // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html\n\n // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)\n\n vec2 dHdxy_fwd() {\n\n vec2 dSTdx = dFdx( vUv );\n vec2 dSTdy = dFdy( vUv );\n\n float Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\n return vec2( dBx, dBy );\n\n }\n\n vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\n vec3 vSigmaX = dFdx( surf_pos );\n vec3 vSigmaY = dFdy( surf_pos );\n vec3 vN = surf_norm; // normalized\n\n vec3 R1 = cross( vSigmaY, vN );\n vec3 R2 = cross( vN, vSigmaX );\n\n float fDet = dot( vSigmaX, R1 );\n\n vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n return normalize( abs( fDet ) * surf_norm - vGrad );\n\n }\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl diff --git a/build/three.min.js b/build/three.min.js index 8526708eb4a103..0498bfdb998ccb 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -283,13 +283,13 @@ d=this.parseTextures(a.textures,d),d=this.parseMaterials(a.materials,d),e=this.p h.height,h.depth,h.widthSegments,h.heightSegments,h.depthSegments);break;case "CircleGeometry":g=new THREE.CircleGeometry(h.radius,h.segments);break;case "CylinderGeometry":g=new THREE.CylinderGeometry(h.radiusTop,h.radiusBottom,h.height,h.radialSegments,h.heightSegments,h.openEnded);break;case "SphereGeometry":g=new THREE.SphereGeometry(h.radius,h.widthSegments,h.heightSegments,h.phiStart,h.phiLength,h.thetaStart,h.thetaLength);break;case "IcosahedronGeometry":g=new THREE.IcosahedronGeometry(h.radius, h.detail);break;case "TorusGeometry":g=new THREE.TorusGeometry(h.radius,h.tube,h.radialSegments,h.tubularSegments,h.arc);break;case "TorusKnotGeometry":g=new THREE.TorusKnotGeometry(h.radius,h.tube,h.radialSegments,h.tubularSegments,h.p,h.q,h.heightScale);break;case "BufferGeometry":g=d.parse(h.data);break;case "Geometry":g=c.parse(h.data).geometry}g.uuid=h.uuid;void 0!==h.name&&(g.name=h.name);b[h.uuid]=g}return b},parseMaterials:function(a,b){var c={};if(void 0!==a)for(var d=function(a){void 0=== b[a]&&THREE.warn("THREE.ObjectLoader: Undefined texture",a);return b[a]},e=new THREE.MaterialLoader,f=0,g=a.length;f Date: Wed, 4 Mar 2015 17:11:16 +0100 Subject: [PATCH 243/333] Update ObjectLoader.js add Line.mode for deserialize THREE.Line objects --- src/loaders/ObjectLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 695662aabbc4d4..378d59fee41cd2 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -473,7 +473,7 @@ THREE.ObjectLoader.prototype = { case 'Line': - object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ) ); + object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode ); break; From 50dd930aa5f67d789cf8ff63a6fd7e56eedd4e1c Mon Sep 17 00:00:00 2001 From: bGute Date: Wed, 4 Mar 2015 17:18:33 +0100 Subject: [PATCH 244/333] Update Object3D.js add the Line.mode property for serializing THREE.Line objects maybe there is a better way to implement it, this is quick and dirty. --- src/core/Object3D.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 46f92db63ce1db..236a3d9585d931 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -698,6 +698,11 @@ THREE.Object3D.prototype = { data.geometry = parseGeometry( object.geometry ); data.material = parseMaterial( object.material ); + + if(object instanceof THREE.Line){ + + data.mode = object.mode; + } } else if ( object instanceof THREE.Sprite ) { From ba5e9779189b960c043c28d60cc507c201307b96 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 4 Mar 2015 17:31:53 +0100 Subject: [PATCH 245/333] Minor code clean up. --- src/core/Object3D.js | 7 ++----- src/objects/Line.js | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 236a3d9585d931..1709671a3ad847 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -698,11 +698,8 @@ THREE.Object3D.prototype = { data.geometry = parseGeometry( object.geometry ); data.material = parseMaterial( object.material ); - - if(object instanceof THREE.Line){ - - data.mode = object.mode; - } + + if ( object instanceof THREE.Line ) data.mode = object.mode; } else if ( object instanceof THREE.Sprite ) { diff --git a/src/objects/Line.js b/src/objects/Line.js index e622b31f45601c..dd3e792e954fa6 100644 --- a/src/objects/Line.js +++ b/src/objects/Line.js @@ -11,7 +11,7 @@ THREE.Line = function ( geometry, material, mode ) { this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } ); - this.mode = ( mode !== undefined ) ? mode : THREE.LineStrip; + this.mode = mode !== undefined ? mode : THREE.LineStrip; }; From e594a1a64afd72389fe1143701e52c744f41d68d Mon Sep 17 00:00:00 2001 From: repsac Date: Wed, 4 Mar 2015 08:50:56 -0800 Subject: [PATCH 246/333] Fixing a bug in emed geometry (which is currently removed from the export) which was breaking buffer geometry exports --- utils/exporters/blender/addons/io_three/exporter/geometry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index b446e436f3aad0..c2a8eeff87390d 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -335,7 +335,7 @@ def _scene_format(self): constants.METADATA: self.metadata }) else: - if self.options[constants.EMBED_GEOMETRY]: + if self.options.get(constants.EMBED_GEOMETRY): data[constants.DATA] = { constants.ATTRIBUTES: component_data } From 584ac47446b844d2e8e795a0c2b258e3c026167c Mon Sep 17 00:00:00 2001 From: repsac Date: Wed, 4 Mar 2015 09:17:00 -0800 Subject: [PATCH 247/333] Fixed a bug where the Blender API was reliant on the object and data node names being the same --- .../blender/addons/io_three/__init__.py | 2 +- .../addons/io_three/exporter/api/__init__.py | 12 +++++++ .../addons/io_three/exporter/object.py | 34 +++++++++++------- .../blend/scene_orthographic_camera.blend | Bin 485384 -> 485780 bytes .../blend/scene_perspective_camera.blend | Bin 479808 -> 483708 bytes .../tests/blend/scene_spot_light.blend | Bin 524040 -> 525516 bytes 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index cd364fd58abbb7..15b4129ed86e45 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -42,7 +42,7 @@ bl_info = { 'name': "Three.js Format", 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", - 'version': (1, 3, 0), + 'version': (1, 3, 1), 'blender': (2, 7, 3), 'location': "File > Export", 'description': "Export Three.js formatted JSON files.", diff --git a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py index a273c9d482eedc..c455561b1c8ab1 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/__init__.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/__init__.py @@ -23,6 +23,18 @@ def batch_mode(): return bpy.context.area is None +def data(node): + """ + + :param node: name of an object node + :returns: the data block of the node + + """ + try: + return bpy.data.objects[node].data + except KeyError: + pass + def init(): """Initializing the api module. Required first step before initializing the actual export process. diff --git a/utils/exporters/blender/addons/io_three/exporter/object.py b/utils/exporters/blender/addons/io_three/exporter/object.py index 1e313d38b742ce..a69c43fc7b31e5 100644 --- a/utils/exporters/blender/addons/io_three/exporter/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/object.py @@ -13,34 +13,44 @@ def __init__(self, node, parent=None, type=None): else: self._root_setup() + @property + def data(self): + """ + + :return: returns the data block of the node + + """ + return api.data(self.node) + + def _init_camera(self): """Initialize camera attributes""" logger.debug("Object()._init_camera()") - self[constants.FAR] = api.camera.far(self.node) - self[constants.NEAR] = api.camera.near(self.node) + self[constants.FAR] = api.camera.far(self.data) + self[constants.NEAR] = api.camera.near(self.data) if self[constants.TYPE] == constants.PERSPECTIVE_CAMERA: - self[constants.ASPECT] = api.camera.aspect(self.node) - self[constants.FOV] = api.camera.fov(self.node) + self[constants.ASPECT] = api.camera.aspect(self.data) + self[constants.FOV] = api.camera.fov(self.data) elif self[constants.TYPE] == constants.ORTHOGRAPHIC_CAMERA: - self[constants.LEFT] = api.camera.left(self.node) - self[constants.RIGHT] = api.camera.right(self.node) - self[constants.TOP] = api.camera.top(self.node) - self[constants.BOTTOM] = api.camera.bottom(self.node) + self[constants.LEFT] = api.camera.left(self.data) + self[constants.RIGHT] = api.camera.right(self.data) + self[constants.TOP] = api.camera.top(self.data) + self[constants.BOTTOM] = api.camera.bottom(self.data) #@TODO: need more light attributes. Some may have to come from # custom blender attributes. def _init_light(self): """Initialize light attributes""" logger.debug("Object()._init_light()") - self[constants.COLOR] = api.light.color(self.node) - self[constants.INTENSITY] = api.light.intensity(self.node) + self[constants.COLOR] = api.light.color(self.data) + self[constants.INTENSITY] = api.light.intensity(self.data) if self[constants.TYPE] != constants.DIRECTIONAL_LIGHT: - self[constants.DISTANCE] = api.light.distance(self.node) + self[constants.DISTANCE] = api.light.distance(self.data) if self[constants.TYPE] == constants.SPOT_LIGHT: - self[constants.ANGLE] = api.light.angle(self.node) + self[constants.ANGLE] = api.light.angle(self.data) def _init_mesh(self): """Initialize mesh attributes""" diff --git a/utils/exporters/blender/tests/blend/scene_orthographic_camera.blend b/utils/exporters/blender/tests/blend/scene_orthographic_camera.blend index 3e0bc12b353e760239d2ab129969cda54bc7b7d2..4791a0547601acf301ed6a0eaaee074139b1a4bf 100644 GIT binary patch literal 485780 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 literal 485384 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

    &VmVNs97xNS>s?%9HYA5PwH1&I^}8R z{tonw{?5!IiR7v-t; zM*Kv-8o#(xo@VavK%epdQl8#PUUc03&IEZ$`hj&4eXh8!mDk5ni+9uUj6|CQAKDc~PF~Z^lpbt31^Exn1M1s*%C&HoMpO=aj4M zThZleTXy66-=zL@Ld&z^S7KsD{6xRXL%pACwv3DpZ7hFZtD8>MYy7fuwSA{e@n^lt z-MKBC7etS%|IB44+g+_wo|G5mY5Z;YiGG#mY2^uLuRP=Qa>QFRv}ttk!qHXnpDn|a z9E5s}&$nkPd~oo1`0?A~mMr*D8Anu}lo#cx_ICV4zsf_K_H*Ov&6|VD^AZztukoi$ zWu@6Bof3|_n5Pe9&p$fjh{}`lqC5?}13%HP^3bOJT)*kO4O_zRn@qANrJ8z;f7Vo1 zn(f4G;XE_uDgXV4zN}nC6HV%%&kA+S8 z(QEvqS2RJv?IBO`r^50)HIID?SDus?<*D{}_=$d{@|tQtHw_JMT)m;2kuKHHYy7EG zT(7o2PR}Dx@w#vGW1{N?%8T+ea1DNo%o46ZQ0ySuj)1a%yPYbCw04C zZGW8pM;Pzoad&d_lVN_M>jlb-@-+S~{6xRXs&an{SI5K8FohR+-6SbgraVnGennhw zUwD<*<$9a<<24=fbZB!S=HvFp_k)!e<*D`_{6xRXL$#kE} zaZ7mJ5|6t)PwhVcqdX}u%2RzCexhGB*B|G#pUp4tR&{Z5&};m@czySF@}zy6%giJ7 zMAKAxQeKp&@%P~;`c+d%IjjBLIJ9>CdFuze>PxYLUgJ-h;(D9+qtp4*A`?MlZ+)p9JUt_v7sURQUssvv^D4@V@-*<*eEyey)m(p^*M7!NVGMQO zoqCQB=b2MlZ}Wb5*^MWoqhw?nt_hgi>bGwn5gNmy@R`QoLUwYHW$k38kq z3nu(r4|!3ZYFBXF(XZ+s|5=C6v7Q&cgf}vJQI}u$YkaQvT|n znJ7=I)()N5sB6pOhEn zN#B=L{szV;&eQsl&EcH9%?dg^mFKDJ_-+H*Y{wVEco+BgWnPx@G|$|aQGZfilqZ!? z{%W7^kf)}PiE&2-g-$qio~9VTFRmB-19{Sh&Mnd_mXs|$o2GGl$HT0?SNpGFKKj1X z_iLNS^D|CfmA=fGUfr!qHFo!JyRoIa8YV8S{nP$v{}iSD7H9j%+2F{O_ASQ&#=BPPTH&4b%gXPouR0?1-8MTA`@z=myzbj@ zXPA#|Gw_6T9|zsvA-|8S?q{m|JA@EFzKVEOgl7&qDBj^YwRXH;)WFlzeH?1z+=rd% z_+7m3^z$@zWy}n$NcV9V&+g-(INdLx-Y$OZish*q?&EOI$6GmHS;pF*^8M>`-WX!T zeH=7xdmo2e=N%UA+}-Yd+^p&nTk6jW#99t7TQn`mYaRH#_V)|Os_7cX|0dlhVB04y zZ@E9%-YSayX)GRhw1e73acZw{%fp>T@$zNq`GKWpfBXC!7rrUnH?Dl>etwDcuk!R; zJP|ow>;1!$<9*>m+{@lL5T{?f<(6>T(6=N&e9WF3F6Y%ko8;F()8h93#`g9hnfzAccNXM5-JeGHYwmR4ZQbAFj_{)9rQw8q&YU}nE6Yr#`_!y^8uwX#2iIAc z4*Y`mLI1nG-)bwl&oZ9VailmMN42)`zu>sp2luHdo)PK_e)BZlZ!xxNy5Hi|?o$)* zff@6aKjM999v||jzL?*qX8dvY%yBeca2#>J<$Sw3vD!uLpmtGtwO8V|gk0Woqn3qV zP7b`Q5n)~tU zP)GiVH9eu}$;i!*+C9}SZ%*S*?JeEkr{*c46OD7ceJX6M`c(6F=kslLJufmX`Ovqg z`z&d?ZXNgS90?aq*KFCaxr^(jF;De#e_Gx@DE9Ao?x_0ag@tkXXTwG2_*d)SUY-xc za+^Qc;JKktTpl0s98|wob4cKLbc^GAY0dnwl0rSV|HAh>kIU;@8^?WF{=?sGSzh~i z#vg3_ZcZ8hist%4{a0o6ZEKCMe>&YaDSn2!dHWs}?sFRVU)%TSa(Oey(#;(AzM1D_ zobLJCsBd1je166YGOlI(fQ%2w_<<9f!IXMAPG+cLg3NGuVlO{9Eineo`ncx+}oHZvZZ z8IR43$7aT3Gvl$D@z~6GY{oZc#$z+%v6=DM%y?{OJT@~Pn;DPIjK^liV>9Eineo`n zcx+}oHZvZZ8IR43$7XzEW;`}C9-A4D&5Xxp#$z+%v6=DM%y?{OJT@~Pn;DPIjK^li zV>9Eineo`ncx*l@>;Fe*d`!kq&G=~K&;mjW?p}od3_Q&zQ(Nadc(_kJ!8HpT@N?&`=n-m$JEU4 zn3`|N;=h>jms+{b>m$d%?#JcpE3saG*{=&Tznbx@8NZtGs~NwV@v9lXn(?a{znbx@ z8NZtGs~NwV@v9lXn(?a{znbx@8NZtGs~NwV@v9lXn(?a{znbx@8NZtGs~NwV@v9lX zn(?a{znbx@8NZtGs~NwV@v9lXn(?a{znbx@8NZtGs~NwV@v9lXn(?a{znbx@8NZtG zs~NwV@v9lXn(?a{znbx@8NZtGs~NwV@v9lXn(?a{znbx@8NZtGs~NwVi{#sl{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xLtKznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7l zznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O| z@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh z8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@yq7SFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{BmLD z7c+h_;}h?U`T9_{EH0%=pEOU(EQ$j9<+7 z#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEO zU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff z_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EPr zXXY0(elg=0Gk!7S7c+h_;}FJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6D$^2r*FJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y7KGQXJdiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnE ziy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7l zznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O| z@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDNW)nP1HK#f)Ff_{EH0%=pEOU(EQ$j9<+7 z#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEO zU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff z_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=qQb%r9pA zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y6K{9?v0X8dwj<`*-5G2<6Aelg=0Gk!7S7c+h_;}OM{bN8l3#n;N+JEC%-f}`K7_h zFAYw9X>jsOgOgtxocz+@npr_BPYrX4>0Kdz)!*Gwp4rz0I_@nf5l*-e%g{OnaMYZ!_&} zroGLyx0&`f)81y<+e~|#X>T*_ZKl1=w6~e|Hq+i_+S^Qfn`v(|*S-kTqr zEq`3bhiCkI88hCyKE``9j-pqJ!X1q5u-kTZk&5ZYE#(Oj4y_xae%y@5Ryf-u6 zn;GxTjQ3{7do$y`nepDtcyDIBH#6Rw8Sl-E_h!a>bAQ%ejQ3u?G+VwbKW2^}GslmaKW2^}GslmaRW_!K&G@+)pO*3SGCn=y6&bJ0_>7Ft%=oN~ z&(8Sy8NVRoKhF41GJavkFUojT#^+?rc<|wDJTNmJm>Cbuj0a}M12f}+neo8PcwlBc zFf$&Q84t{i2WG|tGvk4o@xaV@U}iipGai^356p}QX2t_ECbuj0a}M12f}+neo8PcwlBcFf$&Q84t{i2WG|t zGvk4o@xaV@U}iipGai^356p}QX2t_ECbuj0a}M12f}+neo8PcwlBcFf$&Q84t{i2WG|tGvk4o@xaV@U}iip zGai^356p}QX2t_E0+fGqZhWw$IG=nb|%w+h=C`%xs^T?K87| zpUt+<%=VetJ~P{AX8X)+pPB75vwdc^&&>9HF55mc+h=C`%xs^T?K87|X134F_L9j**-JdXJ-4%Y@eC!GqZhWw(pDC_Lgne8*PeP*`L z%=VetzAt6lXJ-4%Y@eC!GqZhWw$IG=nb|%w+hk8w6B@=HPgOk+Sg3`n$zovMt;)k3GwnJE0=67ilVkK zyG@+<{;cdDhptG|ZA{nkyvoPvSLYSQ8DaX;Iiapux6XUQob-*1 zx#78m&p5YyAG-F&)ZYfK+Wyk`zV!Gn?<(sb|4o|4dYT{gGrst;SZ-itn#S!O3)L#_ z-$UWJmiqs+i68s3<*BZ(EGehwe7u#@!jAvO{fUo<$A8XwV~8DJ;%PCqxG4XMVs+-Wm&<%FyefTe zY_fH#UDOV0mw{i?zO-|y@6pSO;$t^8>JHrhpqnFK8vd?k!R_q)Rq$^y6+czU;dv&Z zU5fr!E{OeNLGh5Hm^(kz__W#aueD$&iuIoqI#uk)`6JeHL@}?>qN|GsF&lef=!Z{e z-!8SQ)A3V(-2r94-}aNWrfL0m zgavU+2ezi|QMvjlca_^EKJ!^8oOR6dRi~|7H99o3VPw_NxqmviW_07w+Ci0=c-m|H z!1|HVq2Y^)xblhD)PCth!_$}kX7}#D4AYBTBy@`KILO?XQJ$0+<*EL6DNo8@BO=Y^ z`+4s0mXURNp$WLx_@!O0uid76D&*<1u;7WQ3%kf%&oyS0C*?(X8owsxN%?C;q`9{H zS@x~GWP9#4er4!L?Q5R=v(F|^#}lIb%x_bL@}#^dPqla90s2)Q+I~MrMu&%9JgFnE z*Z38aUQ@p14SqLy(lg3aI{Nf%nkrAqi}Ez^?vy9xuQjSD+VAI@EyEW~Dos7dFPrq5 z@-1)hUvZ0n9Y^b7aky4Vy<-4RzPRy~gj0{`9a8d3r#;vw@W- zm?zC_&GY9C2rm6CzyeLoO zAH+}etEP~0wy~e-e0<~J$hyI`>nA6tP(!crr-b$O#gnKW6!otEm;AI`FP_-Rb}!46 zC*?(Xs(lzg(XS?(r^z0Fo$@r<_%csD9(+Igb;{GI^ZwAZpOfkm zy~g+0mCD_D2gluiWIOkuj3X*f%8T+;dqcWzq5S2c`F;+sKY#t&bBES;@A2ffZsSjn z>+4$@Ryg%ObxY_^y7mH3qR_CC$?)NT9; zU5u^mwkGE3(d6l57f4qMvdb*x(wL{y!kn%L{!5r|SFXn)xa_xMp<-Q^)pgq1|EBA- zx_+BBxo=rfY`!tg7sUaW^)36IN4?;t$j#SjzexdIm(8!!YPsrR+V(o_u5hh(S5~kS z#`O(_zZ2UeD%SG*#r)#21UG6;g$EY4zfL>;5ynlXoz~sy`TAd^>$BV5dwF?%wo|$M zc^xNOe}0^(eEs*Al-G^Ljefpi^+;YV7N@Kp zd2!$J)uXHTy4sckH;3b7Yk1~xKl=pFsN->o z$1c6;o#Dxkvf%5SSX~3F|BAJ|QBOHn_TK}-wlv;n_-OHsIqwXAS;;mS-}{MwvH!Mv zpJ7&c^v?}rQ0lL-iZqx09e;fL{@Z3%_sUah7qx@hMJrc(iKp{)qIS7;-h<{mv1#KY zt7YQTwR@;t20od5Qv1Z@yizZ|U%syz+vUQrh2rbNHpU*bd-nqu#qDi=+Ns*T?rgzjwuvi_duZH9KnWenLDBiepZE=Hl=F`szhjtbAlxUKH0K zd(_@tS$RSn|3beI#seQC$AVpTFTjBRiM;%WGa+ZvXDx zmxS%y_V-2cm5;>bMX~d!-;~c4|B(3hqr&u-<0{kHpGs7I6Zgy zQ~oXGKgNYeJx-5qq4Xj*zAwL|(mNfACzvVHzx<=-AvwS6Mizb549Wo_~l zYl=M~wnKa*PV@2K`qQW9`Gnd*?K1Ga)Gp(+SK5Qk%ZiBYJZ-ld)b72wphoD z+ClA7yDhbg+AFQ_V;mm?;W&?v|DU}t0g$Vz(th1pC=dh`HAF^RaGco6l7uBHB%KW! z4U0+C$YN97U7aq|-PKc7opczL7PrzL1za#eg%%Veiod%-5yGPMXmoVO8KN>XK^cc} z#$RR}os0|hf8V|LtGD#4uBxsiH1J;ctGk|a?>*<-bI-l^z5AkJ8(Z!7e%Qyn%)qyI zCvdG=;mM8dFB5YXdAw_1lnM5ig&=&KTv#l=_06#Q4zYKh5zm*}B_Eg^;*0nozNj?u z%ZB^WKh6&H7w~1*IVSuy(0l^-Gm!BVCzRsD(GD5I!E}{jUFxv0W!%G-9-9k{3ujHt zdA@`^3=j&5FN{?A!3@MSW%#t2$CrLoSmXP*;19}?>;UOA@ed?6SL%^>gw_#C*?$f_ zr{%I$oPDR*=fPTF;nPN;T_Dc1VgGne?#~To zPR{h6yd{_4baFm3oGYAM?9XR1+1$y+OrcmfxtoQbynjkdup|^nDDXt0K%plylTIJ28gqsv|E&iA~1@Tc7S zZx6xGaX<{ z37-$V&Df`cQ$E2x;^2f&a69LQ;gnBs^ImW1Bz!)c^{G7N6I`c*6F$Lt-kb4uPK&V* z+YqUIf*W;k!Y8<$bHi}TC%7FBPWS}pd3{DKR8Qp-+#Uxfe1dz&oG_g72`=U2Ncem> z>r;8kC%7dJPWS}3b8fgi(aQ zmmIwCs@$kN310aHzth1Buga|kul$04#K8-%;76;}U-<<;?-JKf9Uj3&fy>T~ek0ivP+l_z4FuylQ`c zmG&#Y;P*Lr;Z?m=k0||=U+@bw9y>hZ`?f0OE5G13IC$Yzxz*s6U+^UdFTC@d+)q>~ zU-<McvbH>_;F;Oh`c{rdU4o(QT?R{tLZbAyAwvuTV{D4ErCN0 zxqYrZk%xP=Otn}4KmW7Y*OgoHY=7x&4eM>?kGhn*F(`V$X`L_@e(dvDbLHjsJK7rC z?_hg)nf(s$QQ*RUN5!@4giQC}pS>Ns6uj%ZM6VBnUeU{9@!y}VA8QoT!3m2m;)D32 z(#0wBb&D;Ac$0x5Nhqb;j_o9_CxR8l)ytIBh6iK(K`n7y%MGzZqv*2PM zYV43!U}0Rn7iHL5v|$K;2dWWlVH^iDM81rpK=tcK;3r)>+igEr|JV2y9WONg0K{DH z#KNxnMFxmw&t42m&T=Z)&r|o<{#fM37bdCvU^Zf!DjZA;`cq$Wa=xoRIS;}%<0oItd-AUQhk=X@==}23^;q$m z_3JMY zt5&Zinet}ODVkm@+%){ON)6ZQU5-wA|68dcL3fd&ljtHkO?=hTN%RvAxqdqb(p#}Q zuK0T0X5rUNtJHAqa-frR5mRQn zqnV}%Hw(WmJvcm&>1{jDl#ZSGhDx^;d%2?%L!^`FgCTy>B|3>NqSM4ToPKh06$SL$ zS?EvqHY7?0RkQHxrd4XV6~_nY#1zpfZcjmU5?w^6)Hj`ea&i?eAt+DSlv#8VT|}qOJDq-VauotXAkfYn-d`Ec=Xx@Q22@nD z@E4-gwhJ3AHQb8-!h3_VwV5J$3T($!07NIzMRY3N<@A%2s|tYg`0Xqdp(>)uHN(xq zubWn>;cERPK&PO7Iy9WkghVINMRb~Q^8(Q?3hK8rH&PrPY0w%E%H#ClFPK)T;Z`hg zbhILw;qM8cD)P6i@)CWptq)lw?kCJ zA%5~OZXMEMnO&K?)r+T0v_rIOp7zT*iT=2FtXV%`~<| z(JVYnwdoWaY7XBwrYyZM6dNCq{7POWzsfDSHsM`YLl<0kkJ3K>{x7b&@BVKa`8@+V zuoE|*o0t5a?)0MMcgJiCY2{b@W4}M!^LSH!cP%>%lN8GDQ5c%$dY_)XriHgktnRYC z)GO8GH;N@1u8#TfNg-c4QMAU3-SF2zhRPn;Va``g-Q z)_#2|vS0m8@Rs{N8&OHVpLOV=e{6YntF3Wx986t&iFvb4}%Q)u}8$!?m8mZFpBB0331^ix=_+S!*K z>Q!7LZnN-bPqW-$9p8X;Fw*J6!ASVyBwYPm{aXE8pz8l7JoXi45_u@46-T&BP|AIN={nEeH`Z@6gA*117+D!11FFT;$G_Kx{ zN`)FwrILqMi4R6U-vxB;9P!S^T@U^sp2VL}0B0h^5`pqNjuhFSvPbp4gzVJl^NO-d zWv2@H3n84}fRM@_ZE4vyE6yG*eZYRNLvHFBc6?49Ti-Y>eJD8T!-;3c!0+le`mgf5 zq1P7)tM>7(o&z-YXvY{}VUNmajRs*iMKZ<(gM1-xqL-Z~@O-{HCLK}W$001f zh!5h6^q}}PQo-ykiu1#Zb-K{lImr`*UAHAx@Rg13=ej4=;ARb%x z!~8dw2O^C3nloNKDXv`p-+QC^K!%uhPR^CY95@QBf9{r!DE4~eEdRnh{LpECQ{nxq z{&8)jAB-ani}r!*4}YkB?pz?-Bro;kXbaZ4oIS5|=O$&0L;&Q;b?#j18nkF;oI5v; znrQx}`5dCmrFowA*XKpvgVQ`u`RVeV0L|xS%{n1|f8l;--#d3=z73a-vu+SyoL}Ru z;56RG!jJ8P-NQ@om0TMR+r+BBY!5H{UdhJ+%lAs08#|vn0ecI)>$^m+xcQvL;?L*m z$68<6`#YETB0h*ODo6aX;p;%l|Gvlik6MmBON4)WFT;GNWEF1C*R&rXKFB_0nCWrr zj?!`0&$93Jp|4@yZ~|5fPiXli;Oe=EznUFHOhFvca4>Bq_{o=3P~(*AZ{I|vLJg== zNs#YJaZS8&>hsE`YGja3q$BpcJ>i>!M5aI8-Kl@M*PM&Se0ve6@N8sa9(%QTI!EN0 zh~OMlVLp!-3_r_+fG2S72-EfbT;enN-S_P);jcev-p{RsKkL5_Y~bDZsg+Jwm%(>~ ze}0__2hMFZ@Zb80!T&4(nRHjb%6TvDe3yqzI_mGfFRpW7RF>RzYuyv)_%KAzrpBM= zCLZ!3dOhOaPjHhl3M7AI|zzp7IH9kAo9F!9~w| zQ9i+S?zMCgKEXxLdr>~YjXF5t6Wq6**{XUfpWt>lIN|f*-fUE#;FM2rdmNnb2@Y1V z@d{4)1ebF1Cwzk2IX4Wae1coz;Dk?bIKa1+ewC+ug6ns1!Y8<$bHi}TCph&N;S=0p zv%+x7CphI3K7|jP6+Z7}!qw~N$iV)v&xMtLUKP1xI~N4<3x2`R!u?zDQ8^O4@(X^0 zgI7Hy?@@UYyz&daU!@&!$=wA(9`31kn!3(eW z7L|XMul#~fx$#7J)$VHW$}jjO4qkXw?`rVMFZg~3FT8^9kMt|mU-<>U&A|(=%B=>k z{DPlw@WLzlZ>v(i@(X^SgBM=WzZ$&q3ts(0cvbH>_;F;`xUczc>ZI`aulmo6=pofh z<s2-$>j%8dc`184@Rg9|$$2S;BKz%!d>IEe^=tL>3D?gn{ol&~@wZs|9+e|P@2v3@Q%$x|%+-uF9sa_d?% z@LVL)$E=&t6S$tR=OQ^iiZ5!C_~m&WyD%E8wDFxQHvDAcJqteY-bz^cgRbOC>skzR zUCSy7uG8bY1#fzPCtdrEk~Z_qIkL3Q#wKYBXH~5TBCO#jey&YYj-yu;Q#2gS|9FSl z&-bDd>UVd;Z+qp`H9KYsK4{!gSm{0<8cuz1&Z z5kGPNznJV6i~pU}da-s+SUSj!L481?$QQn^p>iKaDfNiw$~EU+$oDm-_mx!7YZm?j zytQaP%sMoEvh2b88sh-xK1i)g@+*0j{H7kWe3M*TJe1d??)7mZ+%f+?hJ*6E$Msmr zYgB&w<9l?h{AOG0(*Va}Y^1)Y{Ko4Q>JdJ#X0Q6NV&DC*T|fSgbshKtcO<_mU-COq zqaKpKjl-Ftp6o!w^=uaYoO~u-$h2KJz0z%UA93=_Q1JYZxWMh?pNh>N#xaf{?`r*= zd!57?PX$EJuuFUqAH)~g>*ANK_T|vOZFl2d9v^O`abw7g8}n9tqxK3xX60$n9Y=oN zQ}czdPRB_nqG#A8zK9Rvi>fJp+3*%@Swn z#=oDpbxyXGcTLoWC-bHl7o%9B;o2n}+#KY~Hi(esw?9Df^+*)Qk;&KCvN+g!?d8e% z8i}!*sv5-6Y#6TidfT*_@LNk|lV9VgsMbBS4x;Bdv_2Bu57Iu4)u^NaOitzGVc$|1chK8P=+ zl;w-~Y|7{P2;Ta8{JOxdapB;6d`)d=VeSm(Ig1U&Jp{Q^Oa#?qO?AzEocaiMCFBp{)^f#qx#k zqt&C=>*EU)P=kC)?Y4Hd+?aYFkSOwn>mVxk;W}%s`OV|C4sw2GOWV30d`vHtp_ee6g4~zqeQYm<4fgUGYVH5MNXa@k?Rf9V=s= ze+6#m`YF|XCpkXF>F=2NJODg?crtS_q#R#7V~?#vGe=GFt_Jj-z9p*&F?K1 ze|}#-*80lc-?_vW@j-kkJ=^j{{4(Xv;Q77iQf<6^!p`pCqsPv1i*VOy>oX2baPFHrL;u%&t=AX!cyZZh;l)zzi&+mcE zlvj-}7Lz}}ZwxcBAKXiP5g)`C)k6J7Vc*rfUap@~&3BCx)%xf6*R(4cf*{U&D%h#r}7C- z{YCf$w{z~zt@H~{`2?qY!l&?Utv>%2AacUh>*w&Z-TPcv`6Z`OxnsG6SAM}ScqH7v z1s|0o!7IPuH#m6VRk`yVpH(lxE5G1N4qkXwZZ&x27yM2KFT8?_%B9Lze!)ND;DuNH zZnR4Mm0$4l{>}AQwZrxMsGO>Nz1@OvD*@T%U?exvp)zu;59wDc2Rm0Jy7`31kk!3(eIza-KxRKD^HzTd$Mujp3| zUik&T&A|)rJV*CvKUVq5FZc-uFT9e!YVgW0_%WpCrIUZ-2*~cy z{>y~3gOpG7lO8QOe3A?0qsx8XSIzQp;=Sh`a>(s-&v$e2;PaLJWB+E}GnJcqfm;VY z-nv12aemf&3>4F3=Lj-Ug1-bbepPQ`y2_46MUCu7F_fG@2TF7 zxmBLW6kx@b9P{j#=yiJpOEetK|9FSh&(*Kh&r6Hk`{b^_OFu;Qt@O9raU&irC4G3^ zMB>h#-(oGu@Oc@XcmKw|Pww2(3*CC-iyG_af|ERT#=_sd($+}(sydfJVVhd*_gL4- z%s%VbjlhL{R=Jb*Sr3Oi&BqzAylY>g*SkS0(kpsdEdFXteORMd4qjOOTzn8;R0HwL zhOYuG&%94*?@e8`^4hI0G2uf&^ZAbMB}bQ6xUl+pDv~Zd&Rqt#<4VY*|33NrmUp)v ziaU}sCMdozN#zH#5z|!RU|P_h`k|YD{F8NqX$R6zzL@8AUHK2AFp{tHZ>O%uir1`P zf5G|d`08>`Zm5_UEjCumX5m*(r_e|hAH@5N^U&BAM&jdwqLb(%I+gy;(nCauUvI=k;cP*wICFn)s2Wljs+P^V^BnVl(;1 zKHdvt&BCvlR;l4uQZ)bX_m`x94 z(}ji(5pEWKIZ8codBeqqnz7c=>E(z$CXgbz3Pe@tB)W)Br9DnRIr;@*==a+>m@7h< zy1EBO8c|Zs!mmpY4i98{+uUi-D;g`^w&vxIP7IMwq7UC@ieBn>qKoJ>@nff-oLoiW z{B{=l)4dIel0nrh{JLqC8g9k$0Xi{7baG~SD6{A!x`DI{CZNetywObP=68A9VW3$(0XbeSvo73Ppakz9&;? zKt(kRe<4b3!^e6XD>dAT|N4{F=tM!uror3!5&~P>r5}iaB(P_fX3q-#tsNc@qNO5?iL2EqNZ>I-;!L&*Z zw_<^#)AiwKyq_@n5}iaB(MdT)KZWJ`bm~rTYD6(P1kJ*)m{zH(y>*WY$P;7K@17RU zWZC6Y`{c~fv{1+SvA89PiU>u%JPZ!+>mJXNvCl{YJE%VU7d^F{=Qr9imuCR zojyWaI^>wJ%Q?JG#Hbc}#nEdF~1^(#2o+-km#dc(s8!drNlN)vr8z=?O2r{Z6Le zwEp#X-136Vvi7qcUdphpfB3uH-N3hOHQ)*JdE{f-X~6Y9z!Qey+kuz3UgF?CaoMWn zxvjVD+V{i1?;!jaKlU$6uYTQ$cm31&tM5V`?i#u1ie#~RML>)|>i1)I$=a!=m%YXbIcP%}AwD_?Zzr|vEN@tk{Roqp`98(#OWd%yp~TULJfv2#`sS8_dm z6gcxYCv`+iuQ!hJbIH;(mM!`E-aCKw-4EV5>py;ZCuKtTZoT;VuaIA^d1z7rxWQ*m z0@3jD`GD#d?TS%!K-uxhcWlR&*|P?IkFmMhbrk0Ihv0FGYU$ID*L+U%H_hi#?m2DE z^Yolk^m!>g*AT1$$8}z3gU`=+hMu?$%S`8~){c}raf%I>7FpL~sQxSaRB#$^mN)B;SVOjPfQ%K zoQc)|)(E156ck^?2k}M4i(e)@E;+mavV|9Gv&!~}J-;^Q`NT{AsQ_>UV z88z`id{L9cFB=Yis~j<7ZwGDdx6Ad68uh^calk33RD#c_1=C$N=U5$oJzzNY+HaN5 zZ@J1lwB_<}#@LYL_)aIs(M-e?yrSV?+D!1XpPvF+sJ}hczE!?sVE=xrT=*t^tNa&{ zZQhvIhMIY>h>~cIg^w8Vl_kiATiLpsi z&Mm#njw7kF8XHdpC%x7AiWvBgR%?rTZqCs0l5jX!`4~Uj!^@s6wG^;CTgthyE< z|KVNVC3?l}0a+~moS}ZK^_9K9b5WkgzjEb*%i{n(x7WtbIxU{%cG{V$Sx&n$2z4+2CCp zH**kwwSFGO5)Ic^!okZ$zU)AIG_Kx{qU#~Up>v~eO9yoSJvI;+|gg#aOpJnZr~XQ_AC_D<7a3K>)Gk*Rjp~%18sqPf*W;k z!so+>&q7f?!R>Hx(Q>0_p(vl=_Bc4vv_hy_;(qh)Z+7PLH zf?ML?gimlg=Z4{wPjKR|@Ck0ytT3GN2~PQhPvK3N`|x7>xK=B<`8oXL--N3tyyg;J zqjVCy@(X^SgBM=GN82rUz1@FfQ?ynzAvt` z51wm!M0iher#t&V?!;0%uP=4P%uztPDnzackw zt{q7kAKX_;b^NzE`#^5z3fIriX{?_MPV$sm6$ig>CCm4;4!G+gCr|Y~3$FIqb-)5( zxen;u*mb~7IA5N3eOCy71jJ(T*8%It8bNfBg3`a@gZMJB+VVyGvemf+eEG>ee$^1( zwc$R7`M&IfE}`4Wlh$#xucWZjU3NKU9q>x%0{`rT2fdzIyp?5Ym-xv;%5n6vSp08Z z*Ne6D+io53JCDygpvr$34Wj-m-9L3b&OLAWIjgx4IL*VLn}y#W-@N_+)&VI?ufffC z(x$p7zvi8OM;Fm)V#3l%^o!!Cv@<)H-k528*|ceR78|WpgW;W62c*p38-dd}8;lm6 zL>JL1<>b1WTvgh+F+Dg9GI`CypMzrgE@(50%a7rmG}7s&AVJ`d8}UUa(M5C;sOYD# z+)6t)XER$G7bl-i(}Zv83`QKOt2qfX6y+1TxFoY1&Ya`u466NAF+AC2AT zqkR?jk8C(NZnVtya|C_gae*r7G5bdkdabj+i#v!V-p{d|ceQcD+J}w5L)7_Qr+=Iq zU;6%!mHevwsQgwdu_C{P9`v=Yf;sx2TIQJeX5rVd*fx9OLW5gZmD=2gaf9;o!b(ha z59vhtmAp!R1tI&#hVdeg_n(Qp9OjPQ~#8(xg{LO0*|Hfj|&o<%Eb&WSjxBN}bOy@A+j@7@No!29TOhOghg z-MmLac>05Qn4Vk-1riD*6i6tLP#~c|LV<(=2?Y`gBos&}kWe6@Kth3p0tp2Y3OqF_ zz%|Qcz3{2Y`=r$g1riD*6i6tLP#~c|LV<(=2?Y`gBos&}kWe6@Kth3p0tp4CLxIND z6UQUZrp7--$>%M{Q5n5IruWHIKfPzB_r~-dncf%G`>4u4fM==o&N$!0X=ypnyqV4P z;QM5y>+H8hyyBn|f6YeDvEQ9qU$EO!d7_wg&CsW#1>; z1X#XL=G@r#$Tf1j*AtPvy!F(|%>58}(j8pmJ9XIrH)omhHQZ+5*Rs5}6)14}wA$_Hq^d&v%@sFtsGqA}tDl$7xBXoG-(q+H z`gz+u4xRV@YhSSP;*0*vgoFKji_4&X9qs2z7ar%v_VZD1+#8K#j0>utQ&(Rblfh!) zw`%NFA6AT~e`EW%+!)jcBuetDa-;HFtx#Y72GaQEBj2}67jyY)*(b#}3x9zMoZ@Wd zNrgrt_Tc@Wk0b7=NPJvS@+*0j{B}C~Lvn3l`Awg<+~?ytVP*L)8@?Hl`lip}uEX5q zGD?0K=6SkGcgb>${6@d&bHwbMy+3GhQO+2bwifTH-(P#;ebYyL5MR`E@k`;E>XO$} z@#VJ2ds)%&Oleo@Y2k1BDEu{4kmEvO(HAJck!$jIevUgL{7s)%KCs4oA7{GX^zn}E z+J%!vD&O=Oci;3mwZ=Dn?zrvrj#Agh@A|;MejD{3TlT#Rj$ZbI|J{4%DPOkV^tpWd z$Cq98(1xY+m)URnY#6%kj_-f;@@4N?AO5CKZ}-{`)S=@ypZxIBEuUPlZ110r<2QxA zbnlUO+%IG^+y1)aD<9mq>%0GRuiNBN0<(}yylCTv}D*em3hyT8Bbqxp04O&|1SoNMWM zzlW_^?K*JZ^r@VO=*~ZU2vrE$%_(tuKDF1L_oJ|RzgB@dT-sM{$ftVz41U&gkE<8Fv6tYKPjH>r z*m?_}4{T3$5}fi0Zq&gEpWveBAu6BXb~rfU^Wm&dMCB7)%JE6~ z1Q$IIQTYV7#K8%l5BCit7OJQ639jG437_CR?-Jt`obm~7n}ZWR!Tqr{eEy>H32wr{ z37_CRFI-RM6Wl%rCwzkYV`~^r`2?qY!l&@gxqkb2-lO`(&*3M*Hn@JG{F0lf9FRVQ zSAM~l9K7%fKFU|YE5G1(s-HSnStyn;(PK8P+V zU-<>!>EMM|{dGwdc;y%TsDl??)jujXDqr~pzr(=`ugZje#$TSeg`kSqfQ@HgI9jRZ*%a%yQD_>$}ji{ z2QR$hzv>Z{ALSSPJ_j$nl0VTg3a|WvU!d_#ba3^rMt|iOyv9f2mHbH#qU9^U;FT`C z;$Iy6I5KM-*1k(=Nq9U~`O+hu8qb`o^5}BDS?j#c)LZ|}p5rHXt+NN#SvQC;&QG}? zgQ841IL*%|;^33>I^#%qK;py~@j-l1Vd9q!Kf21g$E`4~J+E`Q=d~?Q&g&G#_K!=x zj02VWwfcGI%WOYa|CgSO>f5N^WUbiGd0mYA$RlruMPp38(Ee)bZ`?WT&Mm#h_V3Qu zHP+7sCwYp6-}`yxMF)_;O-7=O4P zPtA3dl|Sf;PFlBSnCsSH1}^fUbA|V& z_jl5@bM3a}2=L-jYqL|}iB%{zveqy0bKRP99KE8LqTy)%$2-h^z895Hzq=cL+bgH8 z*^yHx&)C!}T>GToq|c<^Qf^&AdQW;yc986%eG$8s4W?XN3is z)oZ7DCULXy`|CVn$`j8cu62=4V<3#=Rr1^E^pfP-^M>!k4ZU&*+(Y0-!?jAPl0No| zvpw9O{nlTc;azy|IW`v*>NKtgA;Xm2IQg~bq8QTToa5nsdy@kPamUp9O> z^oY5Z$AzgsXctj$&?TLCDV|}adze!pX_>W~ycPC4XcH^42EzQnZu-YL_4R%WMEuqC zN)%Hx>=!#TeB{e1prgj|dr&O|YhJ0EIc9bSwb4GSGS;E+bZbpIjssYBm+Ua@@5nxr z{iSs!t*b@X$5@X)w0hnhs2HDrY;FBx>)kPS*u>x3@u=edrTb3Amhk=&@x@*0mlF<7 z{jyYugTEAdl9!&_T^0%3)M~$M4=*#%+_fICe2&+-W`4stPH>+2M|>NWcYT-W_4hH% zv{?M-c=V&KKx%tm-}5V z*idE=hrwOD}J;iw;LjY1Dl zviKrCh%YJE-^8y2RQ!HJ%f7<98egnk@x*&>O?(hvL@@CSPbc2(c~_#pjPJtTVbf`E zFy7b-6+43cf&J!q(21Aq3x*lb^xQMv_Hy3FzPNCuv-dnNYaqD7^{oOg{d+n3!g%$-GMY;?llk%ShqL41p z=RPLmX)Y#8d)8wdC}pR}Zc!<+XJntqUeUf_Dzbj`C$y34N3vT|sXJ!H+AR+_yG8D( zvs>O0XLqPJzAHUE;o#KYOP9yNA04q%a*?o)H_rDBH#ix)<+67G7Iur=Si9v8ynDpE z_7$X8oZVuv_;yQuSZkMipmK;W;)D3o`6g$#IDVP(`CSsPe6L>@t{>TOaQ)~{QK5AJ zT0g3iZq|sJ{CZd!rX26@@iFxyw{H3m)(w_(T7`PqXlk$NG_3XLEEBol1^hqF_`EGyIHDG|yDwrr~=sL;O&aDfr~I znW5fHeyZ}~(w4gKx8Nbp&=uERBu}D?=p?{uausT4qeKGoX5n88zO=2&6#4z@>AukR z5BTmE_0xrFtaAgydnHBsQ2I~$Fy+QM=}GLjLJvL){r4`o?^=1x8}7Le_p1B7m)?gP zV@~Z$<5XxKSA9KlHb&`LpK9S<8@I-(YWmP(!6eaL^Cc%D>p&ka5jaRnE2hcdtJxNhkWcAa0owWFG!b{0{aKjCv{jbs)@po>|qo$jHj85q^&Mg32^~3}NP;=ke`OUaEUF z*XH7H=@s_*GP!3i1)h(+ z=fj^`O-@>yP+$@TzPEb~-Z!}94miP7D!tioDm$2MEF}kZmrnXP=xg~Zr~~h^UJFo+*4IAl>ZNry)qr(X zeT!b+OMT9+(+OVr1ur<^B`o`D3)WZ0@TYY?!Y@IB*4w_|%Gu!Ff8F8SM{ct3#R@NZ z&F5o)*t!~1{e`2IJ2cQ!3e!CVePs^b)LT?p(_w7qig0)$ z5{{-f9%d=_8Z+OtS6x-Poez258!p58)B~RPO1Nx4pH;T$zc;#rw6Hp27y9?3%R3*s z+?}~%ZCk>u#G`br6;2Y5zXQOKu3GEm+`Bjd_wH|PrA}H#|FgdMR^w+m3lZMWmr-KW zi^R*el1BIJ{Nh=R`{|K?jr-gV%2Nm8B|o>p&wQ!=*T>3(=*<0>sV?D_JXXUyF=6FQ zc*VbJxQUl*`jYR@z;EiiCsN*t>ATe*B? zdJtzidgk|}Q%;#i2T~m;V`u%Lc+pQSO(#}hm1xDspZ?1Z#^FZz8q~b@^|}l2BqV69 z{h8|kGF7?4___;Tm&*^3degt^DJS1^;aR%xKmCPg>JFDGJ3%h>iM5|RuMMM9#a?n? z;~nOit}qgXkj85`LO=VgD0Lz1Ej%(|aUS--&F;)GtLK?+Z%apz_6d2FuIvlxSN6{( zXo=#vCK<=S_|a!F2`-?7f`qag-tF+o4w(#LV=h?HbibM%SMO+f)DbiJl0H%$*(UCt zap%hJUa6HW*blS33a2CTAY8%y+Umur&-ne<=Jn&-AA9ezT`yaB=J7XP7#U;YV4@`j z^922#_fH=>dD&@azkJz0Em_F(B)!+Z<)%A-{)Zcvo^e{nlyk@@|6w8HA78?aM|Lbc@|}kJ#R%_UzJEmh zS?3h$$^47amWNP()|ug5XcyaZs;mD+FS_kc@1J(vx$V$X@0OlozUf}5iYx6)U}taXz|JpV=K^9qqRzG)>Vyz zcvNN_?}GVi`#aAJpEFb&V(J`mwVfJbda2a=;{a9tuY%u{y$ha6m*_Pqq3#IUGh8ph zxO!&YKrUl&tgVbMZeFYLML0F?C@dG_%Sd;|8}85KGm2}_t!sQaSp2J2_s-*Yy7jR5 z9I3C{^#G-^zTxphEjT#i%Lcd3x6QdMT{Tc0tGklRXg{tNAH);~6HKQ+m?!9urU@>Z zXR3USRhQ|xK_1(;B31zr--EXo-Qf80>1X}`dc%${|MG+5m)1AF%mJEe zv~mSC>tS{-64#b))OR)!-Vh+0+mmU${1< z{>|LMvY9>`aq9QMbd61F`%E62I$3ddowpowA1p+qK5KdQ=ZFusS@~wCE|S-{=Pf@k zUCiXO>48vmLxH$*d;~3+H%Ir`gEA_=58>;VV49gD(;np=xR{5R^490tGaLw)0-YAI zj<69eEd5wIi@C;KS#p_$`%A6Bz$uZ1e+Hh^<{aM6;~B?mwztyjn8jQ4;(E*BxN#wm zg$=t*;w2n5)cmjT`OgSCoUBI&{B8}%x^_KCFx5)8^-ukH>UV*vK_Be+34blZ@h4gX z+aA(B_rdv<8?pggQfug-a!mvs?R@pOI3As zb$7zZHBA4Cwrg_O_7_3~@ips@;;R)NTW08qY~rWZklF}}tIhmc`kv;U=B37e8+w-9 zC088c%q}z9^hV_N~N|x?P*Wj zeZ&z*ln+1raC0MEKJ2i=%zfyghn97-K8=}Nl_{G8`J z$G8kX^O?^qA9d7G<)=UW>1EYLb)btn?~cP;PuwAg9MT8;yPx~q=a!%U{O6b3+SACI*`JmF{LlZqykNnCa(jEbxnJ^< zmy}=p;uo8^7rp3344p`mXg$!L?e(-9W%se%m%j9+{D~)?SXOX%$Q>zXvo9$ycr=Na$ z`DHJAS^4EJe|h;8uXu&I>1W&-XPi+!?X=TOomfZKg>aOtO6R*pXU=!&ee z4s+(rsVbYG=WgOC&a;GtWHJ)P?mVeOM3DjP)Qr zC@bV4X+hawzhU|03*|b>3*_lrvSf+DziQR0@;T?6Q$F|HbIY%MiC?{X zb$R8=l_u|5XPsqe#Cni!C!c(>;mcqA#a|enP&O!|s)Lh@N&SNGY%9w+@4WNM7hG^b z`PHv}b>+VB!V66t(_ZzeSDCtZwLXNDIm?`N2An4(!J)pEq<@ zg%9Z0eQeK~HET?H>({R@zwULfD{t7ap>i|)+Sk6e%(S&@*P6O8Kj}hxkT>KDWrS^^ zoKh}S2l9gQpuT}RRA_*_yNQdqU;p~omoK^GlJXng@P=|%S6Ag`_|i)+Enj@`#imZL zdChAo^&maSFSdcSp!`rq$q&_m{eykuS8y+D!8(&qp)&m9;m}83+xk=N9s86rH{O2+gNUY ze}8$?rcLF+!NJhYxHrD>jb+w{`B+cZGKl`VojCsTFaOfufAgE)T)yIpE6Q(u>s!lL zUU{Xt-}bh*m31?oc~}?13=9kyo&@V4UQiy`r`b2j2kHjO0mmP?=HXRJ?|;M?|ttpf8YZjD1YcfA1Z(FgC8{Ecf8{rp+=gzhK`aAE>w4Cpngh2NLIbi+rG7Aq^-8<`o})CttjlmU*D9H*g&EA|NV!D6=I>Z`9V zZ`-!5{IQRHto-qhf4uz3Pkz$y``h3CcKPQ&|9SaOf5JydasB@Hzc2sz$3HgZlTMUX z%0Z9@lmqG&@_=I~`+>?Q|EYU|V=(mJ?)Sd;y@u}OIotlJPkqYp{*F8DDF5(>KP*4| z@WbU_{_>aQy?ghTC-AV%ZMWTK+E2M*{kLq{V&ov3&6c~nyNw)DC$S%>eDWXqr!w}a z4zOnzv)_@P9le({UtZ+`Qerp)hr=Q~Cgzx?Gdn>w;TvY(QF zltc9e${}Td<+J^yKlxAl1bTmx{lR*mfA&%KNq?138T;&KKWpTGWm4|hAIO`JeB>iW z{#ZWcmpYRAfby*JNq_R6I)FM5dM8A8wO=mebvtE{G`QuKTTEYPA7DM`k|(Si<&(6c zj!^m3AuOLVNcxlils}HI90y<%ZkNofyf_yy+t~+M2ey-C@@9P~7mR1ySx?GrkpAog zbs!z6bJZ7E?oBt{WXfh7`w7!2vy^|yA9We^AbHQWQ|_Q+ zw>MIDus)PY${2M5+e}wwQ(sW_#e2#g$7R|Q)c??TyJ_16@lD4M`PmM=wwrXOj^s^0 z#~`*_VNwi~)`H^$gL=+{^|pH3YFgZ|rxF=ab%jQP8v=Xay6yV2I|&?|k=YYmmT zezoU~V~NGOm{AfZ4)frJ7H1riD*6i6tLP~b^Q zf%C9FblDuNhqz~)PeD8DSr<5Ob<@v=*HuoG?4?J->nHo%JJib8|84tjqQbS@(o%O; z-FxeUOWo|B-RSRD%uFBo2-bSX#1NtMN!yNK&6zD2o+*B{gKJ<<)~j^uWPThd`jdvu z;GT*fsT~Ke9c)80ZBaX-tHi{~xS+hvMVQY#+RMC;W{%F9jWucBZk<{g@XRdr=v?oo zcyHfEwxBqcXfLksvW%cUW2&BmHtATJmcIEM64{pz^d)_Gpvy_{H%9@=$2d@kU#G)w z<#=paxqJoX@vdK-`-^kuf0a^Y>Kxzq zbFm4!1}Q-KxCSud7dJblhpqNJ!CD1*s;e~Pb zyo(b&;!uA270)>3r>l6$vBo>e@qFZ&>N@|N+)&%u>7LAqug&C(jc>6wYTr&(mn7}L zQGoKX3+TnKm%;Db57rW({81h$WAsygDSJFWi*m+u7btT)!+?2Yrx1qu7-l^Ewr}`2 z7*9CD^CpbSQylTL9NtV5F6QM$oQzi<)=P3PdsT9OEYhaBDsn$nrYX{*^SmjtCP|MY z1t=e#C|~?q0zc)A7v+?aNLPN!u>92X^7B15`8j`;f5lq7GXsH4wb?VIZiA3gPE!lQ zXG$R|bgfvsytmiupWfj^784I%sOMV7Or3AD??FZ1kE#bjJ$Y)qA2sHXu>blO?Lc0d zuS^cll=q_^FS>cFErm!opWl<|WOMm+JTP?g@rQXfRlKcP@|#c~p+G``Fa^v^%A998 z+YYFeWZH_a!p(De{r9G=p7C`XbfT{mIhHW5ISc9q2kE&gU>K{FD8++IZr( zn|$Hkkm&XaFvS<43jLQp{~engPdadh>&@;wE2ZNwM%i!9UaQz|r&#+K%#wX8V&Mw|{^-k^O=Z6!*^SBg)}!AH#!YFz9rL;Smj-XA^Q+o!NM9-YP2*>r z{pQY_rLJ6WyxWZx7r&T(RH$ z^Wwypfc@s|wTk_=#My6E*5PQsjpRM7znvPWcSGKW*54-Hnb>c>jYc|0_M5Zo{F1E?_FI0W&>xL%B;1hw zRw~UL`^{g;3d*_oMH0wAhWQlFV-3dz)2HW;;;R)-?6>LBS^PB&OnwpyBos&}5TL;G z=x=KM%^yp=sq8ltGqx->_f&)RQo>x%j8aKW3_Q*ezv|8`YkzxlF2 z9{4t*<;YawWc@8nuOO{z`7L#m--H4Q1riE`DG;*XLP_=7Z_n_ds@iYkTh2G@InCH_ zDK~z`*>AHdb)YWfHQBAT{#HutH%qz-{o=+IKa1=)(XDCw&Dm=e`)z}>-<)0Nmu!8s z-*Q8lW)|QY+CQCm@655^;@6wSFVaW;Wc@8!e~b2=a0zB10`={X+O=Z8~ z`-jd>;(MSK>#3^!2F%(kHFjLMq&lB}bK_^6{pRDFY`57oo(adR`unF7iT!3tW$EPj zDEteiPlQ*>80}|K{wqiv4z(v)`Ou7pR=^!hXwV(uHOWxQ5o>N>|Su`^~3C zP~OEWrplk#Z;AcpOH1NQD3DO#$wYy``rBM<;iz>}*>4yhV2|0$Sb)}B(|&7a{Y~R% z)PCbygkSUEc*aWk;i&!gaQgq=x#(@f%YO2kEABe%YahEK^^WBEH_JxR&9?!3d%({j z`%QGKX1@V~a)FEIhn!IT{19iaRqVHZXTLeS&f@TYSFBx?&Tq;Ld8hEC+-Y46t-p0% zo7it*IS9%J=|5FC**^`_CrGPW{%Of}0+di7p}>=#0{h|pQyu1N$LT505Ak(akg)Zw zziIr8+Hd}|Z^TJm81F{yx9Iz)or(QsNmrp?+_>Urk^LsRRkPpfUVn4;TE%`FcJ`aI z>%3!H#`S#<)&llhKD~wKhb;6f)tIlfvT{5%oRO*22WF1_mh7MU3`@>`^J$Uz5(*>~ zcq&ogI5yV2f9lPyd=A18pvL-}vy=RDbcu)eROk0Lv;L;>GtPeV$Km?zx9Iz)rNn+S ze78Swwwq{cbI5)Z-KyDdb-#b=?6r#hHtOs*XV(QPXS^%co}C>SIC)hjGt5P}=~!_M z?VnD3aOT)=J}tzPAitREhm-R|EVZa39)G*n=Sz@BQ~PcGli!2_2?Y`ggeef%KaG5V zVQTx$tJrV+2A8{P+HcfTwBg_epNCtCaMhc3!Wa~<#?LtW&0m9~e&jXTjjq2%?YD`< zezT;j&@XPR@w3Q&6WyA&-<-WxvERm={pRdCzhvu!{Wg#;7BfR9ugnb<^XWpdVI!^~ z`>k|cV!zpb73^D*5%NU-xb$TIG)$i$t!nwBlAnYV3M3RrC_oA{Z@=+ds_r_V_M67f z17*LZ-kCiACPr2tYy2Ft-$b{j?KfwyRqVHtv)`Ou=a+1KE7qQqPankZXLW8%>^EO7 z$b+EWQ7fF-Z((``X;;f{u>&^jOWeq0c+WBT63$s z`(Qz~kWj#pXHZNUw!Lu8b1$|{Wg)QCH}AA)QoZ4Z&JQVlEV18w8-yed%1EtnV!wsy6{KA) zf4$4&@zecst`&aU%Iwm#Tz*-@`Q z8r?{^A^R=$@yFMG8*?q28TK116O@r!;bi?SOs^pAYWW@G6DOfSLV<(=Aqq@y{Vn|c ztO~*dy8fo|GtPdi)F5E5**NM(UbVlURZ8qPODadN`0>WiBKu8rt7gB|z5eFxwTk_= z)7fv%uJcQ_KG<&~1I6s{z}9F=-QkApw~3n)`^}dL(l}^$)Cwo|TbN!!+ST&cEze2D zgaQc#o>CN;p8Xbl|Fp$l5ICUro5s%rWxq`%_FF*mtBoms7TIs2ThsQNv)3y2+b(Cn zIlIm;+4@$jJ%6NkV>6#WZS4Ki(kBx8&9_0wgP@Gm3Mckkm|j8J)$&_;Pks{$Bos&} z5T-!$?=L*fM_9{#YwG+Ejh}J$n`woq2X!H@$!^^K=}B(?G>`q$R4IA>&C*WviyK$` z9J1d;w`%rV-TSA`UaQz|6V85fcAa0c^{rTYVRope|K#)18;7!eTc`6LYD4dzcHWZM zZ@vu@m62NE#D4Q>7uT<*ii=8q5>6~ z2vZ#{igBrK-q5-iTx%%!mT!@_*rDXiEd5XZ_Zw;*l&BC z{pRet9pC%gz)~;Q-`4ev3=9`n<-yd$c49k%q-e`JazfISEv$Rcq6AC00NGK4cz)_5F z=f8#1rdogV#{>_ja#mI`s@iYBtalfT9TzUCzVmxEe#Y5vK0b~iye7L*`z?BYZ)ak^ zS<+SL7aWh}_p``;6WyxWZ*`v^;_S7G{r0G{-<)0Nmu!8s-*UO)!F&Gg|IQry&8J0B z&VxLX|3IDJ%NqD)*!oNrPVBcZy@Ir=<@dRr_!0^v6i6uGQy{qh=Eu^*>9p-HT$jZ_fMU@Rud@1ZAXFII-Wt^a|3hmfy;I@|#c~p+G``Fa@mrMmsHfO||}pycPTH2p^Df zQ@y{SH8{Azt3LZpfI66WyxWZ*}jV zI(w~Rzonf0=IlDZWb1?dHqu?pr+bRgl)A$W*>9a+o;miL-@>4ri%(3IKiNO^R$FTE z8QF@a3h4*Y>R`}KWi{g3`X|2$1riD*6bMsbKYV||-@H7a_M67f17*K;CiYuEG^&j+ zeiqqpqFdAUo3qy{_S+-BeVbW-b9S9yvh}T4yFN48#LK6^($M>-sjto)`|a_!L&$@m zjMNGz`=?=g1!-5yPueC|LV<(=2?e4Q2(7=Rf~iyOpEmpb)9HM_UgKw+{kA{eKP@Hp zTY&x5#uPt`>^IS^n*CPy^KZ^xtJrUkI{VGpb$-d#2m7smWUzahkG>fkjh+AYwV7kT z`LrOPcm??t4*TyK1@koP50}BvRCQolOJMcO=HEZR$^Pm7p<{w2p+G``CmIF(=ilu9 zqF?{1>^J0c&62J{zqm2p z&m#LxbZgpvbM~6-HOensQ zKt1JHe56N5hs(dLb%CuT!*=a=VnwLjj^oY_hMCX8`u!%F9t=N`{rx%HkK|HL`q3bT z+p6$)U3zeMAUm{ix^3tC^0blswfMH>j9GR5@`ayxS&NtQ_Fc~XcwXeiIwYLG{JhmK zKGO5rhccr@uYEY5+3dCVri*E>y)T=`lONQTQ+63dV{DR(Sc&#aIQdip_k7Lq>BJx`I&*tpf>{gZ8mJPY+*_HN=bRc-E=R= zmCy7MD}f5d{Kbnw4CBvUp0O2`R!APp{OU$#ifUwj5+pwN>+)BEyh z?NHvjD6g-tkSTfvL_<_FUD-iYXlu`ahw}smM+S=7uIx~6X4D%m z`XcDHr-!nGU{aopLjHW=Vo06!b`=J4MZgz|UBQS#4iwFpcvB^>IGo;?F})P*>qe>G zXg)LSZRJmK3kg-+LNYPQh&PHFHu;Ro$Y!<}WFy1qffnyb0gPbH3d0%rzZKK%^q{V!<=K>l$SLLI>>0p+^lD-S1Fl zqY zrF*CZ=l}~HNYOCeE$O^*kqPAMVbowYZ?YH?*t|Fw1qsTK8O#E_c=(iR3f zWvF0^OAmH44S1CuUUYAh2(QV>9K8^By66l=Xm^9qWn<@J7+q##v7f%4fssK|-(ILn zMr_IsZ89Lak&Pw?x`9KuF`wR?Ep9akvV8^-NzO2Ilc@)~!hmT)p+DW5+rp&FGeaW= zGdzeIVjT5{$p+yBv!Hwy`9j>6uR5RT{zG>f%gIG2-^*x@iu$HgoXFK)n=l14L&A z|6xZ7Xx}cU-7%6;VH5^)7-?-X>u!BrBmp41jFyAZ1NBxYW(NkktU9tpLoR>lCNPzy zAy==>mg~u+htMz0@a4LlX`Ues#^>&l0rbP{#(u!%h9KNf(uFhh$n4knR~7O6MW44CQ)?FkK49YgIQQH>NQ*Q~h_P2XiB^E`|zJ0alte z4|Q!>=<#=v`CV*&Pv!4mW)$WU^d3M5>0$Syv1D2h;HV#IS!vRZcM+x9YA6^*#yabP z#~5ey7*oy0z-pj2GcEMeeH`1V;WHSAspRQmT!B@THzV0lx_cn)L5jhc_919KD}$LK zSck)~x;EoRpF?^VQ!!}gdYsmzZvH|_%ci@CfDm=<&7 zBr2oqVX<()?cG8fr+3Rn^NWENeu@&t*8Ik;h6|ADob9Can6jV}A!{BK*+TwMqDR1b z(}gjjr3)UrE-E(&^S4ka_T#soRmt?4RFrU<2b;r4Mgc00fj&rzlNeK7M$yWJYr;^! zT_&$QTd9#v)a4bQ?F}$W(_PSY;Jx*-V^@4zeedO7x)%dpm#d-hL6l&(psyKq$q~oY z03_q9QHM?_nGpk*}$5V~LJ_yoWybwmxaJ~y(8uB#M zPUqmjaf(&N_*f`VN%*ye((4-l=@_eI;-{FJfzyE~&d;tGhg>EmEuOBPks^i?*gRVY z!N)wzOE8MmbsPfwtYt<%o{9#YQPBB=K}(cm)3@|9RpO%bb;%b z6j_akj+@D6(*v$-*dFL`_(g}qZ?~~R__L8e-5$(|Jb#RDBYh+cx*F^$0)Q$;)@g{K zcU#jNWHE`}<+Ohx(!G{?10%4Jd$xL;a|7N+Gb=#rhB5<~{Lo^q_`9-|5b-Moex_Ir zR~&^jvL^7Tr?b1b;aolpt!WxeoF-s~#NS2UM)Z|}Db)IyhdsH=PY48=8tjz@Fce{O z3}p+s00J{!n0A4u#hd}M{5491O0R3c=)Ohv7a^p8?GTSNW<#7L!Nx-$qQz%Aqe-_q zYNXqb>CU0+0}3`E26kBT&TB?z8=Jw%s%UhkK3Jm)n(3g;g}FJ+J=oq3L%^&q7)3c? zl_})3%d#3XE-LQ)#%|2sOmCyoL9ZL279GTJPn8LcWn4-v^&qA&MnL4p!otRWYguJ5 z@b{pvVjjiLnjeIPmd3RBh&~D+qz`jKGq%cGi8fup)-D(oO-mRE`a3Cu{vaESXrNNNXAM|ES zC!x<85A2dZ;)m_uAI??oQw ztU!bn0{)t112fI>+A|muY`ERzV9l{^lq&+Qw=pZH2 zm^gS_GG+kkU+DEO^7y;c4UAZ4GZqUVrz6(cY*sKv%r7jYO_)Rg*t(lN7`8>Dit||6 zF>?cju;i4__KtcmyN0|iUcWblp%Mhc0*Yk}dc!am3>a@IW_{h6&6wbVF-Xo^AI7oV zkTuQ;Zx%3&Fci7T?4}-(Gfvs>b z@iXo~E{BD{K{_K4662w$w-2HKOz;LdeTVCuK|{~>!3>tpu(ISr1^~So#wv|e)B3LN zq6us^lS8`*+GqS+j!An1<`?ZXsNkA%;JTW^XQ~L-)Da}1xdm-y1O>u?b-Z4yFR-H9 zo88QXT{uup7-=wI81vCEg8ICD5Nt6kN?3V8mm*nEZ+0$@Bn2!fapiSnXbaamH)DQ; z$q{Bor+OK?xYPrq6C+Z$>(E>>K_6)E-9o0h$etYg{gC-(t*wk~_JDUY3+(f@D{W)PX3KYc54B_j1WcW zb*l>6?eKuUmBj)HDeNp)D9>T6I-2FKk7@do5VU~HgZj~P8LIRW}mQyUbL02pRL8)O;W{@hH78GWN-CgNCmLyFktY|>& z(Q~cGXecg{w%gTDdacj2mus)|3}Ql;G1fm!IyYHy07lp>$xV%lSj<8VOcyeCrdfie zj_-mU3PHnK`G{GupwAH;)}ix>1y~a_8v^LqusJOx8oe<;>{Am9yn~$XxAzUeI-qO} zK$fw9-HYMM8UYX>D`DKIAWyJ}iR}k00b>9}PaeYL#82T;C-RsjPq;AtNdQcB>0pI2 zgJoKX6b8yXIABd$TQ!QO6FhjqMKgzY%boFwx6ET3F#H=+ww zjm~GK82HGj9xO}uUtndny#QVS18g}%QTgqHmzn2y!$spF2X>rB(ZleY8-S>}PS<7Q zDj`3Cn$~t@P~P@kcx(*Yh*fFp7^K~s`|U~xzy0|3PK}jYwI$YGT`sQhKO5KaUnZQ zvNV`3RJUM&DcovG6^?=znCQNdp&q06xcq3;q8)0eAnj;ld?XP!kFsWVX}fq=C5+|3 z9&D$${Ua`=7a_kM^;^MwRF*#AF%elab$tWr7yFyB4tTpZbLF4g zFkL-nQet&53^Xh$c`ktEJU@`fW(#dZ>=(%GVw}->rZ$|vJGF`l7Xt+#+F~Hu&6*`L zbLrB`wlyp593Cs4oP8T+ZvjWUpo?-nT#qo;8a5-lwqOYo8w8s(Fxayjhp?Yiv_W47 znN&N6=;_Z5Yhki4mmY-5fLKuxb>rx2tHtS~Wo4=pSaW55Gn`aL6O)6RIj}ykRN;0u zFe#&nU{w(Mlk;r#Oo3*`==2hnXRt%40CsM)sBFz*jG0i{R5x6B?@MC~tji7e?L8dj z%;3Ql1GfZ56_C$hg~=@0F~mJnv~dV616@ogs>Dqs`f-;Th_UI5H3ldN0tSXu8#4Ph z7+WnS0%-(Q{w|HM6(V7T?8+`=12lGYrHz&h#&jzt(8#WIq}5$qa6yrrInu-V9I^K- zuwy?VvgApo#@x>mk0vLg>r%&}OWJwwrA$H`O9Rtr+!l zW4MUL-jP8ps6%r5yR30Y3tuZ&UFlI6NSF`yYDIErBUba=>LhwscQ1@l<8*bK>66C+ zybH4jI-AX~k;xnD%i1$t1uS)R=Z3J^k?*mVy-VnYelQ8}m;|H54W))5vzBHUY_OAt z#RzuG5%dGPec1W6KCX^oN(Q!IkaG}N3P53?7UmPy&ym>67|VeX)@w#b8)>x+NrK%T zaokpk4>q6&(_S=YquH{wJGfoYy_i)?!$``pLk|{X>bV8Oj+ucP2eVBZN!w?{JX?Wj zCHz~=`~^ce=AM{@Zt;3Yyxz?oEai4Ii#BT(+gZTL$?Xy|Rc?1XQk;`ntH~;CNS1vb z0q#Nu7V&2>f2d!v@6Ts9+F`--X$uM$CO5`GtNG}M3)n6Ws&JVUyH=QF;CT+?;kGq4 zg*Ss7gVZzJlmTL{&abrnu;AI%X)*;{91weF?oy!^pw96q1bYJ)4Df^mRu6m3azU@# zf1v88;bDek>ybs-iy_LyXu$&Ed23XMEVu)P>wIH>~N#WXSHp(>%^{4IRB*ad?~rYe~>qe7?e1 z@_x{oIA)(W11eC#VaEdN@i3t&D#bhya@z$h!lDyn3s^YsDN@wAVr+;d&m!nDv#&$J z;S!ytDt3B|2ahHc@ElHVINNi!Tfn0v_!7zIQLtZ_$8#chax1rqQy&l&B>Ml1y$67u zMfLta_wHsl5C}2!5(v`5f=Cidu#xO;8f23tn?})P@77DUu_e0+ir5eZBnl$RS4C9B zj&wx?1tbarA}T5%O+l%46oudCIcMg*_a=e=Kbz;i)86TG=FFKh^TwgeKw{UZj{1*P zQ5fi0p9$>;JvXcrP=0~KZAm%|Vp*BIeeP$JN{6ST(P)qctyvco`_b=F@{KIun^e8+ z>}w44X(jK~O>3cPQS4{JbRz;gV_*i`(UoF^k+0q&^-mVX4|Q1XoO+hKlnSiPMDZv_ ze|_t(cfc1jL>F0WTwFvVy%efm`a~LZ>iDqsaZzrqYuX=V5&@fbRq0f0_!c{)oFYXm ztI9+MX+aa3*z&;k|FxmR>eQxOjd-aP*pJih4RAXFX>nSfcCjdK+U#5un2MtA1?pw$>f-Vx9`e0(Y_{Msy*%s1>O=Tjd(rxOB5|Oe z^pZ#fx-xzKGCgo;#EoPv8YGvq8Pn8{d^6IF%%v=N(srw+39Twi3joRAY_ciiMSa#p z2&EWdykYv{2+|bC%Es#jvz9hU4_ijG2gX|24QwinGI^tV5*Kp}=Q1` z3@!rER=v#=;#E6VEo_Cd3|mdBXHcmf#WwHLLu*~uFxazxxY(|}LrnnP18wLdS#mOZ zP{xid8f5ll4B1nBk23}-wHA83ye!48(G45c+rAAO!X78>E=p{wlgeF-Ikz5f;kEPQ z$|jUW>IVEGjwcnbraB3|Z8>Z8U@C~Lw)+t?TZXAsh5+gy{Mdk$fl*5*87{OtSJ8$n z-DISc$z+NulpEmg)*{}r1X~w32AE6@dBiA+o&MW900BYG4^crovUSP2J@#V%Ac|mO zfM}l7XKf1}elac4*-GitnCxX1sTj# zu4BN6k1yW!8j0*4Ewa`Y%iJU?>%zct7kCh47OXN>nG`Lv zTJX#^pKbVltwhz4ls#$wwHO;M(|qWaR+;W1lU!^pFLOnjZjlgG_wvpzxED=qt2%qf z<8ys{ZeZ;=)ZJu~Z;8C?>sk8`nXJ3Hq$^Y?SUSoEMkWH8#A__@m8Hq>ma-0RNAFPE z%}|ELOr$F$4%N)m!Vjdjit91%JI{1l{`H>96# z{jmR^6f!VKFpQ)DYOEQqcfeGw(j;We0|lrb7?0_qu3-rbw2R=;ZxHZySgzN^K|~vdnH9FkZQBz*K~= z74;HvOG{#apl^_#Ihc7)(J5Cseq~Y^?rg zRRk2Lu6++e;-`n{I>a?R)^5gG=TKVI;}A1q`qi)u6lstEFd}U%f7w-sI@wNf7)BD! zlCgJifmCLhsd@()Mo4|z3(=*$;0|5w?KT#9E@Eo|o}U%%@tx}zX!4&A$!B+SEcO46 zvHJBRox{zYLoG({@rvVoY_S&jy`9L){3SF`rM%p3q8iuDZ}0FV;Yb-(J_t`|Nm&uf ztd=7)wZNAkrArwwH)d^K@r11z8%>?r-(-n1FjRVhjuR@^GMU1bUPNq0#IQ&mov7Fsp(-iL&1`hm zGC#IrB|)RhD0ALx%oJI!ZUm4vq=uMfS!~*?GP3|pX4j|lV11+GM1m$F3mXwk*)3d3 z)^=cgETC?WG{c79AeAtr!6BKiMxW+Fo7Q_xTF@%FCxUi5rs=7b>=GAkuqCWa$Y^?{ z8-Q7i1@wB@*WNO;j!PZGDqNHu2iK-5$sfgrLMD4V8wUEjimb%@jHEHa!s|#jW;8qT zzEI1dSnceUcS`k5X+|^ZAU>Ff4P> zrk4*sZ9qun4s|)v3e#d|aX(hvu)#Orl8Y4Z?Zl3=NP5rsvAQ&vY&lRD$BbE`IZL&x z%QENdhS7pe`{+LNWM!yd+ZjVL$M80NehZ;J+X9D3L_WooEw|r=_FIp@3+@f6I)TPj z#<1RgwQMqjCP2ha7Ly6#A?;8lC%YX?sc88je9Dw$kd#_)gA5!M#)o0y*6U|{kcobn z$nBwRYi$>4YmONwwr#9sBj^$-i|KX+53;TazvF16sGa7I4w`0ble+QJ*F$n*+#0RF)J+*QzX< zA?o0n*)s30>e*(h=vwB&xIhZ6En5!(ZLkT{JT+mKY-#kFmx#6*sCNo!qT1wv471oC z4}L)nSUTG;1Hi-((Kf1HdGgUmvAFH(mL!F-k2ZUbYfFj+YDGZQhDLNcMMZHzpWQ-pGYP@)I1LyICr zT}SF@Hhc*i>a@R})+92(oFUqlNg7Hi478YqzZ@YCria7!N)&E54H%WsNeVh84>YjF zpV_$!HGm&~(?PLRqE;SgbnA=WVB715b!^u&icyCDrsRX%IEP3j0{ z*Rqz$XUH^W(A{h+_Ie4diRgZd z9+l@i&kXD+41~pXIcw*5(GJ?J8)j2D6W_KJ*{F~2@P$d~>Llpd$Np=wv>^tY zD#lNnAwBT6x6=5Y6xEsxp7G2k;jv1`v6W$qggFQ)N2~P>I-`mvdIII@j1nXl$Hw5| znY3kEih#43-jnD8Y8>M&q|^~l@nHOsY7uoHi-OR?IDS3%vl+hu) z%4`*WX+$adS=MTBgB=kxaP7wn)vufzx$yd(2PDrv2!Sfzg7C z$h^-QZD>Q4-xQakZX09*Z8T=3cIVSZ*JaPLE*L|^eHq13WD8qoRz#Y*+1+U`CbcDs zq*(@r$;VEjuC`Y~xgcEXuHu_Lg}5~ib3Q`T#(mLbF+yXCJ+yKwv>BZ~pVvrd_Q^Au z&elR$neU|dYKuyD$Y_M~Iohn)+=IyjrPj=YqM#`zM!q-@!$v2sMStA}e$?D|7hBId zL91}jC`tM2LyR)%B)RrhYATN?^NY#G9oNk~MILP7P~n}JH4iKj9w7oAsRBEnP)94~1b3syQPExF3 z87niKIcxtc#lcDlawp-X1p6Mb2zJR$lcG=fnTaM~>nbX44)>?Ct!9#N*@K&vzHS88 zEY{J?)9MvxSXE7hU0s*tmj?wZT^&KKX2g zhHo_nKRc1$+B{7tJYrW(c2tlaw(I9s#=KmZAN`oWq=_~yO5kFrq{Jdi9ad_aaUatk zt=ZfW=O|Im(??9LI%pPKdV$XL<>92tYgx)UT; z1{fi|#G}=ZjJpy(1P6@;bPQ;MtdgZgs*Qfh6kvXa(3MYn>+}Ft4J@aSJDD7S21e3V zVQFPzL4s6r8yYQ?+)$b%zGx?wF0|p1R&tjCE1X6aEFEp#&a3#O*a{70$f)?438^r5 zDKM8NS!Jn%pyyZ|+?b&*jv;Rw{wo@vIXi)q>JxuI@ z>-)*2(pFMYU=~7oEQOS<wO0S5u?d#+0f>U8x_m$wAAc;#a=foT~AjavO6|V5Zx^MtO%83bkh1bAE95gVT|hVu>GnmT6ki$Bcn#PZG^reFQv44Jsxvo zBcs?MPu^kE+EqswB2h8eOi_8n*9$fptTQ^_sU+iqR7UTGwuxFmV8tM`qC~TDWv^*O z80Tk0LsuwBtxy9A!9c9qxZW>xv%ZaEP)3#jF(B#|EXAa)lf_%|i@dW96lILlr6xf$ zB~&c}Q1j463|m!$t-5)|YC>Ec{am`PegHs5tH%+~IPC}hr?Skkjn66%84rrILkj;T z2SkVLS!DjQ#xNVS+B0wCK45dCQAC?)Cj|22%NXf3kvn!n8AHbZvkO6fQIQapp^-&n z^eFaQFTrY0`kqaH_Gld~GJxru9AehfLdYPkPG*&Ej^h;j$Mu6=LvM#!{D}w~xi*Rt zc6W!2Oq)SZsy47xg^wgN>t;zOr^t?o{fcy9u|W(s?MbMmt&71diN~h4ZK125GQ0N( z)(X&U{a6)CZeh(+hsKZehk40jr>8*e^s6cpAIPQ!>UuucYe^nmIQ|jPY*o{0Lb1>m zb@Z2+VXBxoVaN`qb{e~T;C>o3zlbD{3}{l9LI`U>cFYJfr1rIKPJ|XZN+2~u6UoKy z>qD6FpiRquHjU6Hy^RER9S23%tun1Ed9k%jvj8cy_dC?wI!`_Ztw`2l z2z`#kByD~UfM6nJ)~uV`HD9^E3#@cJ)73H~t=9`;qg(wZB$>44Vi%ZIXDSsMCkWFJ zaibt7M#{Ta>>acjYkx|isPv!-$e}_9W_o8%Ze+a zixC!G@@(z#3a@EQ1%zLe-U`NvUhY<~p^T{jtov^49E_VuUCw{{FNd8wcI7JY1kwsvY(^;b9ODr;tdgO{cSPKD7C zPTjeYQx#0n%#SDZ%MP0Xq-edVki3U(mazT$*jFnJbY=FHus5B~lo_Y2;xZ`(Wi?*t z?V={QmMRH@xd#Bz1!qP3wR3`?8^f?2%apZ<9xoGY!Sta`aBIR#7h$p$U{3MGvzd*f zquJOO8xdt<=0robx2*tw&LCllT5k4$K3TEoS16YMaJfuj9@?$mW4#llg`?Xz$QTXQ zAI&_@RTS!+W}%Uk84qMeKhqHDzc?*B@sJtdL`{arK(v$Anv&$HXY#ZD;zx=(!w&gT z|IzI{zHfmHg9}AGUf8Ch#bc?MEydz4^zBmGSSo$(qBH5(#@O7R!k}wIzm>1LrJkk_ zs9pLsuOrL=Q)WC0fiJ>=ikLG3uFdXR=SX*pkqkRs0x$R|nkatL+rDTS9dU zEWRKa?D95fmEsoJbQ3C@y;fnFyC38(SylfYR+(U#>lU3{wLm@`V{AhM-4fTiO{$-* zrPsBJ(q@znJ17HoxE`$`ZLgKvora6E(3tT-Et~IjvVkP7mkL~;3>%Wcdb+%qB7GgnR?K{9kH^DWtNNPPuqQFW|v(@ z-P6^EIGKiZ2+}Yd7F*7#B!He%4!l;f@Luw z%}|ziofqViOMEgt0MES`wn}HqZgSS4{?<{kK?-EHb;(A{+SX{9AN9FeXt`u>7^{JU z&0>ns7oY5DbXxq;D)zn17j-zNj3zJf6-t@6$=vLSoOg#9i4xu{UO82z>K25CXI6c8H=&@u<63h^-Fjk3B=Zt6Xq-WM$W)n)40**1~*Ek z6a!dwyQ`hDccWdm;YJ&GZnTM9d@Y>~1)Ea&OKy>KB>Iw@x-S=sRk&#)VjW%SXry_w zfX;DOhJ*do4o0P;FUI87Hvk>a3??U&E9)gWnnsHZCTEesg)@f)=pLBc-m$#`%4NIu98Pi=XZ;+UhO{1`6W1U-O6MtT2 zO`@zsIgMp6=q!s>jag0Bqf~sdLR!wHepq|RtYpDa2x5$n+>@Qr zv*v`YgjR{S;_NR;8*wY1qntrgoUh?snpw3+VC=mj!NL)C7W1-5TxNyxam6lx_)A;R z%6pj88_3svP7^0w*0yHt7k`y;IV=HMx#pscx4QLuX160fnTw|LtoK-$%tc)yg-iWP zA!IK1Gog737$xYD??(t8JC@U72>~((J1DF7%r&DoC0k_xG&nfhZe_6`(OwxyK3S9& zOv5*G>F6wsmSQkl_CAEtXYLWidLuA+Y!IxQje5LTSoF2Ho0w%CQhiRiA;X|10>ZD; zaYTzwsUX+j29bc;97-4?A}WEaP|z<9BU*~mCA$Jjp+=E0NT|=U7Qq1bI(WOW&&pK8 zwHKWz8xM4h($j23E(s=FH(lOzjL;nMONO-N9#2(_we_yu!k9D&j9Dx{iWkkgIZ0b( zCO#KKqpfx;F7so#l|JJ_J+xrGcyNyrlDWGo_RpPBFAdM+81K5;CG zq{f-8ICDEiJ7&Fru<5EkU_6I?qjjg zVk-2)B4}&MN|a9gvGD2XL?=kHDVGqjz?asUKW4#7yKq9=f!?U9-nj4{moAc0HA>xq zOcdokGn@9QnWFNfnIjWIZjcs2Y(I#uQf^aEq$joUYjxUu%yJAR*{u zm&B@?r%z5+mDv2r7^5wjeAKB}H;MbOY8~s7%q{M+O5&7N88y~tvN+%2*BF#Y(zra= z6=hw492!k51WZgO+QE$5GXn)lI;lalcLJP>WrAnC3)W?+h;>an-A-<_swW^J?dCRQ z*6O-CP+XI}XzRRIwpcWQn#2r>(yIGHXrNeHvl=fYF;zQaz~K=#6O(bQjR;+q!@>$P z10o$iRX)h8?NQG>3dL)qYw#`B3tHJZV^rwE>7e^WXdxr}xIE0}?pqo2ea}0Dd zm+L0+q!i<0Q+1xUwmG_~b0|*KXeUG;xFp}_vl$#Wp2Qi|rH4Rob6^t_@sb3bu25ovMyu@4wP3rjMd6%9anwq0uB? zJ?Vh7Nl$WWMIq4k)MF4=1Bg=6W$z#7+{Ct^v686rx4*F*UbDr#?Qh?}ZN z&kL(0k)#LP#L=#XYZ9|-A;D!ETf3f5)7&nT9Gf(R8CQurN9?U-?veDG8A{HDTM|TR zO)6n-na$%)S9Z1*bVs5W$OlAh5SJJ$ckZBza{LG&+*!MZC(mU6%^KGBVsunIE-TF#xtYQMlIlLLGu2JqTmgv2y?#)n zwv)=H-fU!sL8NEKcZ?vFw=AfeTmKl24kNw`AeCn{LdX_syX<&zFPpZ8WUwp${D!QU2^sZ z>Y=Yu&?1P-*r8%{8f|7_l+J963de3vFb0o*ID#%>I=AuaW@)Ih`)60RyBUR?(;*i8 zLN557jR5g>XqBSzCu z9h6;(=?)O~E#Rz`2Y1nugV?ko#%N-iI$fhmpSs{%E4EiFR@1x^N9hcrW*ECN$qarI zmz;cFlPM}fh_5)c9h8n`ymFW;GM6g&f!wGR<#SvXzFGsUYc9$cxy=}S7%Ml<}{Au7dh>~||lnn<|GBg#S$$^u6R5Vd3h1ZjT)oUUl*IN?PDE^0nE2Q$l zUbUU_5gJ~B&R=b)STA#`pRas}ROk||kR*ZEovZq5j!a?iFlrDlte zAC_8B1W8jN_b|weao^8fCyfV|ki2L|yX*(v-jq<6rrB&{KwCnYm6t|+nxh&@7E(cR zq9c8pAgQ=yuj$OX6MHQwvr-T)GixKpMu%kANk*zUS}Rv*8@<;Hsx97S1-md3%CD!n z>xK|B_=hyuoPza-=V76YmLWUBObhyi4^Qr$4W|vnOKO!ae7>C~u{>DEVOyM4htMUN zPP=Ktir}2=ColUr{XfQtVk{6J%ZQXhG*C6@*lO2`u8u;D$OpNhR-35+&oI4+RTt57 zO|l3PR@gLY=ZSiYR$@ zt3A3ZE-pOGfo0Ct9PC38!~Gp}EvDevwx2DMH=El8bosorA0ZJ`Lp%V!UPFT=Yq=Ex z92YNWQ7bm6bTy$3GVPM{ikYEUG7}s6Kk1Zrj8LaK%AHCiM9ct0iaXqNIS6DCdyEy= zWP%g&*m28D(ut1ELW@EvpdKO?symM2x%xO=5E)5#>r9bSGjT^VS0^Obl9^#NpoY!{ z09v83&#IrU5M2^KlJ$OFz`$&k*<%8w=q0R*Uq-2;+xsZhE)+f2I!dY%W+RRk#k)3; z01dH+uG1;5s=5MV!#6S7)|ql`H>#q}F52hIm=M#4#caim79&g=rwJk*hK$eywS}4K zplWVn$;IUwJ|a!XXZP^Xd`1Xu9yg5_v3Y7k9VXG!Hm5`*<1N_e!=@mJr?~XZgUPH= zt}7~=#WwEp{SE%mwj38d^UF=otfm!_8SLcBaA&tzTevH_yk!UigF+j@;U2hL$ftMt zx=C)PifcOUT$~_M48>={gm>{_XcX3sbRJ!iMJ=0#8LWgoZMra%O+*r;m7KWz$pb@R zBIy>n6ZD zuWIWoyldJ%!|@6Cj+Tx%T6?x4cjOy-w*lSxOQ3+jMwcBO8( z>aH$UN_OI*xRz0GDrCjAG;JifMXr_Uk7m16-afkLok$aw=^4@$#@D+PA=2)sY^enG zd9-4CnFDo%YK#rR8|g$K$@e0h-!8)-wLKpCw6Q5m+$ z;hmB5kvffoDiuPuL~X59agOcxr(6S01Sct(C6W(n;E`TtMszmRwqOIZ%(@b-HDx;gLY*?A%TeHA1|Y{i ze%$Qi$36q%=Op+bh`Xh*l5Hx26h7JgopPHsLRnZE+tko2-p*X&`xSO#$m}FLPdwBH z^2-n1odIN*?zTu;B5^kwSJqcWSCdT9r!sT*69BrBI}Q-j4D3goCTVSnKXbDXZuK|BNxY1EcjIX?&?d9pKl<#8*dk8UYD>*FZmF=ZgUOri)z%!lb0+?60!0uC01 zV|}}Vo~>hR62q}7mjWA?!$aD*bKMIhrAIqZYf@tBSJ^Nbo$WEfB%#qdz=v$4s&3c2 z8kev6hiTu*xtlFzMr?GXG2GWbEMkcpzs)DbJU_NGr6nbcKnW<+s9q=nNT34y(<|1> z${>ANcy*et=u^CFB}+Ug-Szd6p>g4$mCZ@lOsJOTj9KwHJ3f!#YJ0XewFN;vNkA!K zJ)0A{5DpF=-Q-bz28Z}CK$6Y*iH&6AGBGw->imnXBQUWd_$Y?zvqvzYF!&xmhEs31 zBE$RnQ!ZXFsGh5FxM7^a!o)>^v4Tl(q=Hj!lj6r(rHPG$(>9HQS?z1Ly_EwXb}ffX zzB6lk&nVF-$C}1V0tb#InBIOi=|pcW1M5^VRv|NVdcpMZbR*piKgMKoLAP^f4U-V{ zx7O{>U1kCJM1?L58{%iUgP&1;e6>iMy8$Zg1{au^jMw*De3o<_1>KCv8r4=G5~xWA zL6w<`8XC)Vj}B^=O3SvaBde5oFak3(w3E5cj*O@t5nW0Ta*&C`J_tE%A4S#b!5Lq> zBgH$l8IANpMx3FhXS%^=NzQ=zb@vb%H|TDQwVge#O+hP0$)WFIV2#qlxYy(A?KBgj zZ>hMOPWW)Kn_DeyupkPT*(Ww#XCc1B)e*b`#hbEXh1f{*+^GgEYTOV>H>b!&-6z?N zf3>-nGyNRtADPWJPT+lPxyhBO`r0f#Lvw0dFJfNq&fwZ#m>p?ij?WC^v%>nBVLj_0 zzAJ>?9&W>3HvA|+wy-IzwVunGk&B?!x_k!}dTPgKNEtyU6|7r7LcurFU@zfz5f7Ro zx_!=15sJ|2-YL7F+a_caw~@IZVUGws90(LvcPfa|*kzhB!1bvBY%@~PNK&!ejDfU7 zc8N~(WaHJIT&^YQtnWq8I!I`k-~2Nw)-st*A8gaC%$5XSkwZKPNnrh?G+BnlkI0Fa zf_-o6<-{T1YcWBsH>$GiZ&>c#sH+8-LY(GFSMBsL%z%gPl$kRn&a~|WaaI5B8y$u( zp*L8S+r8>$f*sd-hA3dIlZAQS=0jeL2mFnwx)?o^B}1Q7IZ1?&tVz^t%8qO_(mT>Q z`EsYy$1Y4%94`Tp)Y$I^=_u+raYm+%s@~8_L-2L(q-MC z9Y{aNB@>gIoxU&v!F*$3MSmp+G>e;cl~H`H%ptywi$p@|vdEmvwke2}JN~IWeocSX zs#CqqDpQ8S7%9o%8>lkD<(AIFi`2JrkfhBurOg`8otQbE=`eGlEKCf~g}Jlr`#ACF zj%`_$9pljyLoVCkCQO8&g*@XUvp9K4UiMYpWQoKP39B8Yiu&7`HG0zkR6WH~HQSk? zOjd!AretPY!6KHtdp6r^F;>rr9GU;&dIp>s)P$&h67`M6A8Hq=OlnPklq4i>_F9+l z5vqLfbr5)ReWg*86$)oE!2?K+%9Lr>X_`(t*SjF5Hlt)gT1H3p64&ibTh|pDP4F!*v;kl)JesrqU6r3=@cSgqQiao%N5nJ8sJf zA1GcRQ~-47oC;z^D5Ak4K%!W8u(_8bk~b^4h}6RyT?;Rue%3{+h(b*s*}CXG}AqZF^cGVr^~c4kqXcTXZUob^su%#=K}1ObB>Z z9*T2JKV9~rD-UO}EV=;-(RhPUzbf>vd^pyikK)fb>OsaoIHE-f33JE^2K>FQ}W(wxnBK zTMMkxX~QVGA+0jA9S63mNm(q64y;EiE)Glcqs!1(d#HFk?6Py0_}XE3qxwvrHuzw5 zSd1#cjm$@iR@?1x}er`CJC6b^6s~IHHdsH*<(mCfV&mDxTWo$}A;MIzL z4!QI+noa8BdGW_EgtQE2Mb~C{~YK&-HC|Y`7e8Acw z{M)NR(j-i`xSzcpu=^I#9Uv`(EFD0mw z_<37cBk?c3UCiF4jA;9HbAKC*5Pgv;MC_f_EZnX>OW}kNDk36jyPFIreFq{s*ooRo zCp%}aHei~tU5fV50Fx9N*6FrlzZ(+SPJ#4nVSdE4JV6L5KUdPs`aJv?*5wGE;=j)ImGyAr(Wm-!&zHB^(S*r2eX@L&?LGsJWSZeNlzQ`7LR>>26BPD7S1d zvDv|Gah8bO`4kZSi5*S81fDhRkW9zJ?P2r3MngeR3aQts{W*3id19J zGLD3SVX9YEoJcq{fsgGl2h|~>Q|l|UekxcM?j{`)rg>li%}ypH+s~96F|6$?>byK6 zO$NTim35Zu7+i9+tSae4N+11@xZ~)wk;@RYt>)Tv-U&^Ej(gPV1_re~IRHU|g;gzb zCk?lV*z8S$>-j>x^xceWaBXJTwag*1++IV`g18bp#FEi#^BJ1_x^l)>fzeq)QbwP9 zM2pFwovraIM8K&Hd<{n*b9`*2&4h+wPyz)PlW3#CShWU;#So~f%6*0z)~z67_@fn( zEmzkd@__9cH|ih(mnlcGT;bE`QhA1)+IFgX>DbT;EEct-MLvtzR_#y2phC@3Jh~c@_w5vmR!b)2y-J}D;cVIUSPUt4TCD?` z$->aqq+s+%vp?NPXD_(E!b)`nJCdpkqhFduox*tiNvRUMA8(RONdsLQKhk@&6aI_` ztx~1QW3qM^u(3|bb#88VHF$uXNI{R$flbmjx0G&554VZRU3 z_Ue>aYuV?#%x>&M)KtViN7|b;qi@4TPnb%2kKI2UxRuOTm~7^=?G`NrjHc2#7F%JXB*5ki z0#7ui2%|L|%!yyq9=|71cA!m zvo=#-=Kg0lm*RCh!_OD9ZdGryvleA98e#X32C6MLRe$D7{Gux|z|+989aw9b)7j#1|aCI^Rt7oz`H5+Zr|Bjnt?d zYJDareMg+nL?sjT%+4uCA7Li=lB2PmN#LPHpoJsjh~C_&K_#(n6dd~tzOU@&=mBpC z|H+#=ZyeKOF``Szk}XD+B6c~Vr^36M9BnZRZHe3+O12i8X}m=31WM)CYikRbb(X$U zWuhnb<#@bEoVq?A7&i{>pb&B;eR3OF9qSysw-G*-_uIKbv{!Ytc4k;RE3BPOWI8!U zRJfGPv&1Oc=<);NR3w`f4tIXQ1F2gxs$!-isVjHRw{t0;X6NbQL# zCu@q#D|5c7&xvB+;UK}vifUMEEv8ywOqfyrS*f%673;G>6in|MNm2Q3rt zXoto-UzK(VjLE7j5XUTshjn3>v7pLHRP|)?O*)^V)5+E6z*Iu9XVQhS<5_WylfE#W zUUB({m}TvFXR}_+FnmLSD{?k?_p>u1URX1hWn8m1wFXOQPfDrGx`jhNTo%aTUpNZC z3EkNZ7+vV4iBsSvpe=*WlzGp!<4iEni2qyys#_rwnS(o%{)kUU{+71USrzN#O8FKb zOE!~jl!e!t9kQe|QIJ?I|IK216xm9tgA-pq#XDCodx>kX)wN%Q;u%LSs>LYM5>##~ zUaWA65*LpcE_%?u?rH`xb{Uf#XMW$_iWcqgWl|iocr<3z+S_|%^pR}K_W#P+*GLmg z(W+dxg2_vVUb4cM*=O03qHYkzG0x5z&6_rMU}v zHDg*kYk6x%QGm=$pJjcR`ja}R6^%YbZDm$BvhL+;#x_}4FOIa?ozc?7XOuPW29tKS zj`GcC;LJ+gCAP0Uh(2*@$%czjaD)MNzg?8CnunMx`j*7YTL0VA#n-+nqr=I~R%m{) zkgpk?9@fQAx)aukrRtf*j{1xizi901Yj!qF>?TLfr?76ab#WB>m1&gLrLRuL%chex zj`hqtO4rk;h^cU0n}U{~)Lmgyxz)o@9gy>^Tf=T;X1Ncu#)B%@2jq3wqSAq>U1K>; zzLb(Z@qxlD1oM79N7;b2*;guet>dsQ`s{4E%jh7ieVGdi&YOkNRoInbHf#}QLq!?F36iWKh3Z1={9I}^^ z!v=9HFl(yAD4x%TnfoYTTldjB8kg*=*|DWk_;S~*>y&ya6Ot|?5btw(k^fqpGZZjL zx^AjB;_xM{u@8g!eO~S) zSJ1I`s5J?k|$1R$0V@hj<4P>^kb!Vj0 zaT{u&eFQo$v9ljLM9U7oKw8`BwoPtKNk&9I?4v1a7FH?K(dK%0$uC7BjcJISO%-Z% zF)Jv2nQQB4d?IaCDBQ_7g9tf-5p*?H$p-y{KsslTxk~TA7m+0=(?v%a(be#oYbmh^ zR<@_FRJ>l5LNwtPt3-~`=&yC4%QQ1a(cLzfjB=h;a!y7$&n`J*WDR21wTkp=>sg$m zEfnDgOtkL_SkxXV##v}4Dm=UE&m~G9$Q>8j9bL-~&W}WELmN~6B zv3dR(`5@&d)bi|?n=a|#DADLa24O3yu2K87^H*?FeB4Al%g9kjv=THK)=7zB3A(lR z)2L0aC9L)8wF`{Ia+W?a+CHmGzq6S|8CCk}3X2N_{AfcGH^ ze8Taa>+7|Wlp)Mx(PQZ-G78ffWC#t&o4APDl3L0B1IK{%DFIKqNtb;!Xd6)%cl3qj z(1y;T6_^@Wn^hE)p?2l%fg)r4Bee4Tr(7XjcKtwApJFi2r3nwSAW_t0WpsYC`w(A11jKd4^Zu!N1Y(4^m$tNck(Lel~rFlbs~5C3gi zB`&3DJ`7iAYP8K^cTxCy+>0ZYP=l$jdpT$!ln{qg_|^UatfmDzbeMW&XjKw1{c;M3998Jvw5x?A^JofQ?Y!P%wB?MudsL#qR$fBnrm8a-}nj(5qCF>e`=EK z#fsd5=q4We%#lO8);kLwg+AG|=^Oe6@FS$}h80D?P zVV*WADqNb1Lqm*<@_3Z<7Lnx&*LoGd!lgwb#4TMK?ZeGk54KRW<5;B&ZP1&!sCjhx zcSU3?SJAdwOIElxazvSVvoa`YaLZdoxCUnQ3WwFqrWFqJ;@4Ix92c?SP~o7jq3a}T zg=0hS7Rkvan0pJK)J{~z94d-x1jK2S+)Z*-5qJHnMMg4OTm)L-*9a|OZ`Vdo47Y&o zB)6kV2i>U%uhB;bi^pkYYd{_kjTr9naaj?%8IDS-BQ5$ebKmQDg%ome+$*dIJD)Fo zLiZ}%(#WfDTwuBu#mbbDV^)PNrZgb!=8Bi8W#)~ol%hr21_2fg8fQIIJvP3 z7o*%;x&(9gMqACTxfLOtRIOTQWUYJ{C6A`!_*P$_cl(02!naZP>lE9aw3J6z?$OZJ zzpiaKtD?bGm8wXQ85mAWpChbnvn6dBllX0Abgf*qMLnofSrt`8 zo<*{imRb$PHwjh68>&aqyAX+9DEO;B0WKNna5~&#>bfmR#k3|U%=5KDp_${cp|G&I zLtIZmOvI|~MMm*@M___G7+P?T?Jl?!@#RdjoyG=7E=-W_Q;J=nrRyhk6 zG!1rkmx9gHr<^Pf_%j1lzTYQU!VEa zvx#kQdrDMCH%G>075jK#5jSA1EIb?|@N@f8p zlH{U(m<99R7FMo{hE*Qz3YJ)QS2yfNwgg(~Ul^-Q#|m!jiBaDcmP@Np8(RU<&Jroe zbvW>TDdFZG6fD|HLtVL2sjW#oJm0^f>ZMBM{I9OP%z9|-77O*|q0HMD=jC=Wm0E|J zExgK&Q*`5e|1gxi8~xi*P6a%Ci&T}uSfA>7D8x9dbhhk}!>q^1FiJAiK9pi5OJ(dWCMiwY7CP6m0rQ8u}2Ia&DYG!qh77h{t z|AtqKf2~Grkw+=k*cdpiW1R1${q-#v^S9NFezbm~yvtY}nS!#p`4?Y2B3t^z=ob-~ zBZX~!F>6}4Fm&~?5DOg5+3LW^k=fFGss)e*)dIpzOYELg#v6h-vcsCk0z?P5s9jl$ zbww|AgsjbD-bRbY==-C^WFn)*^jvMaj>Ul&y6DV79>)JNT!O{{xHKjjNXk3^=RXShDDusE7 z4!s^N)I1+9AwJDbonWEeuokoy8T76yQv>U0cgrY*TdfvYo|%G`y(BJx#@1U|Kc%Ev z&e>Ydv%Q+DvQ}|bKp?#_Gh`8)%_`3#cdJwq=o-2<&>i9ksF-QXGgIkdiboYri$-Zd zc4;=_#_L&h_0asJ)V3MFoejDz79l=0G6Az(!E94+dW!!HV%6o45dnHiluWRuW=FNf zwu=MP`RFjiR(r>EtpNll$-)RK3~PgWc3Ox z*<(GG95j!YY|N8I?LCgHFS)H48)#(sAsZ>VLAW7BCA$%>k~OtX$)#nall4@8cjjXG zj67Vu&bAfOOC~pQrxFWkM94T!#4NUJT3CF%O&_7KnCtX7AVJi$rL(R^5ZxhpWbe_! z!wey6Z7WWpQ1V{kM@LE>Bfb_2$1^9eFfO*20@M7q9klrPayKYP``Q&;rZ5JEJeXHWxeE!ewOp1vHXr1ptS?)&dZsF#&xLH6r;;n?t*1zR(dcn7-4M-QH%f&Ynk1g2#mqJfn%&qwGex1N&%-XxHTT5YNbESD>4NPHMU-Y-vxweXoMZq! zj^#_|d7$!lWBi1iue&YmJs5+wHm&KozQoLMTkyt>`uv{qw2*7>JU=U-!P115 z>k?*pjSsVwb1o$ZJFsuoMl1LHA>K24R&@xoZHcTHF}Ls`#b_*5J?;(qBpUN`^n=TR zb&M9a1Bycf{dR+JbV_V+3bIrhk;$@ZfY1ZQWNnI96(qZOon&rm)3*#1DMBoEF6OZ} zs4MwAfV-)CW~3;PR|Q|@H|EF)<3pFEO5v2VUg3_J)yM{tl5&UsVF`dTmu6U0wl0_{ z)KWvf6;sNYH(6O$S7>{au~!PRRN{bM?VOa{R<4rWCD(0(F5yTvU!x;1W!^3A40ty$ z*^!_4#XpNsu+}n(`PPJ%GS{>5mF#A*;v|yqeriniDr6GB-&UTACM` z^d(!gC*RCLnaC{3*OsQrVianXRqFALB70dz8aZ%c*%nDv%}JWo$mRV^T5h!CNM8{J|)KFZjuD0VrzTt(AOrP5^kPW5=iEYOE=G!^nu|75(GXI5$5~K@dA!)D0 z2!nm!i@h{Ra&m7(t-$<}13qbi?CYa!URi*tbs-ydarG?gg3*3wj!MoAO|6VBBwB;s z5$(0)63o`%r$Nl@%(1)M1Uu|zAAS}D77uNWj^Nvnv60=vx=7n&;@jdT=l z1|+3Nj5CzX()&Q-;L{@p8z15LmR4KAQ?D9%Opzk~%b0<6A|fpAnAb6~07@<&ybJ8|JgLwL>E%0f8?>GkJjvQ_O0`)I3*Vi}JM!H?I(LLM&&jB=a~+ zQRYU(o)uxY=4Mo9YY~^oQDr3AK&yzFVwWi^R(O?VOLF51zsUJlxTyx&IMl{+ss@Rm zOo=hE>aXD&l`dOcJ@Yl<2<5W-xa9*aV6aDv(E`n1kP;DC8J(-Q-nw%2<}PJ+Ga3c8 zO_7qdv`Z;TlDcdr(KQE?3uR7>Ryt~=8JT}JxHA`aWA8k*p~gH z0nL&kqHT0N!wM#nT*!qyf7S7CV$fd*Q^Ibb8uNBMr-bR@tS}xf!D~vGga5{`al&BO zKP(EDg&V`8;nXlA+!r?SyJpAn2?XHZ+%PA1S#Gy5v1${xo^V!fZgq3GDz`DrshXHy zLrfd1E(sf}<<}El3TsGBDUk-6RHshxwDnsZb_$0R-%gerULd7ga}zDkAvc}(l-s%d zZpUvmX63y)3=-~~a4Uaj#ouvUHikv{8%bxk+>G2Na=$6e<+&y|7_KDdD=FWM3AbXp z1O(nxjr5S~jd{g2j?2^4D(hf)khrE;X%El!P}ZK@Ih16O5DIl`*qFP-LQwpl~&CWi4U+5F#lZVoZ3t)}D-CpV;> z8w^hq_oLzP+~F4IqqRMRP~EIKc;ikpcDgcu<%GG!R89F7k;*x_o^S~z->rH&Z%*fL z3V%ISoAOh_j3d^B-Kyr`cI$pG@jHWbh=_b{(t|d?jNh|xn_E3GH-+3C8m3gAQ*~cvsME{Bi@6tbC^VYeIeG)1Q;BIJIEVNaVLB%);dwXDbEwyI!YTYV^N#9f zIzHpPy%GCG*v=yLHT2r^D2eKFB552>4i{-qV4t3^#x_pR7^j}c@g1bLcjKLA`bbJXwTE{$Qg3U*UiL@Hd1ngkw}{ja52q6AoNyn%fwXqh!~UtZVh*a+cXuPEo%m(s zkp5oO!ge7{m^fkjghS2kEK06gna-c`uoJ%%!=|c7t3vgrst2oHs=BXg6YxLP(p>%y zr@RwY8`Xvt#q=7inyGjdb#3pvpSjf)3!s`WY4m-^2le$V3VK&?)sPcF*MCEOzXXW+hw zG$FxMy?VFgDL0+=SG?*K8garom}OJTxXI13E8JNigq9V{8{VAP z7|W}6K`v|`sz3m_FbVg`U=nVVXq_D}=feb0LkaVt7IQ7;H{hSlwV0+7R#dY(Yy-9h zlfsVt*5X!+TP<$2xb0*<+mXihm?ncA!p`{ZO!_;MzWQGv_B=5Li$Qg|GvRgtyYjm& zu>_FAyc;gNW81^RSBE_bvlp1g8++qdOPGBCG%xH+xHp3RaNnP|4&bdC!X5|?;{6%m zV9a&IatN{15X+&sy$Ku!RC?v<&BUzO1IQ8k;lw_ZoX!HX%fcUl`ABdSI2ud^bFzA< z4#!}A3wSGd8|l5B9D05yhj$Ryv4mIJbHO}NPwscH61He?CwvEC36s z9~zlh=v{PllW{qPu%-X8_)Xx+)Q?igu|gY{qo zI0L_TgZF?lK|Sfb7n}v&XKAW0)loX-NB!rJ@P7Ko2k03eq;)<7&L-T4!8zbednX@0 z!c(;EqddF_?z=QvfOuJ`FyD+ogp0Kk!+4 zRNuG^d;wezzR25OqE~(y|0}>(fGF2j!Pj{I>);#Un}q!q_%^r-d#wu1J{Eaz>VO$Kz;ao;3n{Wa5MM;xCPt_eh7X9ZUeW2JHU^@onRCA3HT|v z3)~HU2JQj(g8RVF!TsPD-~sSU@GJ0Z@F4gN_$~MycnCZU9$^I5@GQ^o@3A*fhsQE9 zMZYxu9t9d#j}iWHM(Z1_uIj=Q;fU}g;r{^sh`;*(Q{1^NWw^zWc zAmnO8E;lRWb4P`$+|kyjs&mz0LJoQilx8i@iC`O0Pg>jN)c(*~!fnSu-JUomW8MLr zN$aUce~I>;g8dDkp1yKyHr}A*gx?YD1a=0yfL+0EV0W+wm`412^4v>ius7HTOb7dd zH-i1Z{@?&`AbC3o%m4?2I&cU$6ub$j9I4I^BmA4e;b12Dn+0YQ<_K^kP}1nSd@DkbS%*`FQ@4A zV#=YhcN}5M`>n>=@whDkO<*Zl2AaVMU^!?3E5J(n#VX=?o_N$IslTqqZw)vRoCHoL z%qifV;9a1Va-Ry?Fc&~O=m4Fdi}2l`2Nc0+xUB`fpbzwe0WgT)>0k&9gAp(a)`2lF z4%UMW;0*9?@E+bflXTx}ZS!XMU+64QJG|f8NA31@tHTcv{)6B{;B4?=a1Qtg_$W9R zoX5N8gO7m=z((9Y4n6@c1Q+GrK~1YopslpU#h{Vi{(-Xg_!RG{&C1*065jnZ_zbud z{2%x%_#F5=xD0#&Tn@enz68Dut^i*FSAwsCuYs>qo^OzkZ({xy_%^r-dB1FwKr2^aGDkjq!|$cHLW4JLq^{NzxZ zpU3===697wyy5O)V!i=Bqyb9M5OVaIZ3r(KC0eyD=1KW-{EYaBhQ`k^Wn)7Etnj3CjDK&u6fa_V_7)_;tyeW;@<;key-^?L0|@94hD7L5bTHM_aWxm@FwgYN1k_} z*Vtdgy&jHo7Z5;>{HP8NGk?`Zb$B!NdN}r(U>2ASjsQo3qrlO`GY1?)I?gNS!&`8F zEAPE6ztHC9w_`tyyr}GIfoX89T08h!qc*&Q_m9ml#%*$#n?Ekhgs^i6^e;j_tgC)e>gncR41G8wuGTfWN3Am*) zF2~%0{|d0u@&b(||En-J^3H0)uK_25lfcQ~6!1>)F3<{2Y;B(;fxT{ZH zX5rV+my&-7U%>5h{HL-qff|G_68FB8vkLo{c=yX-s;zFI>4f`AO!IQ;p_;UR53U2( zgBw^mDefzI=lqza_hYT3s>4@t{~GmN121xMjHf*B^|sPtp0G4qEdEm5N^7abQ;q)= zR$&^epUQ7Nu1oW+L2JWrU9ln`wgzu!@yRDqp67ITK4%P3>yjEw`;d*l~vOX`8Vv%>c!wvbaa3lWT z#ZUc1eM5bup1S=WZ9AF2o9JiXBcAVro52sjE#Ox0L+~Rom64@BcQ*BV8}{4trxCx( zx0W`mwe-JZ@%Cb7&4GC;t3!hFl!T?f%sc?!Hh}AZ#i4bY=FcD7`&u(=ofyKM`9a!j zAZ*GX9)1EH`6-dzMVPz6&+=Mn$}b=80XKnr!AbPf`|^{*&+|jnmHeI8-jUGv^Zudv z;mzFh;TO0+kROR@vEHFAenniGXMRmu59UX+cYZ@yQAXu=DxB-~F^%7n&hNlO;9=f> z1pMCOsSS@3$7A4epx*mLek{h94^LV;%+tL0$NV^TsXW()r!4Gx+S2V$WB-$tk2Mg_ zXTYX>BlY^@$uFRY6!4(4^t^{l|R zi{<(!{rq3JDc>&<-@n0sz{}vjyp!6ao)x>N!Mso2Ucv8Gpt+Mmkw33b)myGgH0OP> z4(K~&{#8})ht{Nalb_FlUG#?(#}v57onNy&tlZ1uQ~DE#qXyIh%_9?eZUeRjlfZUh zd(enPA@!-rRr#=k<`6Y>|3=WypeeK1N#&A0pP%@ z^TR<^AB*w&do!vo2nSbf#2xvWg_m?A)nj!y1h;ym9ikJ5634#z3(YJU%$uq%VwOr_ zy`B%F{ObQR^PdQB=H0`2XC_b4kXcn1hS^o02uH{cjskDO|7b7=90T40-dZ&&yshe! zu{|#iZ?`;Fhj$SESTHxHQIDi0wYlVdTB9p%jSaQmJmRXax+L~*=Ii)gBkuF5>no7Z z`1^23*cSrPtwlT+gOlhxGxMK`W9!mzoYnpRWqthks%c>f;hKnVDRD2u+ziA+oWOHA zXaO_xpUv{Q0=vSm1gkJFhL?VlG-u{N7u)^wv0YW4tigzDHDT9)6M@Qg63>&tDb$6^ z`%cn+SJh=%A8W<^RL}-qA&vrJHI|f)c(kcVoTgd3T^`!2z8E?P*9p1^*A3Lad%!cK zRpfaZSPObV9}sQmC;R|$4uaFc5Eurc*(2m<6s#l6gQVX@JY$&akzVXz>28glOkOz>WC7Vo@|^xj`}c=!Nu zeh~AAa66mlhpVp0;y4Glj}ZQ&;9Sh-f%Cz~{y*dRN*2cp)WrqFyODH0{<`n6w#ENK z%X2_{sfJ zo-^~`jPB|e@Jz({Sx^tx=JbhmF!6mJH1bZOi&a(Mjx;!g%ZTR--~sCXa?12Y%wOX9 zWu8}nCU95&D&qHcP}-9Fe+Bm|!B@f8z}LYyNM|L_Zvx3AzlHtV;41JPa5e7xA-zmv z@EY=ZEvUlpI%vT4)Rp@8qTJOs?|Zvfj)@y$7>$9M`D^Ir*M=KaX8OpX`D>B*CO$gP zdM9t|o$tnXzQ^+>@O>a&_Ga?)18@s?j``+R^6^9PBXAqI9ozwaT(wWQvnuiA;;}Wi zU&DUZb=1E&!0Q;xF2h&-tfRKY>->a#sa@*fJ|`FldOhLbPjEj8|GTK?v$Oo(5bh>l zTC@EO|9il_;6C#9bHeS6QAbQN2`4O`WSYtn;xf(;`^WA`6ST#^$$G%2(*rUil^4hPxJf} z_%nD0JPV!!n%kZSlF7b6oG(%iwc}rS{uTTU{2lxQ{1f~OyhOSF4gN#;m%)F*|G+Ci zH1Ad73)RR}K^|0rYA^xRfLbsSYy-BfW{nTF1KY#&PX;?+?x8KFV15H(rh*--Cx@ND z&R`d?D{i|Hu9|+bJLXHMi#^!i+_U=Tuov%51Ckr>jo&_mpAPl~Zv^{Q{{Z>qEn)xa zx#0l99S9C0u6pX}g8ZdnM)j@X;OYxP9XOK}z8 zNaM)r8R010j;_8w%&EQ&j{7!BaGUj+{izexv*eo2N2tFgUV=R;(pKMj3-Rnybvtv) z?Yw)ty?ZF(-b%VQNAmvL2=jHyta1Ey^8F6{j;+2p%%x1)S5w=~Q(3?y+NyzPBbW~s zfQ7uj2rLH2f#bmv&;*u(WuO_H0G5LmumY?EtH5fo2Al{^0w;r0z&pXaKr1*Ew1Gmk z_DAjr?U*~r=Y#OSoz*{Pj+e}dxd!)c@}xZXSQ+nRtlde;?xgHaV~f=q7n`6dn{eM` z?xzuUE$9VPp@w~g>8I`os?QC(vJ(`5-q-jYB+Thx2n>S}FbdXzdi)iS`p_8pn8Tae z%NwU&*Mkk<4B~xv^-sckNaM`vpAxTRI5)E^srZ@0D8pIceZ=#A@B#2a@FCpJ1|J6J zfRBKWf^)%n;C%2gZ~@o|J`O$sE(8~WPlAiVr-o|l6!f-iwDgDb#Sz?I;u;A@2cI$^)T^PAYe1-^~_D$+ZH zG`_?0YW%JN*HZTDuwM_BQ|=oGdn5QR_#XZ@f$xKx!4JSK;8yTM@T2OVh1&>sJGg^3 z`Z0C7XVs6xo!B>lpMakd?_JgRSpD8zeJN%9O!ygY_W}fnQ^O5c~%GmiK-K9s&;o$uJ+``Fs2x1&@KptDC|T;7Q8-2kd_YPgQHK$fJXU z{1p5dw`X|oS)R{<=P|zk)b=l8{|opl`TiSjN8D#Rm5E-g9reefOk(Zlbv zas49m%$x~ogM2uKINmZrYqg(4Hz$R+PGCKP-`l}Ez_DO1mbf%uE#Cj5eZ%j$4E_9dVRECtIzGdKY(2Q6R)SP52`U$Ig8{jzzP6tC^7>p3t=!9Q~brT-6d1Y*Z^RVMQ z#S^XPxdEI3-c5S%0cY~gd$FGd-UlAY|0cYD!f(R|Cj5?ecrbhrxBY0JWzg1I=AmlF zr`q~Myr=p-8~+c3a{wAq;Ug0sLWe-_{XBe>HaVC2KX1YV;e7I^wXV}6XeRaxz((+K z@QGOddno&b#C;L?B)AxS3cpLhr@?2yrQjLz^nbkfS*l!;7YI_e3iU^4SXH{ZvgRU-^Be}Ks4*yJg)-Z0at@-z_k;04A+6{ zCrk}DOqd*Q#O=G_d*t^f@O^MI_yO_V!t++}L+~ST8{uvTcYq&*JHaOK6a0P(?!tUG z_!;JVz`f+{KH~W~Zuf)dsOMkc{s8zTe!l|01`mSY5bn2x`5kx&|A)aNn12r*#rzo0 z$H5bXdy?lLz#qX=;A#B-1g4?E@n`&>!Tc<7K1W}8e!|1_+lOiKhpj)pK=>EIU%+31 z*57}#cOSu&H~E+77aK_7@3{XX#{16+zh|66Q;Ao+Pa{x2dM@`U>s070;rhdj?JP+j9~G%Y*^e@@)kYrvL$h5n2CM6iv*f>2CmOs1<|&|(7DJD5o65U8f}Oz5U>7hgJPwcaIHh~s=-p|| zL*f^w;yxI%iH|GB+^JgyMIR_kr|66#zmFL^Q+rc}qA6xTWn2UKH=4nVJ zq?M;WRbRs{B<_u1K3D)2;C6<7_{;CCYKCt*GroI;zuv*xMrF5Fwesra>l0)FkF19K0k&9gAwX|l;=7y2FAg9umPL_-VNRZ&IIoTXMy(-&-=j#zz4yH za621(7@Pw>0zL}PrT)$X=Yx-d3kbUroD3cOIQjVmxUlBga8b?k;gdBl(l^l!Al#?G zCE(NGGvHF-`xesVK@WhqKMOubTvJW62fl|e;^!~pIfs?b;TaF5F>!DB0{!svn#tjd zHTQ)tQRXj`_7&hO;7agS-qZZ|HJ)F$cwH~$8#UrD{uaJTdw#3t@8R1u43f8`sYW#9vGDzxzl57>w2uF4_(9D-!!0#h zJ8m0ptx5CaVc~~0{|Y~j2-?VqBettXY++lfkeW!Xf znGVMN$Ar5RYyv+4KLvMzyTQ-EJvEKt-kSe}`)XbeKd6 zzaq@9!GoZgar7IWzXiVo(qDUsHh3630`3662ake9gnf+sJPw{9?2|nI0RD*iDeyG- z6ZmsY$Q^}d6$)1TOb*Xb_s`<~9ATg5nbLiMIA64QtHWOi^H=;I0e8@jyMn*f>=^z| z9sh$m`zLYUN7#R5?TI{su>S`C0WSm5zTH{N_fm%clFt9YD?nws0{>S53JHN?1cHSq zt`N)3e(q$ZipilCOvJto_%y+{o99~=M<1P1}-Z3Z|P)Defv#wLYB$k(CZO|`p(!>Erp z*Vg2wyl&jcOKNL#Gl^qX?Zn({;#1j=;CUoCia3t0-6l8rb>rAJH;48(hVYtO-$MH0 zCEv>P<(f%3w3J_?ZWLDOY2HvAD(iN+D%058j+dAhYPZjAv-S50J2||aG~Qw9P0sDO z^>FlM#hb>g*X6OKI~UB0d9CMp2Yt4|`pyoy#@Z>l31|k+r(PC-gf|Xw^}nt#&ucv3ssyWvUJBSsk$Vfw=>8 zk{`*zyNFZ#NH@rGbPtsyGL%{Ez(Q0;=s^Hnft*2@1I0GgFH{?-61fH z`v@2X>u?_f<6u45KpxIuT)rE;2mdp{dwJ(9@IL(C4?ckTQ1+8QNZ1e6?wQ-x=9Wp} zZ2IPh!8za~;G?`NUh7=Kp9jvb-HWhW>wA0VK1RHrPv^TXsGSD6nMO@a;|0w*d*?P1 zpVn<3C$3M_?t`}D*5VSaRR7u~TnMD?pf(rZd=dGTTqDgDs`GZ*^^>)V|Cn$w@qUUl zE&IB9 zzV_eY%395%2hcawU!7)X?0psguL14TAe6Sc|2p<>5bm4Q%eR1Z!e1urRZIr$jM3iO z1IgEcl=(nqE_|CXSAp+kzW@)^)-hM0e~90&z^}oB;5Xp6q4kXTY=IIq*Dq0lWzQ z0{%+A{#JWP?(gK`AEftBP)}O_!u}HJ{TuuTyj*)&?ke0L!u(&LGX4)Judjet0Ze94 zA@iULRD%hi2GoLyU>mS4m;|<)ct~#hiHGJUW8MKw0dD|P!H!@jurt^N> zAOR{v6{rf;pgPomnjmNSYC|2U3-zErG=PTC2pU5oG=Zkj44Oj=XbG*LHGBvkK^tfb z?Vvq$fR4}!Izt!e3flMLXjk)9- zHH(h&Pjra$8_~L)HQUMa&#()Af!(mjmzD&*sNR9Fdx`T`kp9;`%>Bqd00-eWI0T2` z2polDa2$UpkaH4F!D%=HXW<-fzr%UB!0(H2iRa631+Kz1xDNAZpKjoO6K=t6xD(14 z1n$9ocmNOK5&S{ikMZ*ap2DB-44%VZ@B;o0Euz1~{0CmaYj^`J=2 zRanb{eOAcE@9fCT0n(P{B@ zV)?Gd;uh<;#o@OcZX1{rRQ>hhdP;gRw05|c(7mpb^igTkNKZUeK(C5W2@;?(VXHWC zEBRGLMu2S^-veb!#MjgHM(c$xpOA;W zT@~o#(H0Y~5A=n8&>xob?go&)fv()zXXMi$80<2&A%qqqii`tYM%3G`HhwbA?@=c;ls;EyR+;~?N{a8>XeLC^YAfA~nIqz3Zj|RSqgtN3+q*u

    pPB7p21+r!bWHN`vvz%F*gE<#n=fQkffIbW1E9@7+Vsu;LlC>^1Z@Sba zeN`C;N;>Gn5@wmJn!X%Xz)JFem8-hG8eP7@P1bnUV15g0vHK30>)?A>kKG1LId3WF z787_=7lUe$$6Uk!G6%B}nVVcsNS&>1c4XVy7VLf?PqxC3gx?0+VF!3g{ZFo%$e_(f zzRb)2OnP>?YEido`?1>%dtfjAe}#Rn+Ris(KXwP;Ap8c0aC=4G9mYK3s>6Gh`F!bf z)^*UM_EIYZ!)1xDOdIMy+&pI zG&0V(qB_jtY!@{N9g`4AqV+aK^4p1@Q16Q03y_zUFh%L~j@n1A!$ zU&23xWj0!W<&ymw&6z`Jj^54xLvPlfi9ZCA!n^xzUn4_wbAu-+l=rIg>@^Vz1^YgG^ct@N%k-6`jC5hb86*W&ekTz1wW-=&1Jj ziG4dKE)U^tkhFL?y+;%7gb5S5U{XJ1jw+H3fuE~Daj>wfT@_vIgkJ$+g z<+u2uA3)sU$PpRw_(@@QcG8m)`v}r3=Ob?!U62u}rNS;Xq%pfPp6p82bq&0$v_2iv zVWx)+pz=rJl07xu^hi^kz0bmY=vvA_M*Mg=acKF{B=b<2u#>c2!#y+cXMwDc4YETH zv%B-oa+*ERQ|4*dmq-6g?Vaz2Ufs~E8-BX!A0W#=XO)X*(Mj~o4Uxnl>yt{ip6J$9 z&x5_JN984+d}c4_eaL=RFTV3}3Nnn-()sbDWcurn$Y4B$eL*M$gOL%1Ss0{^EJC@6 zHhVj5R8gLbK@7w~aVP;Lp_KV4-w~Dm(&!-XL-Z_zn`(!pUGA-yMXu-|YrS#?G|ucp z9&#R;JX5-fzSXsIyeoOnUc#4$H(r1QzWNMW$r_Ckn$?!M9ROUyE^$LZBh-w)P!14oAlQ)2hpbc zb)e5qTX&7NN9w$M`Q_YrUD8v}984-y9jTA32G9^0ji51dlAA-EdXq@Hn(#X{VVZ(^ zM^Yz-I(1%jk~-{uP?m%3semLbxPww>HnQNezl7l+k(M+p#GNo^!%4cWfOJBiX z#`p7Wk#DOPzeAym$-X&r40$kyIL8pD$mN6waorAZr=3|VGDQEatV562r(-XDk{OsYA)K2Tq+HG7`3sm0 zUm|l3%!PR%^Q`kR7r;XJ3O|crF)V?l<^(+#r>dEK@a3iKQ&n|A%FEY;k^Q&J$lK+x z0#=gdRfNkG@BHTgzvEf<{>r}JyU6iScco6Q!~T1aeZT85 zH^4^N1e;+C`~X|Y*B{Nzq|?^6nN_sy=p%Ybd$a@nWe!?S1pb8Io#^p1cDvvg!tI7V zrtD>A*QPm<^oji>+6yt+JBF-ZVIR-?;Q-GE9r^SX`F#iu!x2+XnolN=CL_bvjv`;` z<1wea71WQLo7i`t%IFDn*ajzIE#*M`ox=ZV@Us3BiobpArQT-7X=ez37W;EPdA~b; zrqHeu4ZOczDdQ~JuWjn*2`g(FYHf*qGUildPsL^`;U?=BojNG{w?zkepX_UJO`|QJ zhM#HpQF{!x@O+;AX<0xUs$~9+KK;mh(W4`C$}iDLedAaccH&y-^Q+Rb zE?AB2q#v%ncM?|m7^3S}0Ue(5USBzOi~eON{m0}%ivxL~&I7S8o_N(B`Xzz9cte_5 z?9+5$>4|Vl>2HhPk=kn9V;>H6B~7y9!vt+9+U_cni} z?z^41meViu=NIh)a%}9wAQ^I#LpY>>ln?=_AT^|cw2%(cLk4SwFAhnAoQdR3IC`z5 zPM|Nizyu325+;*R@3h9M|A(K|{|`TMig1&5+Uzh`k`LuHVFB~ikmw7CFi{| zql=vV%4d8_co~OlS{6%{#jNB-HcRb4$ZoAAU&URyd0A-<`PXmpD|sva*HNa{Q76|? zC*RiP9Jq%QOA6vYN_ohM-+bIikqWp8$nmT6W&NG}$z@3!A!SeYR;lx zd=NyMWId}OWj#MS7l4A6jQiKq_mKHoe_2*-OCe-OL18EY(NGkkj178PZpPrWHM(rj zi&@fEFms1I>2t*5NA+cyH{!X3wNWpLTWxeIg&w6XODltYS%@PKRUd^{K4S#`0VR`>N=pbW&qe8KYLit~%5}pPJ}h3pur+4t8~+9?$im0qJOHrO+Bd zV@SlV2{a{KB)5b#vofN0Fk`T-l!=VGj47Mr?&ao?B-|j<0@*G3-3nSe`LK!dD>sd7 za?<-DI(|fcw1Kv`%Qwo)da$HH-LJ6Cmlxahc9!fjk@aC)Yfrj5;9vS29Wguk!qz07 z&LHz!vUb^p=dREV_m9!Pdmx{7=snQAC-z=$HR(kKI~jxe%hfJQH2010Pl7HtqbT=*ycav`VcGeze{3i0Gog8Gz z%_*vm4z_-!KB;?#WS{RF#sfph$DyRd%grh>&m{LF$vsKKkUJbkIO*7r+dh4ywND=f zqhSngV_}?ifcGKuRqRpY_js596Rm@eJaH4bldw~B7^2s2|A*Tl^rfFjyi=^hwAF9t zQ+qM)n~JW}K<zpZ4#SK0#Vohq6v< zi-^yEo?|i3Ug!21_BJDLDZk_K*DqN7u|@^Gj8l$o%aFeuR)E~Cu@Z9?tR~zyu*Nz~ z*=DTB^IG^0*5Up=tcMM-(Kkc9Qci6j>9~I9P{Cc?^ zNXfV#u)pfqKM4H3=KOvb_uW8ze8)eZdJbo@T?xjl8vTh^bv zcg7~@c?a&|=N{&LcmNOi{RsYm$M6K6T5=l^Z4Kq*PwP2xYuYoOD_|Zs{tCD~w_cDJ z{y8W)hrljN{JpULCQPvQH?poF=%w}2c@MYg%e}PzarAm=y+U_?c~$MxKh|q>Wi5sA zlk_*`+|4U=d<}0vbHCDcFd)cHpAC|@i%~*V`(73^#En#U3M~{|?$^4B9}C>z0o$FH zavbc8Z^HPU43a}Qq=1wl?S*{B)m#hmD9;h@H1y@vU3sa9BQ^fgV5Y@P2kCjvfEkII z5i=9=&ElLYlc+J4{(?BM#HRPS}r<|Q6XnFdB?fk1spR4 zH$SlpoIPRmOYkfEvAxqqTx=IoHEVH~ypCtR*o2 zSeR$o$1V3$N*)(MpJ*rw4Y4nVdkn-vaac;MB``~(V<{*NWuPo}aZnDtAbC_C8Szj7 zDq<)5#w%eaKxL=`RiPR$S?*MoZ>$y|>V&HSHK7uEt2r3mkbGE^v?HjMjzz%b?@dpq4F0?T=IREaZNwMbfK2_$CUYx0hj}k_Zi4oa1g%-!w`_U-JzJn zU^wKaT#mpT38P>%i~(6Qk+qb=FqYrrz<<8>bDqb;1el2KlVCDTfvGSJro#-}<-E;I zo@c=qFdN>k1JN$>ZT}LxIWQOI!F*VN?y^R71s3xB6|xq=V%*+cFIvLyrSLT@gXORS zR>CS+4RTgn-qkleuYqr2EgZ$}J7lke@AwM zgLzl%;XZBW1GoR|EBj8|A;u%Z{Q-~N$&4p%x$h;p@szm!1XCYFs~T<$MF%;r`wYA1 zAnidie#?9Ni{EnZ*$d3S;U)Y7ui!Pj0XgT(hILH`16J_ce-1c^-@%XsLLeyz@Iyi7 zXIz-3hh7%A!2>pgK{7}V;dH$68B*`Yl562c3S^{&2#~u3Q(>ltG>%NxDF~C!BWsJS zN%1UgLnJr$N&Be!hv>ln83^;lNJ;yZlC~)&ZBq(kI`fHgKJzho94T@0rON1uAZ!GF zBJg8tnTRJdgi}MA6U081W8W9|ERMYjn-%%l&^^0n3w=^Gceu%Sb}I+6b9yZ815aur z1ev)AmmBgp;iWx$qviFap>39MX^niIv_^gp`(|)2NZ3LU#qYvU1R2qoMWGnPK&&U7 zQ5;G@Nq(2|ywOUdOBpDOtjx%in+atuFb~<1e1y6`&&c_jFW} zXDC4%H<$54WuB`*Rfyy^!)l%kMs-i5Q3IJZp%!VZP5ebb_IT96tPAx#8I5pmJY+{B zI>`85-NIcTISoMCRauj3$a5oT42jSLq>XQinF-UYWipz1GE-wRBP%nqG8)a1-NKWF z>8>o;WpUn3OX6%rnrf5I)`b1gC+8z{Y=e$%$tQX;_)q84N7LF7<^l7V?eP=NsE}JB zP&LBozbSpQ8eaBBbRc|3kLZ!w=tP*#o(R2*NA?jZT@&4fpGpUK)-cF19T zfPGG$)Vc9qgi(HSk!Re=Lq7C|Poa+|H~w;J6P)?mJoE!nXnm2d`e}KcxTOtu?%+XA zKf>RI{+@hJ+yfjtzB!~vtzG0NjLey^capsSj5r2?$Q$e_Kq}-Cj7;q%-ow; z$QXq`IX7PleWm;)rC&E1*#og3gX{$Q*JClg&W(`l*~IO0PZ9E{2r`Qxa})D=wl>}q zZKUN!Om@s-XKNEYGIv(Qn8+JKT8_PZJ7vvr3I0}i$~f^X#(pKpU5GB+W4Uou$x?G5tGKj4#$T)P zvxe{HH|ShhkK~eG6;JqldKHnVfpYT@{2`7tm3yfm%TxBQ@@#!}qwa z2N@G=5c%}4B%X~RbtetqOBvg3;`e6Q0zbf3_z||jcGv+w!A^Ae+0$PuLyg7^lYb|% zKLw}Z44lR79L&P)cYdGe`2xt;>mt7|!DW!|_!aW+DqQ3Db^ORZfHyF2^7|It_Kef+ zkdC_^)qlQ++kJR|+e6Gpn15hCh9~e8{)A`n+%tf`?jUKGd+Frvw?f)q*uNl5HuCsy zo?pU0Fbv(KF2CZrF!}x(^9{&_Kf}m(-KKxSvzM~HpVAp*t9DrKcMrxsQ5(p&+8>uc z4&}$Il{eo0%>~($L4N{yA&?Y8LDs@um?l`D_HU?q*v$2UDI@ut1OKq^RWS2EJr(OOzahurkUodF_o>%$GZM}sOE8L`h~SElZW z9d`=zyPRHydcxNgzga=nd$M7l9dhtHC&Xj-0l#xWZpZ_9As=zdH!MHT1)v}la^e%c z6O44g46oDnNIM#Zd*OgT(IZgLzp`JmhzzLjjS`b#_xyl5wx-E@=ojGuP*+W zTfxr1f5FR*$})c-e@mks>Er~f)}HueeZ2$zyjn%W!wtl=lgo0{trr`(sImM!{$p z17l$vd=BGb0!$>l+$XW0+?s^U$uPxU&f8k1O|_+cv$bjHG#x}IFMem(EBK2yes^jA z$}&<>I?qJrdO~ji`MVy{HqXND3z!XG+J&__Fc*3A;5zv*A5-e=0^AqESFp%V&Ro2| z&9Sw`=(z-zf`3k5^#kQ5Y`)LfC&Rz=?Us>-<;Yk8EA2*3y;{X{8FUP1ukAcy9xf9;E%Q&8Q=wM=7KCj_p zv6DXEKh8Vr?n@heDxZH@>l8Pcr;6u>dU=Nu-+#OJ48;H1iN9Ci_Z#Q;CxPEezutl0 z{U`%oZnRhOReo^!fhKbFFh;Ks6xJu8w|}gq=6L%0@|+bS!X$wZkhRaGn4#bzyq8<@ z{rO>HXMx+XZ*JrZw1@Avv61AN2fsFcrOt<8CIitgIfO$BNC^>PjDjFFq=B@M4$|X4 z14QB{Bfn+-cnHYf32lv|m9RL6T diff --git a/utils/exporters/blender/tests/blend/scene_perspective_camera.blend b/utils/exporters/blender/tests/blend/scene_perspective_camera.blend index 29e3e1e9677aa381a4e744492311795206ce29db..97e4fedb143a223ed2eb3009eb7fe2bfa97033ed 100644 GIT binary patch literal 483708 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 literal 479808 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 literal 524040 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

    {!Dqns=?aJ(8HkFnsI(6v(+3{sL$ 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 VuSx+aAyt$@r6YWFg8%yO{{eu0Gf@Bl From da829c3c8dd5f9a63a50cca04d4a2bb59637a3a9 Mon Sep 17 00:00:00 2001 From: repsac Date: Thu, 5 Mar 2015 08:04:47 -0800 Subject: [PATCH 248/333] Fixed a bug by inverting the conditional results around embed geometry tests --- utils/exporters/blender/addons/io_three/exporter/geometry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index c2a8eeff87390d..3c456e35da7d62 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -335,7 +335,7 @@ def _scene_format(self): constants.METADATA: self.metadata }) else: - if self.options.get(constants.EMBED_GEOMETRY): + if self.options.get(constants.EMBED_GEOMETRY, True): data[constants.DATA] = { constants.ATTRIBUTES: component_data } From 951c4049b5f17da303da4d6aa785867720ffaa5a Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 6 Mar 2015 17:33:20 +0100 Subject: [PATCH 249/333] Editor: Edit/Flatten robustness. --- editor/js/Menubar.Edit.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/editor/js/Menubar.Edit.js b/editor/js/Menubar.Edit.js index 246713c83d0a6c..10906eaf9c0275 100644 --- a/editor/js/Menubar.Edit.js +++ b/editor/js/Menubar.Edit.js @@ -68,6 +68,13 @@ Menubar.Edit = function ( editor ) { if ( object.parent === undefined ) return; // avoid flattening the camera or scene + if ( object.geometry === undefined ) { + + alert( object.name + ' doesn\'t have geometry' ); + return; + + } + if ( confirm( 'Flatten ' + object.name + '?' ) === false ) return; var geometry = object.geometry; From 58cb06f4e528295a91759f39ff78e443920f4d04 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 6 Mar 2015 17:44:25 +0100 Subject: [PATCH 250/333] Editor: Edit/Flatten to Geometry/Actions/Flatten --- editor/js/Menubar.Edit.js | 39 --------------------------- editor/js/Sidebar.Geometry.js | 50 +++++++++++++++++++++++++++++++++++ editor/js/Sidebar.Object3D.js | 2 ++ 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/editor/js/Menubar.Edit.js b/editor/js/Menubar.Edit.js index 10906eaf9c0275..dbe75877094dcb 100644 --- a/editor/js/Menubar.Edit.js +++ b/editor/js/Menubar.Edit.js @@ -53,45 +53,6 @@ Menubar.Edit = function ( editor ) { } ); options.add( option ); - // - - options.add( new UI.HorizontalRule() ); - - // Flatten - - var option = new UI.Panel(); - option.setClass( 'option' ); - option.setTextContent( 'Flatten' ); - option.onClick( function () { - - var object = editor.selected; - - if ( object.parent === undefined ) return; // avoid flattening the camera or scene - - if ( object.geometry === undefined ) { - - alert( object.name + ' doesn\'t have geometry' ); - return; - - } - - if ( confirm( 'Flatten ' + object.name + '?' ) === false ) return; - - var geometry = object.geometry; - - geometry.applyMatrix( object.matrix ); - geometry.verticesNeedUpdate = true; - geometry.normalsNeedUpdate = true; - - object.position.set( 0, 0, 0 ); - object.rotation.set( 0, 0, 0 ); - object.scale.set( 1, 1, 1 ); - - editor.signals.objectChanged.dispatch( object ); - - } ); - options.add( option ); - return container; }; diff --git a/editor/js/Sidebar.Geometry.js b/editor/js/Sidebar.Geometry.js index 1fd62143bef2ad..bc3efd9e40e1be 100644 --- a/editor/js/Sidebar.Geometry.js +++ b/editor/js/Sidebar.Geometry.js @@ -17,6 +17,56 @@ Sidebar.Geometry = function ( editor ) { var geometryType = new UI.Text().setTextTransform( 'uppercase' ); container.addStatic( geometryType ); + + // Actions + + var objectActions = new UI.Select().setPosition('absolute').setRight( '8px' ).setFontSize( '11px' ); + objectActions.setOptions( { + + 'Actions': 'Actions', + 'Flatten': 'Flatten' + + } ); + objectActions.onClick( function ( event ) { + + event.stopPropagation(); // Avoid panel collapsing + + } ); + objectActions.onChange( function ( event ) { + + var object = editor.selected; + + switch ( this.getValue() ) { + + case 'Flatten': + + var object = editor.selected; + + if ( confirm( 'Flatten ' + object.name + '?' ) === false ) return; + + var geometry = object.geometry; + + geometry.applyMatrix( object.matrix ); + geometry.verticesNeedUpdate = true; + geometry.normalsNeedUpdate = true; + + object.position.set( 0, 0, 0 ); + object.rotation.set( 0, 0, 0 ); + object.scale.set( 1, 1, 1 ); + + editor.signals.objectChanged.dispatch( object ); + + break; + + } + + this.setValue( 'Actions' ); + + signals.objectChanged.dispatch( object ); + + } ); + container.addStatic( objectActions ); + container.add( new UI.Break() ); // uuid diff --git a/editor/js/Sidebar.Object3D.js b/editor/js/Sidebar.Object3D.js index 4bea46dc1ed46b..0aae11c0e456f6 100644 --- a/editor/js/Sidebar.Object3D.js +++ b/editor/js/Sidebar.Object3D.js @@ -18,6 +18,8 @@ Sidebar.Object3D = function ( editor ) { var objectType = new UI.Text().setTextTransform( 'uppercase' ); container.addStatic( objectType ); + // Actions + var objectActions = new UI.Select().setPosition('absolute').setRight( '8px' ).setFontSize( '11px' ); objectActions.setOptions( { From 48b299b23bb7a3b66953fe53be22e6fed8eeb601 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 6 Mar 2015 17:49:43 +0100 Subject: [PATCH 251/333] BufferGeometry: Compute BoundingBox/Sphere after applyMatrix(). #6167 --- src/core/BufferGeometry.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index 3fe6a10ea000d6..f89f4a2f94836b 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -84,6 +84,18 @@ THREE.BufferGeometry.prototype = { } + if ( this.boundingBox instanceof THREE.Box3 ) { + + this.computeBoundingBox(); + + } + + if ( this.boundingSphere instanceof THREE.Sphere ) { + + this.computeBoundingSphere(); + + } + }, center: function () { From e60612aad33e7f224ccdc8da9c7210f190a92739 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 6 Mar 2015 17:49:51 +0100 Subject: [PATCH 252/333] Updated builds. --- build/three.js | 18 ++++++++++++++++-- build/three.min.js | 45 +++++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/build/three.js b/build/three.js index 122cd84739060b..e1994beeb665af 100644 --- a/build/three.js +++ b/build/three.js @@ -8103,6 +8103,8 @@ THREE.Object3D.prototype = { data.geometry = parseGeometry( object.geometry ); data.material = parseMaterial( object.material ); + if ( object instanceof THREE.Line ) data.mode = object.mode; + } else if ( object instanceof THREE.Sprite ) { data.material = parseMaterial( object.material ); @@ -8555,6 +8557,18 @@ THREE.BufferGeometry.prototype = { } + if ( this.boundingBox instanceof THREE.Box3 ) { + + this.computeBoundingBox(); + + } + + if ( this.boundingSphere instanceof THREE.Sphere ) { + + this.computeBoundingSphere(); + + } + }, center: function () { @@ -13049,7 +13063,7 @@ THREE.ObjectLoader.prototype = { case 'Line': - object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ) ); + object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode ); break; @@ -15062,7 +15076,7 @@ THREE.Line = function ( geometry, material, mode ) { this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } ); - this.mode = ( mode !== undefined ) ? mode : THREE.LineStrip; + this.mode = mode !== undefined ? mode : THREE.LineStrip; }; diff --git a/build/three.min.js b/build/three.min.js index 0498bfdb998ccb..f4814682742294 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -170,9 +170,9 @@ b,c);return c}}(),getWorldDirection:function(){var a=new THREE.Quaternion;return this.parent.traverseAncestors(a))},updateMatrix:function(){this.matrix.compose(this.position,this.quaternion,this.scale);this.matrixWorldNeedsUpdate=!0},updateMatrixWorld:function(a){!0===this.matrixAutoUpdate&&this.updateMatrix();if(!0===this.matrixWorldNeedsUpdate||!0===a)void 0===this.parent?this.matrixWorld.copy(this.matrix):this.matrixWorld.multiplyMatrices(this.parent.matrixWorld,this.matrix),this.matrixWorldNeedsUpdate=!1,a=!0;for(var b=0,c=this.children.length;bqa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array, -e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hqa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()"); +else{var c=this.attributes.index.array,d=this.attributes.position.array,e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+ +b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array, +f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;h Date: Sat, 7 Mar 2015 16:44:26 +0100 Subject: [PATCH 253/333] Slightly faster BufferGeometry's toJSON I did not time it, but the logic says native methods should be faster. Right now editor's export is quite slow, I guess, in large part because of this. --- src/core/BufferGeometry.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index f89f4a2f94836b..fbf6968b1f9201 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -896,13 +896,7 @@ THREE.BufferGeometry.prototype = { var attribute = attributes[ key ]; - var array = [], typeArray = attribute.array; - - for ( var i = 0, l = typeArray.length; i < l; i ++ ) { - - array[ i ] = typeArray[ i ]; - - } + var array = Array.prototype.slice.call( attribute.array ); output.data.attributes[ key ] = { itemSize: attribute.itemSize, From de657cc6053c9abd1d3fb434895fc6a62376d3f9 Mon Sep 17 00:00:00 2001 From: Alexander Rose Date: Sun, 8 Mar 2015 12:43:18 +0100 Subject: [PATCH 254/333] code cleanup, removed variable re-declarations --- examples/js/loaders/OBJLoader.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/examples/js/loaders/OBJLoader.js b/examples/js/loaders/OBJLoader.js index 01d4f4c91509d8..f66baddcf25121 100644 --- a/examples/js/loaders/OBJLoader.js +++ b/examples/js/loaders/OBJLoader.js @@ -87,11 +87,12 @@ THREE.OBJLoader.prototype = { } - function addFace( a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd ) { + function addFace( a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd ) { var ia = parseVertexIndex( a ); var ib = parseVertexIndex( b ); var ic = parseVertexIndex( c ); + var id; if ( d === undefined ) { @@ -99,7 +100,7 @@ THREE.OBJLoader.prototype = { } else { - var id = parseVertexIndex( d ); + id = parseVertexIndex( d ); addVertex( ia, ib, id ); addVertex( ib, ic, id ); @@ -108,9 +109,9 @@ THREE.OBJLoader.prototype = { if ( ua !== undefined ) { - var ia = parseUVIndex( ua ); - var ib = parseUVIndex( ub ); - var ic = parseUVIndex( uc ); + ia = parseUVIndex( ua ); + ib = parseUVIndex( ub ); + ic = parseUVIndex( uc ); if ( d === undefined ) { @@ -118,7 +119,7 @@ THREE.OBJLoader.prototype = { } else { - var id = parseUVIndex( ud ); + id = parseUVIndex( ud ); addUV( ia, ib, id ); addUV( ib, ic, id ); @@ -129,9 +130,9 @@ THREE.OBJLoader.prototype = { if ( na !== undefined ) { - var ia = parseNormalIndex( na ); - var ib = parseNormalIndex( nb ); - var ic = parseNormalIndex( nc ); + ia = parseNormalIndex( na ); + ib = parseNormalIndex( nb ); + ic = parseNormalIndex( nc ); if ( d === undefined ) { @@ -139,7 +140,7 @@ THREE.OBJLoader.prototype = { } else { - var id = parseNormalIndex( nd ); + id = parseNormalIndex( nd ); addNormal( ia, ib, id ); addNormal( ib, ic, id ); @@ -202,7 +203,7 @@ THREE.OBJLoader.prototype = { var face_pattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/; - // f vertex//normal vertex//normal vertex//normal ... + // f vertex//normal vertex//normal vertex//normal ... var face_pattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/ @@ -261,7 +262,7 @@ THREE.OBJLoader.prototype = { } else if ( ( result = face_pattern2.exec( line ) ) !== null ) { // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined] - + addFace( result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ], result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] @@ -337,8 +338,8 @@ THREE.OBJLoader.prototype = { for ( var i = 0, l = objects.length; i < l; i ++ ) { - var object = objects[ i ]; - var geometry = object.geometry; + object = objects[ i ]; + geometry = object.geometry; var buffergeometry = new THREE.BufferGeometry(); @@ -352,7 +353,7 @@ THREE.OBJLoader.prototype = { buffergeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( geometry.uvs ), 2 ) ); } - var material = new THREE.MeshLambertMaterial(); + material = new THREE.MeshLambertMaterial(); material.name = object.material.name; var mesh = new THREE.Mesh( buffergeometry, material ); From 8022f80dc2e444c4d3a778bc5801e8a964da386d Mon Sep 17 00:00:00 2001 From: Alexander Rose Date: Sun, 8 Mar 2015 13:02:37 +0100 Subject: [PATCH 255/333] code cleanup, fix undeclared variables --- examples/js/loaders/PLYLoader.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/examples/js/loaders/PLYLoader.js b/examples/js/loaders/PLYLoader.js index da547209b1151f..d0734fe9c0cc6a 100644 --- a/examples/js/loaders/PLYLoader.js +++ b/examples/js/loaders/PLYLoader.js @@ -116,14 +116,17 @@ THREE.PLYLoader.prototype = { var patternHeader = /ply([\s\S]*)end_header\s/; var headerText = ""; - if ( ( result = patternHeader.exec( data ) ) !== null ) { + var headerLength = 0; + var result = patternHeader.exec( data ); + if ( result !== null ) { headerText = result [ 1 ]; + headerLength = result[ 0 ].length; } var header = { comments: [], elements: [], - headerLength: result[ 0 ].length + headerLength: headerLength }; var lines = headerText.split( '\n' ); @@ -241,7 +244,7 @@ THREE.PLYLoader.prototype = { parseASCIIElement: function ( properties, line ) { - values = line.split( /\s+/ ); + var values = line.split( /\s+/ ); var element = Object(); @@ -252,7 +255,7 @@ THREE.PLYLoader.prototype = { var list = []; var n = this.parseASCIINumber( values.shift(), properties[i].countType ); - for ( j = 0; j < n; j ++ ) { + for ( var j = 0; j < n; j ++ ) { list.push( this.parseASCIINumber( values.shift(), properties[i].itemType ) ); @@ -354,7 +357,7 @@ THREE.PLYLoader.prototype = { geometry.useColor = true; - color = new THREE.Color(); + var color = new THREE.Color(); color.setRGB( element.red / 255.0, element.green / 255.0, element.blue / 255.0 ); geometry.colors.push( color ); @@ -423,7 +426,7 @@ THREE.PLYLoader.prototype = { var n = result[0]; read += result[1]; - for ( j = 0; j < n; j ++ ) { + for ( var j = 0; j < n; j ++ ) { result = this.binaryRead( dataview, at + read, properties[i].itemType, little_endian ); list.push( result[0] ); From 02a08075e85c86ce8b2dfed696ea84ad14220702 Mon Sep 17 00:00:00 2001 From: rkusa Date: Wed, 4 Mar 2015 16:20:11 +0100 Subject: [PATCH 256/333] Blender: export hierarchy --- .../blender/addons/io_three/__init__.py | 13 ++++ .../blender/addons/io_three/constants.py | 3 + .../addons/io_three/exporter/api/object.py | 67 +++++++------------ .../addons/io_three/exporter/object.py | 24 +++---- .../blender/addons/io_three/exporter/scene.py | 10 ++- 5 files changed, 62 insertions(+), 55 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index 15b4129ed86e45..b8a05893cb3158 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -303,6 +303,7 @@ def save_settings_export(properties): constants.EMBED_ANIMATION: properties.option_embed_animation, constants.LIGHTS: properties.option_lights, constants.CAMERAS: properties.option_cameras, + constants.HIERARCHY: properties.option_hierarchy, constants.MORPH_TARGETS: properties.option_animation_morph, constants.ANIMATION: properties.option_animation_skeletal, @@ -447,6 +448,10 @@ def restore_settings_export(properties): properties.option_cameras = settings.get( constants.CAMERAS, constants.EXPORT_OPTIONS[constants.CAMERAS]) + + properties.option_hierarchy = settings.get( + constants.HIERARCHY, + constants.EXPORT_OPTIONS[constants.HIERARCHY]) ## } ## Animation { @@ -638,6 +643,11 @@ class ExportThree(bpy.types.Operator, ExportHelper): description="Export default scene cameras", default=False) + option_hierarchy = BoolProperty( + name="Hierarchy", + description="Export object hierarchy", + default=False) + option_animation_morph = BoolProperty( name="Morph animation", description="Export animation (morphs)", @@ -811,6 +821,9 @@ def draw(self, context): row.prop(self.properties, 'option_cameras') ## } + row = layout.row() + row.prop(self.properties, 'option_hierarchy') + layout.separator() ## Settings { diff --git a/utils/exporters/blender/addons/io_three/constants.py b/utils/exporters/blender/addons/io_three/constants.py index 146ebee7b31c85..caa3d88ed6100c 100644 --- a/utils/exporters/blender/addons/io_three/constants.py +++ b/utils/exporters/blender/addons/io_three/constants.py @@ -60,6 +60,7 @@ LOGGING = 'logging' CAMERAS = 'cameras' LIGHTS = 'lights' +HIERARCHY = 'hierarchy' FACE_MATERIALS = 'faceMaterials' SKINNING = 'skinning' COPY_TEXTURES = 'copyTextures' @@ -110,6 +111,7 @@ MORPH_TARGETS: False, CAMERAS: False, LIGHTS: False, + HIERARCHY: False, COPY_TEXTURES: True, TEXTURE_FOLDER: '', LOGGING: DEBUG, @@ -160,6 +162,7 @@ SPOT_LIGHT = 'SpotLight' HEMISPHERE_LIGHT = 'HemisphereLight' MESH = 'Mesh' +EMPTY = 'Empty' SPRITE = 'Sprite' DEFAULT_METADATA = { diff --git a/utils/exporters/blender/addons/io_three/exporter/api/object.py b/utils/exporters/blender/addons/io_three/exporter/api/object.py index ab7d40dcc609d8..2e6c0cd5639516 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/object.py @@ -2,6 +2,7 @@ import mathutils import bpy from bpy import data, context, types +from bpy_extras.io_utils import axis_conversion from .. import constants, logger, utilities, exceptions from .constants import ( MESH, @@ -225,14 +226,8 @@ def position(obj, options): """ logger.debug('object.position(%s)', obj) - vector = _decompose_matrix(obj)[0] - vector = (vector.x, vector.y, vector.z) - - round_off, round_val = utilities.rounding(options) - if round_off: - vector = utilities.round_off(vector, round_val) - - return vector + vector = matrix(obj, options).to_translation() + return (vector.x, vector.y, vector.z) @_object @@ -250,23 +245,35 @@ def receive_shadow(obj): return False +AXIS_CONVERSION = axis_conversion(to_forward='Z', to_up='Y').to_4x4() + @_object -def rotation(obj, options): +def matrix(obj, options): """ :param obj: :param options: """ - logger.debug('object.rotation(%s)', obj) - vector = _decompose_matrix(obj)[1].to_euler(ZYX) - vector = (vector.x, vector.y, vector.z) + logger.debug('object.matrix(%s)', obj) + if options.get(constants.HIERARCHY, False) and obj.parent: + parent_inverted = obj.parent.matrix_world.inverted(mathutils.Matrix()) + return parent_inverted * obj.matrix_world + else: + return AXIS_CONVERSION * obj.matrix_world + - round_off, round_val = utilities.rounding(options) - if round_off: - vector = utilities.round_off(vector, round_val) +@_object +def rotation(obj, options): + """ + + :param obj: + :param options: - return vector + """ + logger.debug('object.rotation(%s)', obj) + vector = matrix(obj, options).to_euler(ZYX) + return (vector.x, vector.y, vector.z) @_object @@ -278,14 +285,8 @@ def scale(obj, options): """ logger.debug('object.scale(%s)', obj) - vector = _decompose_matrix(obj)[2] - vector = (vector.x, vector.y, vector.z) - - round_off, round_val = utilities.rounding(options) - if round_off: - vector = utilities.round_off(vector, round_val) - - return vector + vector = matrix(obj, options).to_scale() + return (vector.x, vector.y, vector.z) @_object @@ -477,24 +478,6 @@ def extracted_meshes(): return [key for key in _MESH_MAP.keys()] -def _decompose_matrix(obj, local=False): - """ - - :param obj: - :param local: (Default value = False) - - """ - rotate_x_pi2 = mathutils.Quaternion((1.0, 0.0, 0.0), - math.radians(-90.0)) - rotate_x_pi2 = rotate_x_pi2.to_matrix().to_4x4() - - if local: - matrix = rotate_x_pi2 * obj.matrix_local - else: - matrix = rotate_x_pi2 * obj.matrix_world - return matrix.decompose() - - def _on_visible_layer(obj, visible_layers): """ diff --git a/utils/exporters/blender/addons/io_three/exporter/object.py b/utils/exporters/blender/addons/io_three/exporter/object.py index a69c43fc7b31e5..3da492f540f442 100644 --- a/utils/exporters/blender/addons/io_three/exporter/object.py +++ b/utils/exporters/blender/addons/io_three/exporter/object.py @@ -68,14 +68,13 @@ def _node_setup(self): logger.debug("Object()._node_setup()") self[constants.NAME] = api.object.name(self.node) - self[constants.POSITION] = api.object.position( - self.node, self.options) + transform = api.object.matrix(self.node, self.options) + matrix = [] + for col in range(0, 4): + for row in range(0, 4): + matrix.append(transform[row][col]) - self[constants.ROTATION] = api.object.rotation( - self.node, self.options) - - self[constants.SCALE] = api.object.scale( - self.node, self.options) + self[constants.MATRIX] = matrix self[constants.VISIBLE] = api.object.visible(self.node) @@ -120,11 +119,12 @@ def _node_setup(self): elif self[constants.TYPE] in lights: self._init_light() - #for child in api.object.children(self.node, self.scene.valid_types): - # if not self.get(constants.CHILDREN): - # self[constants.CHILDREN] = [Object(child, parent=self)] - # else: - # self[constants.CHILDREN].append(Object(child, parent=self)) + if self.options.get(constants.HIERARCHY, False): + for child in api.object.children(self.node, self.scene.valid_types): + if not self.get(constants.CHILDREN): + self[constants.CHILDREN] = [Object(child, parent=self)] + else: + self[constants.CHILDREN].append(Object(child, parent=self)) def _root_setup(self): """Applies to a root/scene object""" diff --git a/utils/exporters/blender/addons/io_three/exporter/scene.py b/utils/exporters/blender/addons/io_three/exporter/scene.py index 6fbf3e3641e289..cb78709ad703d3 100644 --- a/utils/exporters/blender/addons/io_three/exporter/scene.py +++ b/utils/exporters/blender/addons/io_three/exporter/scene.py @@ -39,6 +39,9 @@ def valid_types(self): """ valid_types = [api.constants.MESH] + if self.options.get(constants.HIERARCHY, False): + valid_types.append(api.constants.EMPTY) + if self.options.get(constants.CAMERAS): logger.info("Adding cameras to valid object types") valid_types.append(api.constants.CAMERA) @@ -207,7 +210,12 @@ def _parse_objects(self): self[constants.UUID] = utilities.id_from_name(scene_name) objects = [] - for node in api.object.nodes(self.valid_types, self.options): + if self.options.get(constants.HIERARCHY, False): + nodes = api.object.assemblies(self.valid_types, self.options) + else: + nodes = api.object.nodes(self.valid_types, self.options) + + for node in nodes: logger.info("Parsing object %s", node) obj = object_.Object(node, parent=self[constants.OBJECT]) objects.append(obj) From 5f009a9c49a2c9b5f1c14956a981ddb4edcb1416 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 8 Mar 2015 17:41:45 +0100 Subject: [PATCH 257/333] Loader: Robustness. See #6197. --- src/loaders/Loader.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/loaders/Loader.js b/src/loaders/Loader.js index 4dd0f7c440acd3..87301f6bfd1c16 100644 --- a/src/loaders/Loader.js +++ b/src/loaders/Loader.js @@ -225,11 +225,15 @@ THREE.Loader.prototype = { mpars.blending = THREE[ m.blending ]; } - - if ( m.transparent !== undefined || m.opacity < 1.0 ) { + + if ( m.transparent !== undefined ) { mpars.transparent = m.transparent; + } else if ( m.opacity < 1.0 ) { + + mpars.transparent = true; + } if ( m.depthTest !== undefined ) { @@ -308,14 +312,14 @@ THREE.Loader.prototype = { // modifiers - if ( m.transparency ) { + if ( m.transparency !== undefined ) { console.warn( 'THREE.Loader: transparency has been renamed to opacity' ); - mpars.opacity = m.transparency; + m.opacity = m.transparency; } - if ( m.opacity ) { + if ( m.opacity !== undefined ) { mpars.opacity = m.opacity; From 703420f775ca4f08b55bf36e09fa09ad5352b8e9 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 8 Mar 2015 17:42:59 +0100 Subject: [PATCH 258/333] Updated builds. --- build/three.js | 14 +++++++++----- build/three.min.js | 8 ++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/build/three.js b/build/three.js index e1994beeb665af..9484ccf52e3abb 100644 --- a/build/three.js +++ b/build/three.js @@ -11472,11 +11472,15 @@ THREE.Loader.prototype = { mpars.blending = THREE[ m.blending ]; } - - if ( m.transparent !== undefined || m.opacity < 1.0 ) { + + if ( m.transparent !== undefined ) { mpars.transparent = m.transparent; + } else if ( m.opacity < 1.0 ) { + + mpars.transparent = true; + } if ( m.depthTest !== undefined ) { @@ -11555,14 +11559,14 @@ THREE.Loader.prototype = { // modifiers - if ( m.transparency ) { + if ( m.transparency !== undefined ) { console.warn( 'THREE.Loader: transparency has been renamed to opacity' ); - mpars.opacity = m.transparency; + m.opacity = m.transparency; } - if ( m.opacity ) { + if ( m.opacity !== undefined ) { mpars.opacity = m.opacity; diff --git a/build/three.min.js b/build/three.min.js index f4814682742294..dfc847dadbedb5 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -254,10 +254,10 @@ THREE.Loader.prototype={constructor:THREE.Loader,crossOrigin:void 0,addStatusEle "%"):b+((a.loaded/1024).toFixed(2)+" KB");this.statusDomElement.innerHTML=b},extractUrlBase:function(a){a=a.split("/");if(1===a.length)return"./";a.pop();return a.join("/")+"/"},initMaterials:function(a,b){for(var c=[],d=0;da.opacity)h.transparent=a.transparent;void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide);void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe);void 0!==a.vertexColors&&("face"=== -a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));a.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),h.opacity=a.transparency);a.opacity&&(h.opacity=a.opacity);a.specularCoef&&(h.shininess=a.specularCoef);a.mapDiffuse&&b&&d(h,"map",a.mapDiffuse, -a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&d(h,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&d(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&d(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&d(h,"specularMap",a.mapSpecular,a.mapSpecularRepeat,a.mapSpecularOffset, -a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapAlpha&&b&&d(h,"alphaMap",a.mapAlpha,a.mapAlphaRepeat,a.mapAlphaOffset,a.mapAlphaWrap,a.mapAlphaAnisotropy);a.mapBumpScale&&(h.bumpScale=a.mapBumpScale);a.mapNormalFactor&&(h.normalScale=new THREE.Vector2(a.mapNormalFactor,a.mapNormalFactor));g=new THREE[g](h);void 0!==a.DbgName&&(g.name=a.DbgName);return g}}; +"basic"===k&&(g="MeshBasicMaterial")}void 0!==a.blending&&void 0!==THREE[a.blending]&&(h.blending=THREE[a.blending]);void 0!==a.transparent?h.transparent=a.transparent:1>a.opacity&&(h.transparent=!0);void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide);void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe);void 0!==a.vertexColors&& +("face"===a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));void 0!==a.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),a.opacity=a.transparency);void 0!==a.opacity&&(h.opacity=a.opacity);a.specularCoef&&(h.shininess=a.specularCoef);a.mapDiffuse&& +b&&d(h,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&d(h,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&d(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&d(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&d(h,"specularMap",a.mapSpecular,a.mapSpecularRepeat, +a.mapSpecularOffset,a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapAlpha&&b&&d(h,"alphaMap",a.mapAlpha,a.mapAlphaRepeat,a.mapAlphaOffset,a.mapAlphaWrap,a.mapAlphaAnisotropy);a.mapBumpScale&&(h.bumpScale=a.mapBumpScale);a.mapNormalFactor&&(h.normalScale=new THREE.Vector2(a.mapNormalFactor,a.mapNormalFactor));g=new THREE[g](h);void 0!==a.DbgName&&(g.name=a.DbgName);return g}}; THREE.Loader.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=0,c=this.handlers.length;b Date: Sun, 8 Mar 2015 18:27:25 +0100 Subject: [PATCH 259/333] Loader: Robustness. See #6197. --- src/loaders/Loader.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/loaders/Loader.js b/src/loaders/Loader.js index 87301f6bfd1c16..c6b0e62182c1af 100644 --- a/src/loaders/Loader.js +++ b/src/loaders/Loader.js @@ -225,12 +225,14 @@ THREE.Loader.prototype = { mpars.blending = THREE[ m.blending ]; } - + if ( m.transparent !== undefined ) { mpars.transparent = m.transparent; - } else if ( m.opacity < 1.0 ) { + } + + if ( m.opacity !== undefined && m.opacity < 1.0 ) { mpars.transparent = true; From adf7c1f198510fa8cdf1932e48466dd36896d533 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 8 Mar 2015 18:32:31 +0100 Subject: [PATCH 260/333] Removed incorrect opacity data. See #6197. --- examples/models/skinned/marine/marine.js | 1 - .../models/skinned/marine/marine_anims.js | 1 - .../models/skinned/marine/marine_ikrig.js | 1 - examples/obj/f50/F50NoUv_bin.js | 63 +++++++------------ examples/obj/gallardo/GallardoNoUv_bin.js | 21 +++---- .../obj/gallardo/parts/gallardo_body_bin.js | 21 +++---- .../obj/gallardo/parts/gallardo_wheel_bin.js | 6 +- examples/obj/veyron/VeyronNoUv_bin.js | 15 ++--- examples/obj/veyron/parts/veyron_body_bin.js | 15 ++--- examples/obj/veyron/parts/veyron_wheel_bin.js | 6 +- 10 files changed, 49 insertions(+), 101 deletions(-) diff --git a/examples/models/skinned/marine/marine.js b/examples/models/skinned/marine/marine.js index c931fe8d1c0530..3f2d0263e6a117 100644 --- a/examples/models/skinned/marine/marine.js +++ b/examples/models/skinned/marine/marine.js @@ -30,7 +30,6 @@ "mapDiffuseWrap" : ["repeat", "repeat"], "shading" : "Lambert", "specularCoef" : 9, - "opacity" : 0.0, "transparent" : true, "vertexColors" : false }], diff --git a/examples/models/skinned/marine/marine_anims.js b/examples/models/skinned/marine/marine_anims.js index bba0b20a044c63..2070f187550643 100644 --- a/examples/models/skinned/marine/marine_anims.js +++ b/examples/models/skinned/marine/marine_anims.js @@ -30,7 +30,6 @@ "mapDiffuseWrap" : ["repeat", "repeat"], "shading" : "Lambert", "specularCoef" : 9, - "opacity" : 0.0, "transparent" : true, "vertexColors" : false }], diff --git a/examples/models/skinned/marine/marine_ikrig.js b/examples/models/skinned/marine/marine_ikrig.js index 98654f95333416..6a773b53e910f7 100644 --- a/examples/models/skinned/marine/marine_ikrig.js +++ b/examples/models/skinned/marine/marine_ikrig.js @@ -30,7 +30,6 @@ "mapDiffuseWrap" : ["repeat", "repeat"], "shading" : "Lambert", "specularCoef" : 9, - "opacity" : 0.0, "transparent" : true, "vertexColors" : false }], diff --git a/examples/obj/f50/F50NoUv_bin.js b/examples/obj/f50/F50NoUv_bin.js index 51bf1b79d91acb..8355760f08787d 100644 --- a/examples/obj/f50/F50NoUv_bin.js +++ b/examples/obj/f50/F50NoUv_bin.js @@ -21,8 +21,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -34,8 +33,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 17.647059, - "opacity" : 0.0 + "specularCoef" : 17.647059 }, { @@ -60,8 +58,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -73,8 +70,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -86,8 +82,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -99,8 +94,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -112,8 +106,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -125,8 +118,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -138,8 +130,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -151,8 +142,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -164,8 +154,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 17.647059, - "opacity" : 0.0 + "specularCoef" : 17.647059 }, { @@ -177,8 +166,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 17.647059, - "opacity" : 0.0 + "specularCoef" : 17.647059 }, { @@ -190,8 +178,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 17.647059, - "opacity" : 0.0 + "specularCoef" : 17.647059 }, { @@ -203,8 +190,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -216,8 +202,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 17.647059, - "opacity" : 0.0 + "specularCoef" : 17.647059 }, { @@ -242,8 +227,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 17.647059, - "opacity" : 0.0 + "specularCoef" : 17.647059 }, { @@ -281,8 +265,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -294,8 +277,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -307,8 +289,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -320,8 +301,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }, { @@ -333,8 +313,7 @@ "colorSpecular" : [0.025, 0.025, 0.025], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 98.039216, - "opacity" : 0.0 + "specularCoef" : 98.039216 }], "buffers": "F50NoUv_bin.bin" diff --git a/examples/obj/gallardo/GallardoNoUv_bin.js b/examples/obj/gallardo/GallardoNoUv_bin.js index 7755e32d22ded2..ff8fc9b3af4bb5 100644 --- a/examples/obj/gallardo/GallardoNoUv_bin.js +++ b/examples/obj/gallardo/GallardoNoUv_bin.js @@ -21,8 +21,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 29.411765, - "opacity" : 0.0 + "specularCoef" : 29.411765 }, { @@ -34,8 +33,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 29.411765, - "opacity" : 0.0 + "specularCoef" : 29.411765 }, { @@ -47,8 +45,7 @@ "colorSpecular" : [0.0, 0.0, 0.0], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 7.843137, - "opacity" : 0.0 + "specularCoef" : 7.843137 }, { @@ -60,8 +57,7 @@ "colorSpecular" : [0.6525, 0.6525, 0.6525], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 25.490196, - "opacity" : 0.0 + "specularCoef" : 25.490196 }, { @@ -73,8 +69,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 29.411765, - "opacity" : 0.0 + "specularCoef" : 29.411765 }, { @@ -86,8 +81,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 29.411765, - "opacity" : 0.0 + "specularCoef" : 29.411765 }, { @@ -99,8 +93,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 29.411765, - "opacity" : 0.0 + "specularCoef" : 29.411765 }], "buffers": "GallardoNoUv_bin.bin" diff --git a/examples/obj/gallardo/parts/gallardo_body_bin.js b/examples/obj/gallardo/parts/gallardo_body_bin.js index 515dc7c1bc5e53..25cfa8613b8a12 100644 --- a/examples/obj/gallardo/parts/gallardo_body_bin.js +++ b/examples/obj/gallardo/parts/gallardo_body_bin.js @@ -21,8 +21,7 @@ "colorSpecular" : [0.6525, 0.6525, 0.6525], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 21.568627, - "opacity" : 0.0 + "specularCoef" : 21.568627 }, { @@ -34,8 +33,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 27.45098, - "opacity" : 0.0 + "specularCoef" : 27.45098 }, { @@ -47,8 +45,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 27.45098, - "opacity" : 0.0 + "specularCoef" : 27.45098 }, { @@ -60,8 +57,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 27.45098, - "opacity" : 0.0 + "specularCoef" : 27.45098 }, { @@ -73,8 +69,7 @@ "colorSpecular" : [0.0, 0.0, 0.0], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 3.921569, - "opacity" : 0.0 + "specularCoef" : 3.921569 }, { @@ -86,8 +81,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 27.45098, - "opacity" : 0.0 + "specularCoef" : 27.45098 }, { @@ -99,8 +93,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 27.45098, - "opacity" : 0.0 + "specularCoef" : 27.45098 }], "buffers": "gallardo_body_bin.bin" diff --git a/examples/obj/gallardo/parts/gallardo_wheel_bin.js b/examples/obj/gallardo/parts/gallardo_wheel_bin.js index f70f26f4bb275f..e0944dd3d0dab1 100644 --- a/examples/obj/gallardo/parts/gallardo_wheel_bin.js +++ b/examples/obj/gallardo/parts/gallardo_wheel_bin.js @@ -21,8 +21,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 27.45098, - "opacity" : 0.0 + "specularCoef" : 27.45098 }, { @@ -34,8 +33,7 @@ "colorSpecular" : [0.175, 0.175, 0.175], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 27.45098, - "opacity" : 0.0 + "specularCoef" : 27.45098 }], "buffers": "gallardo_wheel_bin.bin" diff --git a/examples/obj/veyron/VeyronNoUv_bin.js b/examples/obj/veyron/VeyronNoUv_bin.js index 19728862376bbc..76b4f235e7f041 100644 --- a/examples/obj/veyron/VeyronNoUv_bin.js +++ b/examples/obj/veyron/VeyronNoUv_bin.js @@ -21,8 +21,7 @@ "colorSpecular" : [0.14825, 0.14825, 0.14825], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 17.647059, - "opacity" : 0.0 + "specularCoef" : 17.647059 }, { @@ -34,8 +33,7 @@ "colorSpecular" : [0.6, 0.6, 0.6], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 37.254902, - "opacity" : 0.0 + "specularCoef" : 37.254902 }, { @@ -47,8 +45,7 @@ "colorSpecular" : [0.75, 0.75, 0.75], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 56.862745, - "opacity" : 0.0 + "specularCoef" : 56.862745 }, { @@ -73,8 +70,7 @@ "colorSpecular" : [0.75, 0.75, 0.75], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 56.862745, - "opacity" : 0.0 + "specularCoef" : 56.862745 }, { @@ -86,8 +82,7 @@ "colorSpecular" : [0.4, 0.4, 0.4], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 17.647059, - "opacity" : 0.0 + "specularCoef" : 17.647059 }, { diff --git a/examples/obj/veyron/parts/veyron_body_bin.js b/examples/obj/veyron/parts/veyron_body_bin.js index f8b36215ee8eb9..0aad247e742855 100644 --- a/examples/obj/veyron/parts/veyron_body_bin.js +++ b/examples/obj/veyron/parts/veyron_body_bin.js @@ -21,8 +21,7 @@ "colorSpecular" : [0.75, 0.75, 0.75], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 52.941176, - "opacity" : 0.0 + "specularCoef" : 52.941176 }, { @@ -34,8 +33,7 @@ "colorSpecular" : [0.75, 0.75, 0.75], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 52.941176, - "opacity" : 0.0 + "specularCoef" : 52.941176 }, { @@ -47,8 +45,7 @@ "colorSpecular" : [0.4, 0.4, 0.4], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 15.686275, - "opacity" : 0.0 + "specularCoef" : 15.686275 }, { @@ -60,8 +57,7 @@ "colorSpecular" : [0.6, 0.6, 0.6], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 35.294118, - "opacity" : 0.0 + "specularCoef" : 35.294118 }, { @@ -99,8 +95,7 @@ "colorSpecular" : [0.14825, 0.14825, 0.14825], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 15.686275, - "opacity" : 0.0 + "specularCoef" : 15.686275 }, { diff --git a/examples/obj/veyron/parts/veyron_wheel_bin.js b/examples/obj/veyron/parts/veyron_wheel_bin.js index 758866d1e2927a..a4f75fd5d17990 100644 --- a/examples/obj/veyron/parts/veyron_wheel_bin.js +++ b/examples/obj/veyron/parts/veyron_wheel_bin.js @@ -21,8 +21,7 @@ "colorSpecular" : [0.6, 0.6, 0.6], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 35.294118, - "opacity" : 0.0 + "specularCoef" : 35.294118 }, { @@ -34,8 +33,7 @@ "colorSpecular" : [0.14825, 0.14825, 0.14825], "illumination" : 2, "opticalDensity" : 1.0, - "specularCoef" : 15.686275, - "opacity" : 0.0 + "specularCoef" : 15.686275 }], "buffers": "veyron_wheel_bin.bin" From 7463dea1f8537f62e6b40e5328b988e39d19a9aa Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 8 Mar 2015 18:32:40 +0100 Subject: [PATCH 261/333] Updated builds. --- build/three.js | 6 ++++-- build/three.min.js | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/build/three.js b/build/three.js index 9484ccf52e3abb..d731683e47f135 100644 --- a/build/three.js +++ b/build/three.js @@ -11472,12 +11472,14 @@ THREE.Loader.prototype = { mpars.blending = THREE[ m.blending ]; } - + if ( m.transparent !== undefined ) { mpars.transparent = m.transparent; - } else if ( m.opacity < 1.0 ) { + } + + if ( m.opacity !== undefined && m.opacity < 1.0 ) { mpars.transparent = true; diff --git a/build/three.min.js b/build/three.min.js index dfc847dadbedb5..7823c76477e3f1 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -254,10 +254,10 @@ THREE.Loader.prototype={constructor:THREE.Loader,crossOrigin:void 0,addStatusEle "%"):b+((a.loaded/1024).toFixed(2)+" KB");this.statusDomElement.innerHTML=b},extractUrlBase:function(a){a=a.split("/");if(1===a.length)return"./";a.pop();return a.join("/")+"/"},initMaterials:function(a,b){for(var c=[],d=0;da.opacity&&(h.transparent=!0);void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide);void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe);void 0!==a.vertexColors&& -("face"===a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));void 0!==a.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),a.opacity=a.transparency);void 0!==a.opacity&&(h.opacity=a.opacity);a.specularCoef&&(h.shininess=a.specularCoef);a.mapDiffuse&& -b&&d(h,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&d(h,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&d(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&d(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&d(h,"specularMap",a.mapSpecular,a.mapSpecularRepeat, -a.mapSpecularOffset,a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapAlpha&&b&&d(h,"alphaMap",a.mapAlpha,a.mapAlphaRepeat,a.mapAlphaOffset,a.mapAlphaWrap,a.mapAlphaAnisotropy);a.mapBumpScale&&(h.bumpScale=a.mapBumpScale);a.mapNormalFactor&&(h.normalScale=new THREE.Vector2(a.mapNormalFactor,a.mapNormalFactor));g=new THREE[g](h);void 0!==a.DbgName&&(g.name=a.DbgName);return g}}; +"basic"===k&&(g="MeshBasicMaterial")}void 0!==a.blending&&void 0!==THREE[a.blending]&&(h.blending=THREE[a.blending]);void 0!==a.transparent&&(h.transparent=a.transparent);void 0!==a.opacity&&1>a.opacity&&(h.transparent=!0);void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide);void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe); +void 0!==a.vertexColors&&("face"===a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));void 0!==a.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),a.opacity=a.transparency);void 0!==a.opacity&&(h.opacity=a.opacity);a.specularCoef&&(h.shininess= +a.specularCoef);a.mapDiffuse&&b&&d(h,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&d(h,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&d(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&d(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&d(h,"specularMap", +a.mapSpecular,a.mapSpecularRepeat,a.mapSpecularOffset,a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapAlpha&&b&&d(h,"alphaMap",a.mapAlpha,a.mapAlphaRepeat,a.mapAlphaOffset,a.mapAlphaWrap,a.mapAlphaAnisotropy);a.mapBumpScale&&(h.bumpScale=a.mapBumpScale);a.mapNormalFactor&&(h.normalScale=new THREE.Vector2(a.mapNormalFactor,a.mapNormalFactor));g=new THREE[g](h);void 0!==a.DbgName&&(g.name=a.DbgName);return g}}; THREE.Loader.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=0,c=this.handlers.length;b Date: Mon, 9 Mar 2015 17:18:37 +0100 Subject: [PATCH 262/333] Fixed incorrect combine parameter. Thanks @redsolarmoon. --- examples/webgl_effects_parallaxbarrier.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/webgl_effects_parallaxbarrier.html b/examples/webgl_effects_parallaxbarrier.html index 00e8501ab0b597..b28f44ff967256 100644 --- a/examples/webgl_effects_parallaxbarrier.html +++ b/examples/webgl_effects_parallaxbarrier.html @@ -36,7 +36,7 @@

    - three.js webgl - effects - parallax barrier. + three.js webgl - effects - parallax barrier. texture by Humus : Bugatti Veyron model @@ -245,7 +245,7 @@ "Carmine": new THREE.MeshPhongMaterial( { color: 0x770000, specular:0xffaaaa, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Gold": new THREE.MeshPhongMaterial( { color: 0xaa9944, specular:0xbbaa99, shininess:50, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Bronze": new THREE.MeshPhongMaterial( { color: 0x150505, specular:0xee6600, shininess:10, envMap: textureCube, combine: THREE.MixOperation, reflectivity: 0.25 } ), - "Chrome": new THREE.MeshPhongMaterial( { color: 0xffffff, specular:0xffffff, envMap: textureCube, combine: THREE.Multiply } ), + "Chrome": new THREE.MeshPhongMaterial( { color: 0xffffff, specular:0xffffff, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Orange metal": new THREE.MeshLambertMaterial( { color: 0xff6600, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Blue metal": new THREE.MeshLambertMaterial( { color: 0x001133, envMap: textureCube, combine: THREE.MultiplyOperation } ), From 133e5390dd160563d89a80c5a17f24b3df5f6738 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 9 Mar 2015 13:37:30 -0400 Subject: [PATCH 263/333] Fix note #2 of https://github.com/mrdoob/three.js/pull/5805#issuecomment-75610227 --- .../shaders/ShaderChunk/linear_to_gamma_fragment.glsl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl b/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl index 3d40053aa55ba9..365c6dd0a2aacd 100644 --- a/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl @@ -1 +1,2 @@ - outgoingLight.xyz = linearToOutput( outgoingLight.xyz ); \ No newline at end of file + + outgoingLight = linearToOutput( outgoingLight ); From 8cb82c88109537090b2fa82d397f8f79e7005d52 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 9 Mar 2015 13:37:46 -0400 Subject: [PATCH 264/333] Fix note #5 of https://github.com/mrdoob/three.js/pull/5805#issuecomment-75610227 --- src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 0c2df89544ed19..5395e8cf0156be 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -227,6 +227,6 @@ vec3 totalSpecularLight = vec3( 0.0 ); #else - outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight + emissive; + outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive; #endif From 47b7f88ba745586dd34edeb444c216c9f29eb247 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 9 Mar 2015 13:38:41 -0400 Subject: [PATCH 265/333] Fix note #3 of https://github.com/mrdoob/three.js/pull/5805#issuecomment-75610227 --- examples/js/ShaderSkin.js | 6 +++--- examples/js/shaders/NormalDisplacementShader.js | 6 +++--- src/renderers/shaders/ShaderChunk/envmap_fragment.glsl | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 72a3dc0767dddb..668fbf40aca3b2 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -269,7 +269,7 @@ THREE.ShaderSkin = { "#endif", - "outgoingLight.xyz += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;", + "outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;", THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "linear_to_gamma_fragment" ], @@ -526,11 +526,11 @@ THREE.ShaderSkin = { "#ifdef VERSION1", - "vec3 nonblurColor = sqrt(outgoingLight.xyz );", + "vec3 nonblurColor = sqrt(outgoingLight );", "#else", - "vec3 nonblurColor = outgoingLight.xyz;", + "vec3 nonblurColor = outgoingLight;", "#endif", diff --git a/examples/js/shaders/NormalDisplacementShader.js b/examples/js/shaders/NormalDisplacementShader.js index 1537d0d84ce2e2..b30a941a9833b1 100644 --- a/examples/js/shaders/NormalDisplacementShader.js +++ b/examples/js/shaders/NormalDisplacementShader.js @@ -387,11 +387,11 @@ THREE.NormalDisplacementShader = { " #ifdef METAL", - " outgoingLight.xyz += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse + totalSpecularLight );", + " outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse + totalSpecularLight );", " #else", - " outgoingLight.xyz += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;", + " outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;", " #endif", @@ -417,7 +417,7 @@ THREE.NormalDisplacementShader = { " #endif", - " outgoingLight.xyz = mix( outgoingLight.xyz, cubeColor.xyz, specularTex.r * reflectivity );", + " outgoingLight = mix( outgoingLight.xyz, cubeColor.xyz, specularTex.r * reflectivity );", " }", diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl index 09407c1fb1d8c1..7c930647da0e6c 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl @@ -37,7 +37,7 @@ sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 ); sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5; vec4 envColor = texture2D( envMap, sampleUV ); - + #elif defined( ENVMAP_TYPE_SPHERE ) vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0)); vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 ); @@ -47,15 +47,15 @@ #ifdef ENVMAP_BLENDING_MULTIPLY - outgoingLight.xyz = mix( outgoingLight.xyz, outgoingLight.xyz * envColor.xyz, specularStrength * reflectivity ); + outgoingLight = mix( outgoingLight, outgoingLight. * envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_MIX ) - outgoingLight.xyz = mix( outgoingLight.xyz, envColor.xyz, specularStrength * reflectivity ); + outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_ADD ) - outgoingLight.xyz += envColor.xyz * specularStrength * reflectivity; + outgoingLight += envColor.xyz * specularStrength * reflectivity; #endif From 7fe874e4e1e9ccdfb1a2c476c15be18e95b9fa31 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 9 Mar 2015 13:38:51 -0400 Subject: [PATCH 266/333] Fix note #1 of https://github.com/mrdoob/three.js/pull/5805#issuecomment-75610227 --- src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl index 6e373629889276..586e98270fe641 100644 --- a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl @@ -1,5 +1,5 @@ #ifdef USE_LIGHTMAP - outgoingLight += diffuseColor.xyz * texture2D( lightMap, vUv2 ).xyz; + outgoingLight *= diffuseColor.xyz * texture2D( lightMap, vUv2 ).xyz; #endif \ No newline at end of file From 2ba715f2edba1a83989535f33fefefdb867c44b7 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 9 Mar 2015 13:39:41 -0400 Subject: [PATCH 267/333] Fix note #3 of issue https://github.com/mrdoob/three.js/pull/5805#issuecomment-75610227 --- examples/js/ShaderTerrain.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index 7c336c26042943..004a26a8cbc01e 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -253,7 +253,7 @@ THREE.ShaderTerrain = { "#endif", - "outgoingLight.rgb += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse + totalSpecularLight );", + "outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse + totalSpecularLight );", THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "linear_to_gamma_fragment" ], From b0eb1bf216b77729f1a056fc5a05ff6bbf6d198e Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 9 Mar 2015 13:40:05 -0400 Subject: [PATCH 268/333] Fix node #6 of issue https://github.com/mrdoob/three.js/pull/5805#issuecomment-75610227 --- examples/js/ShaderTerrain.js | 2 +- examples/js/shaders/NormalDisplacementShader.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index 004a26a8cbc01e..d0cecc3f07ed3d 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -253,7 +253,7 @@ THREE.ShaderTerrain = { "#endif", - "outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse + totalSpecularLight );", + "outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + totalSpecularLight );", THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "linear_to_gamma_fragment" ], diff --git a/examples/js/shaders/NormalDisplacementShader.js b/examples/js/shaders/NormalDisplacementShader.js index b30a941a9833b1..8ee897a56093ff 100644 --- a/examples/js/shaders/NormalDisplacementShader.js +++ b/examples/js/shaders/NormalDisplacementShader.js @@ -391,7 +391,7 @@ THREE.NormalDisplacementShader = { " #else", - " outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;", + " outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight;", " #endif", From 98f65da002bb9254e15fa6483f3e90a7307657dc Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 9 Mar 2015 13:41:01 -0400 Subject: [PATCH 269/333] Fix node #3 of issue https://github.com/mrdoob/three.js/pull/5805#issuecomment-75610227 --- src/renderers/shaders/ShaderLib.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 57c058bca47f50..74c4b1c8224fb9 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -87,7 +87,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], - " outgoingLight.rgb = diffuseColor.rgb;", // simple shader + " outgoingLight = diffuseColor.rgb;", // simple shader THREE.ShaderChunk[ "lightmap_fragment" ], // TODO: Light map on an otherwise unlit surface doesn't make sense. THREE.ShaderChunk[ "envmap_fragment" ], @@ -196,7 +196,7 @@ THREE.ShaderLib = { " vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );", // outgoing light does not have an alpha, the surface does " vec4 diffuseColor = vec4( 1.0, 1.0, 1.0, opacity );", - + THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], THREE.ShaderChunk[ "color_fragment" ], @@ -421,7 +421,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], - " outgoingLight.rgb = diffuseColor.rgb;", // simple shader + " outgoingLight = diffuseColor.rgb;", // simple shader THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], @@ -713,7 +713,7 @@ THREE.ShaderLib = { "vec3 direction = normalize( vWorldPosition );", "vec2 sampleUV;", "sampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );", - "sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", + "sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", "gl_FragColor = texture2D( tEquirect, sampleUV );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], From 2d218c64027985886fae78720cbc3a485b8df8b7 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 9 Mar 2015 14:00:45 -0400 Subject: [PATCH 270/333] clean up lightmap example to make it look more attractive with normal lighting. --- examples/webgl_materials_lightmap.html | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/webgl_materials_lightmap.html b/examples/webgl_materials_lightmap.html index 0d4887a062c474..7b845ddc3b0cbe 100644 --- a/examples/webgl_materials_lightmap.html +++ b/examples/webgl_materials_lightmap.html @@ -100,15 +100,13 @@ // LIGHTS - var directionalLight = new THREE.DirectionalLight( 0x333333, 1.475 ); + var directionalLight = new THREE.DirectionalLight( 0x333333, 2 ); directionalLight.position.set( 100, 100, -100 ); scene.add( directionalLight ); - var hemiLight = new THREE.HemisphereLight( 0x333333, 0x333333, 1.25 ); - hemiLight.color.setHSL( 0.6, 1, 0.375 ); - hemiLight.groundColor.setHSL( 0.1, 0.8, 0.35 ); - + var hemiLight = new THREE.HemisphereLight( 0xaabbff, 0x040404, 1 ); + hemiLight.position.y = 500; scene.add( hemiLight ); From bb71476f385cdc8d163c643ffca7df4501c9756e Mon Sep 17 00:00:00 2001 From: brason Date: Mon, 9 Mar 2015 22:14:35 +0100 Subject: [PATCH 271/333] Fixed small typo --- src/renderers/WebGLRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 998bbaccd203a9..8bf5ed92afe555 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2590,7 +2590,7 @@ THREE.WebGLRenderer = function ( parameters ) { _this.info.render.calls ++; _this.info.render.vertices += position.array.length / position.itemSize; - _this.info.render.faces += position.array.length / ( 3 * position.itemsize ); + _this.info.render.faces += position.array.length / ( 3 * position.itemSize ); } From 8e326bdf1ea5420f948da5e4f24b960d1ae73859 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Mar 2015 22:36:28 +0100 Subject: [PATCH 272/333] Editor: Removed unneeded selectionBox update. --- editor/js/Viewport.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/editor/js/Viewport.js b/editor/js/Viewport.js index 79313be553b3cf..c64630885aa3a5 100644 --- a/editor/js/Viewport.js +++ b/editor/js/Viewport.js @@ -370,12 +370,6 @@ var Viewport = function ( editor ) { transformControls.update(); - if ( object.geometry !== undefined ) { - - selectionBox.update( object ); - - } - if ( object instanceof THREE.PerspectiveCamera ) { object.updateProjectionMatrix(); From 46a5ec01157be229e8820830ad424fbe5eb8680d Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Mar 2015 22:51:04 +0100 Subject: [PATCH 273/333] WebGLRenderer: gl.bufferSubData doesn't seem to work with gl.STATIC_DRAW. --- src/renderers/WebGLRenderer.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 998bbaccd203a9..98683b7951207d 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3939,7 +3939,15 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute.updateRange === undefined || attribute.updateRange.count === -1 ) { // Not using update ranges - _gl.bufferSubData( bufferType, 0, attribute.array ); + if ( attribute instanceof THREE.DynamicBufferAttribute ) { + + _gl.bufferSubData( bufferType, 0, attribute.array ); + + } else { + + _gl.bufferData( bufferType, attribute.array, _gl.STATIC_DRAW ); + + } } else if ( attribute.updateRange.count === 0 ) { From abb1b9ef1174817b6b2a651d56a7c7ff3c751be8 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Mar 2015 22:52:02 +0100 Subject: [PATCH 274/333] Geometry: Simplified .center() --- src/core/Geometry.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/core/Geometry.js b/src/core/Geometry.js index 76b52321f1acc3..55ec6acbc22ed9 100644 --- a/src/core/Geometry.js +++ b/src/core/Geometry.js @@ -81,18 +81,21 @@ THREE.Geometry.prototype = { } - if ( this.boundingBox instanceof THREE.Box3 ) { + if ( this.boundingBox !== null ) { this.computeBoundingBox(); } - if ( this.boundingSphere instanceof THREE.Sphere ) { + if ( this.boundingSphere !== null ) { this.computeBoundingSphere(); } + this.verticesNeedUpdate = true; + this.normalsNeedUpdate = true; + }, fromBufferGeometry: function ( geometry ) { @@ -189,13 +192,9 @@ THREE.Geometry.prototype = { this.computeBoundingBox(); - var offset = new THREE.Vector3(); - - offset.addVectors( this.boundingBox.min, this.boundingBox.max ); - offset.multiplyScalar( - 0.5 ); + var offset = this.boundingBox.center().negate(); - this.applyMatrix( new THREE.Matrix4().makeTranslation( offset.x, offset.y, offset.z ) ); - this.computeBoundingBox(); + this.applyMatrix( new THREE.Matrix4().setPosition( offset ) ); return offset; From ddb00d1ad17dd29ef68304f22ed9b9120a9320ff Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Mar 2015 22:52:18 +0100 Subject: [PATCH 275/333] BufferGeometry: Implemented .center() --- src/core/BufferGeometry.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index fbf6968b1f9201..14bfe1a97cd0e1 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -84,13 +84,13 @@ THREE.BufferGeometry.prototype = { } - if ( this.boundingBox instanceof THREE.Box3 ) { + if ( this.boundingBox !== null ) { this.computeBoundingBox(); } - if ( this.boundingSphere instanceof THREE.Sphere ) { + if ( this.boundingSphere !== null ) { this.computeBoundingSphere(); @@ -100,7 +100,13 @@ THREE.BufferGeometry.prototype = { center: function () { - // TODO + this.computeBoundingBox(); + + var offset = this.boundingBox.center().negate(); + + this.applyMatrix( new THREE.Matrix4().setPosition( offset ) ); + + return offset; }, From 6a1ed12243d76802414c1d9d90df23a873ee8dce Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Mar 2015 22:52:41 +0100 Subject: [PATCH 276/333] Editor: Added Center Action to Geometry panel. --- editor/js/Sidebar.Geometry.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/editor/js/Sidebar.Geometry.js b/editor/js/Sidebar.Geometry.js index bc3efd9e40e1be..e051c66a1b2274 100644 --- a/editor/js/Sidebar.Geometry.js +++ b/editor/js/Sidebar.Geometry.js @@ -17,13 +17,14 @@ Sidebar.Geometry = function ( editor ) { var geometryType = new UI.Text().setTextTransform( 'uppercase' ); container.addStatic( geometryType ); - + // Actions - + var objectActions = new UI.Select().setPosition('absolute').setRight( '8px' ).setFontSize( '11px' ); objectActions.setOptions( { 'Actions': 'Actions', + 'Center': 'Center', 'Flatten': 'Flatten' } ); @@ -34,26 +35,35 @@ Sidebar.Geometry = function ( editor ) { } ); objectActions.onChange( function ( event ) { + var action = this.getValue(); + var object = editor.selected; + var geometry = object.geometry; - switch ( this.getValue() ) { + if ( confirm( action + ' ' + object.name + '?' ) === false ) return; - case 'Flatten': + switch ( action ) { + + case 'Center': - var object = editor.selected; + var offset = geometry.center(); - if ( confirm( 'Flatten ' + object.name + '?' ) === false ) return; + object.position.sub( offset ); - var geometry = object.geometry; + editor.signals.geometryChanged.dispatch( geometry ); + editor.signals.objectChanged.dispatch( object ); + + break; + + case 'Flatten': geometry.applyMatrix( object.matrix ); - geometry.verticesNeedUpdate = true; - geometry.normalsNeedUpdate = true; object.position.set( 0, 0, 0 ); object.rotation.set( 0, 0, 0 ); object.scale.set( 1, 1, 1 ); + editor.signals.geometryChanged.dispatch( geometry ); editor.signals.objectChanged.dispatch( object ); break; From 5714eaf10a2c895830dbe44d7328a4236d96ede6 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Mar 2015 22:55:48 +0100 Subject: [PATCH 277/333] WebGLRenderer: Reverted bufferSubData change. Doesn't seem to solve my issue. --- src/renderers/WebGLRenderer.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 98683b7951207d..998bbaccd203a9 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3939,15 +3939,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( attribute.updateRange === undefined || attribute.updateRange.count === -1 ) { // Not using update ranges - if ( attribute instanceof THREE.DynamicBufferAttribute ) { - - _gl.bufferSubData( bufferType, 0, attribute.array ); - - } else { - - _gl.bufferData( bufferType, attribute.array, _gl.STATIC_DRAW ); - - } + _gl.bufferSubData( bufferType, 0, attribute.array ); } else if ( attribute.updateRange.count === 0 ) { From fee2c405c50de8d7df3ef8ba833e84d9c305c5f3 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Mon, 9 Mar 2015 22:56:38 +0100 Subject: [PATCH 278/333] Updated builds. --- build/three.js | 35 ++++++++++----------- build/three.min.js | 78 +++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 57 deletions(-) diff --git a/build/three.js b/build/three.js index d731683e47f135..5477219052f46d 100644 --- a/build/three.js +++ b/build/three.js @@ -8557,13 +8557,13 @@ THREE.BufferGeometry.prototype = { } - if ( this.boundingBox instanceof THREE.Box3 ) { + if ( this.boundingBox !== null ) { this.computeBoundingBox(); } - if ( this.boundingSphere instanceof THREE.Sphere ) { + if ( this.boundingSphere !== null ) { this.computeBoundingSphere(); @@ -8573,7 +8573,13 @@ THREE.BufferGeometry.prototype = { center: function () { - // TODO + this.computeBoundingBox(); + + var offset = this.boundingBox.center().negate(); + + this.applyMatrix( new THREE.Matrix4().setPosition( offset ) ); + + return offset; }, @@ -9369,13 +9375,7 @@ THREE.BufferGeometry.prototype = { var attribute = attributes[ key ]; - var array = [], typeArray = attribute.array; - - for ( var i = 0, l = typeArray.length; i < l; i ++ ) { - - array[ i ] = typeArray[ i ]; - - } + var array = Array.prototype.slice.call( attribute.array ); output.data.attributes[ key ] = { itemSize: attribute.itemSize, @@ -9528,18 +9528,21 @@ THREE.Geometry.prototype = { } - if ( this.boundingBox instanceof THREE.Box3 ) { + if ( this.boundingBox !== null ) { this.computeBoundingBox(); } - if ( this.boundingSphere instanceof THREE.Sphere ) { + if ( this.boundingSphere !== null ) { this.computeBoundingSphere(); } + this.verticesNeedUpdate = true; + this.normalsNeedUpdate = true; + }, fromBufferGeometry: function ( geometry ) { @@ -9636,13 +9639,9 @@ THREE.Geometry.prototype = { this.computeBoundingBox(); - var offset = new THREE.Vector3(); - - offset.addVectors( this.boundingBox.min, this.boundingBox.max ); - offset.multiplyScalar( - 0.5 ); + var offset = this.boundingBox.center().negate(); - this.applyMatrix( new THREE.Matrix4().makeTranslation( offset.x, offset.y, offset.z ) ); - this.computeBoundingBox(); + this.applyMatrix( new THREE.Matrix4().setPosition( offset ) ); return offset; diff --git a/build/three.min.js b/build/three.min.js index 7823c76477e3f1..99a89150589a76 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -185,47 +185,47 @@ THREE.Uint32Attribute=function(a,b){THREE.warn("THREE.Uint32Attribute has been r THREE.Float64Attribute=function(a,b){THREE.warn("THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.");return new THREE.BufferAttribute(a,b)};THREE.DynamicBufferAttribute=function(a,b){THREE.BufferAttribute.call(this,a,b);this.updateRange={offset:0,count:-1}};THREE.DynamicBufferAttribute.prototype=Object.create(THREE.BufferAttribute.prototype);THREE.DynamicBufferAttribute.prototype.constructor=THREE.DynamicBufferAttribute; THREE.DynamicBufferAttribute.prototype.clone=function(){return new THREE.DynamicBufferAttribute(new this.array.constructor(this.array),this.itemSize)};THREE.BufferGeometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="BufferGeometry";this.attributes={};this.attributesKeys=[];this.offsets=this.drawcalls=[];this.boundingSphere=this.boundingBox=null}; THREE.BufferGeometry.prototype={constructor:THREE.BufferGeometry,addAttribute:function(a,b,c){!1===b instanceof THREE.BufferAttribute?(THREE.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),this.attributes[a]={array:b,itemSize:c}):(this.attributes[a]=b,this.attributesKeys=Object.keys(this.attributes))},getAttribute:function(a){return this.attributes[a]},addDrawCall:function(a,b,c){this.drawcalls.push({start:a,count:b,index:void 0!==c?c:0})},applyMatrix:function(a){var b= -this.attributes.position;void 0!==b&&(a.applyToVector3Array(b.array),b.needsUpdate=!0);b=this.attributes.normal;void 0!==b&&((new THREE.Matrix3).getNormalMatrix(a).applyToVector3Array(b.array),b.needsUpdate=!0);this.boundingBox instanceof THREE.Box3&&this.computeBoundingBox();this.boundingSphere instanceof THREE.Sphere&&this.computeBoundingSphere()},center:function(){},fromGeometry:function(a,b){b=b||{vertexColors:THREE.NoColors};var c=a.vertices,d=a.faces,e=a.faceVertexUvs,f=b.vertexColors,g=0qa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()"); -else{var c=this.attributes.index.array,d=this.attributes.position.array,e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+ -b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array, -f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hqa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal|| +void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array,e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.", +a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x, +w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f= +a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;c Date: Mon, 9 Mar 2015 23:57:22 +0100 Subject: [PATCH 279/333] Fixed envmap_fragment typo. --- src/renderers/shaders/ShaderChunk/envmap_fragment.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl index 7c930647da0e6c..28b50198adff4a 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl @@ -47,7 +47,7 @@ #ifdef ENVMAP_BLENDING_MULTIPLY - outgoingLight = mix( outgoingLight, outgoingLight. * envColor.xyz, specularStrength * reflectivity ); + outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_MIX ) From 9d7c12628ed63fbc8f32cbc8f4d0c958e3210b74 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 10 Mar 2015 00:12:42 +0100 Subject: [PATCH 280/333] Updated builds. --- build/three.js | 75 +++++++++++++++++++++++++++++----------------- build/three.min.js | 69 +++++++++++++++++++++--------------------- 2 files changed, 83 insertions(+), 61 deletions(-) diff --git a/build/three.js b/build/three.js index 5477219052f46d..20166830921787 100644 --- a/build/three.js +++ b/build/three.js @@ -16571,7 +16571,7 @@ THREE.ShaderChunk[ 'common'] = "#define PI 3.14159\n#define PI2 6.28318\n#define // File:src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl -THREE.ShaderChunk[ 'alphatest_fragment'] = "#ifdef ALPHATEST\n\n if ( gl_FragColor.a < ALPHATEST ) discard;\n\n#endif\n"; +THREE.ShaderChunk[ 'alphatest_fragment'] = "#ifdef ALPHATEST\n\n if ( diffuseColor.a < ALPHATEST ) discard;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -16603,7 +16603,7 @@ THREE.ShaderChunk[ 'lightmap_pars_vertex'] = "#ifdef USE_LIGHTMAP\n\n varying ve // File:src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_fragment'] = "#ifndef FLAT_SHADED\n\n vec3 normal = normalize( vNormal );\n\n #ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n #endif\n\n#else\n\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n vec3 pointDiffuse = vec3( 0.0 );\n vec3 pointSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n vec3 spotDiffuse = vec3( 0.0 );\n vec3 spotSpecular = vec3( 0.0 );\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n vec3 dirDiffuse = vec3( 0.0 );\n vec3 dirSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n vec3 hemiDiffuse = vec3( 0.0 );\n vec3 hemiSpecular = vec3( 0.0 );\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n hemiDiffuse += diffuse * hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n totalDiffuse += dirDiffuse;\n totalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n totalDiffuse += hemiDiffuse;\n totalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n totalDiffuse += pointDiffuse;\n totalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n totalDiffuse += spotDiffuse;\n totalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif\n"; +THREE.ShaderChunk[ 'lights_phong_fragment'] = "#ifndef FLAT_SHADED\n\n vec3 normal = normalize( vNormal );\n\n #ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n #endif\n\n#else\n\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\nvec3 totalDiffuseLight = vec3( 0.0 );\nvec3 totalSpecularLight = vec3( 0.0 );\n\n#if MAX_POINT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n totalDiffuseLight += hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\n#ifdef METAL\n\n outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * diffuse ) * specular + totalSpecularLight + emissive;\n\n#else\n\n outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl @@ -16643,7 +16643,7 @@ THREE.ShaderChunk[ 'lights_phong_vertex'] = "#if MAX_SPOT_LIGHTS > 0 || defined( // File:src/renderers/shaders/ShaderChunk/map_fragment.glsl -THREE.ShaderChunk[ 'map_fragment'] = "#ifdef USE_MAP\n\n vec4 texelColor = texture2D( map, vUv );\n\n texelColor.xyz = inputToLinear( texelColor.xyz );\n\n gl_FragColor = gl_FragColor * texelColor;\n\n#endif"; +THREE.ShaderChunk[ 'map_fragment'] = "#ifdef USE_MAP\n\n vec4 texelColor = texture2D( map, vUv );\n\n texelColor.xyz = inputToLinear( texelColor.xyz );\n\n diffuseColor *= texelColor;\n\n#endif"; // File:src/renderers/shaders/ShaderChunk/lightmap_vertex.glsl @@ -16651,7 +16651,7 @@ THREE.ShaderChunk[ 'lightmap_vertex'] = "#ifdef USE_LIGHTMAP\n\n vUv2 = uv2;\n\n // File:src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl -THREE.ShaderChunk[ 'map_particle_fragment'] = "#ifdef USE_MAP\n\n gl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\n#endif\n"; +THREE.ShaderChunk[ 'map_particle_fragment'] = "#ifdef USE_MAP\n\n diffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl @@ -16671,7 +16671,7 @@ THREE.ShaderChunk[ 'envmap_pars_vertex'] = "#if defined( USE_ENVMAP ) && ! defin // File:src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl -THREE.ShaderChunk[ 'linear_to_gamma_fragment'] = "\n gl_FragColor.xyz = linearToOutput( gl_FragColor.xyz );\n"; +THREE.ShaderChunk[ 'linear_to_gamma_fragment'] = "\n outgoingLight = linearToOutput( outgoingLight );\n"; // File:src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl @@ -16687,7 +16687,7 @@ THREE.ShaderChunk[ 'map_pars_vertex'] = "#if defined( USE_MAP ) || defined( USE_ // File:src/renderers/shaders/ShaderChunk/envmap_fragment.glsl -THREE.ShaderChunk[ 'envmap_fragment'] = "#ifdef USE_ENVMAP\n\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n // Transforming Normal Vectors with the Inverse Transformation\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n #ifdef ENVMAP_MODE_REFLECTION\n\n vec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n #else\n\n vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n #endif\n\n #else\n\n vec3 reflectVec = vReflect;\n\n #endif\n\n #ifdef DOUBLE_SIDED\n float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n #else\n float flipNormal = 1.0;\n #endif\n\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n vec4 envColor = texture2D( envMap, sampleUV );\n \n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n #endif\n\n envColor.xyz = inputToLinear( envColor.xyz );\n\n #ifdef ENVMAP_BLENDING_MULTIPLY\n\n gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_MIX )\n\n gl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_ADD )\n\n gl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;\n\n #endif\n\n#endif\n"; +THREE.ShaderChunk[ 'envmap_fragment'] = "#ifdef USE_ENVMAP\n\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n // Transforming Normal Vectors with the Inverse Transformation\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n #ifdef ENVMAP_MODE_REFLECTION\n\n vec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n #else\n\n vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n #endif\n\n #else\n\n vec3 reflectVec = vReflect;\n\n #endif\n\n #ifdef DOUBLE_SIDED\n float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n #else\n float flipNormal = 1.0;\n #endif\n\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n vec4 envColor = texture2D( envMap, sampleUV );\n\n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n #endif\n\n envColor.xyz = inputToLinear( envColor.xyz );\n\n #ifdef ENVMAP_BLENDING_MULTIPLY\n\n outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_MIX )\n\n outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\n #elif defined( ENVMAP_BLENDING_ADD )\n\n outgoingLight += envColor.xyz * specularStrength * reflectivity;\n\n #endif\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl @@ -16707,7 +16707,7 @@ THREE.ShaderChunk[ 'specularmap_fragment'] = "float specularStrength;\n\n#ifdef // File:src/renderers/shaders/ShaderChunk/fog_fragment.glsl -THREE.ShaderChunk[ 'fog_fragment'] = "#ifdef USE_FOG\n\n #ifdef USE_LOGDEPTHBUF_EXT\n\n float depth = gl_FragDepthEXT / gl_FragCoord.w;\n\n #else\n\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n\n #endif\n\n #ifdef FOG_EXP2\n\n float fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 );\n fogFactor = whiteCompliment( fogFactor );\n\n #else\n\n float fogFactor = smoothstep( fogNear, fogFar, depth );\n\n #endif\n \n gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n\n#endif"; +THREE.ShaderChunk[ 'fog_fragment'] = "#ifdef USE_FOG\n\n #ifdef USE_LOGDEPTHBUF_EXT\n\n float depth = gl_FragDepthEXT / gl_FragCoord.w;\n\n #else\n\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n\n #endif\n\n #ifdef FOG_EXP2\n\n float fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 );\n fogFactor = whiteCompliment( fogFactor );\n\n #else\n\n float fogFactor = smoothstep( fogNear, fogFar, depth );\n\n #endif\n \n outgoingLight = mix( outgoingLight, fogColor, fogFactor );\n\n#endif"; // File:src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl @@ -16731,7 +16731,7 @@ THREE.ShaderChunk[ 'map_vertex'] = "#if defined( USE_MAP ) || defined( USE_BUMPM // File:src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl -THREE.ShaderChunk[ 'lightmap_fragment'] = "#ifdef USE_LIGHTMAP\n\n gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );\n\n#endif"; +THREE.ShaderChunk[ 'lightmap_fragment'] = "#ifdef USE_LIGHTMAP\n\n outgoingLight *= diffuseColor.xyz * texture2D( lightMap, vUv2 ).xyz;\n\n#endif"; // File:src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl @@ -16739,7 +16739,7 @@ THREE.ShaderChunk[ 'shadowmap_pars_vertex'] = "#ifdef USE_SHADOWMAP\n\n varying // File:src/renderers/shaders/ShaderChunk/color_fragment.glsl -THREE.ShaderChunk[ 'color_fragment'] = "#ifdef USE_COLOR\n\n gl_FragColor = gl_FragColor * vec4( vColor, 1.0 );\n\n#endif"; +THREE.ShaderChunk[ 'color_fragment'] = "#ifdef USE_COLOR\n\n diffuseColor.rgb *= vColor;\n\n#endif"; // File:src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl @@ -16751,7 +16751,7 @@ THREE.ShaderChunk[ 'envmap_vertex'] = "#if defined( USE_ENVMAP ) && ! defined( U // File:src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl -THREE.ShaderChunk[ 'shadowmap_fragment'] = "#ifdef USE_SHADOWMAP\n\n #ifdef SHADOWMAP_DEBUG\n\n vec3 frustumColors[3];\n frustumColors[0] = vec3( 1.0, 0.5, 0.0 );\n frustumColors[1] = vec3( 0.0, 1.0, 0.8 );\n frustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n\n #endif\n\n #ifdef SHADOWMAP_CASCADE\n\n int inFrustumCount = 0;\n\n #endif\n\n float fDepth;\n vec3 shadowColor = vec3( 1.0 );\n\n for( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n // if ( something && something ) breaks ATI OpenGL shader compiler\n // if ( all( something, something ) ) using this instead\n\n bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n bool inFrustum = all( inFrustumVec );\n\n // don't shadow pixels outside of light frustum\n // use just first frustum (for cascades)\n // don't shadow pixels behind far plane of light frustum\n\n #ifdef SHADOWMAP_CASCADE\n\n inFrustumCount += int( inFrustum );\n bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n\n #else\n\n bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n #endif\n\n bool frustumTest = all( frustumTestVec );\n\n if ( frustumTest ) {\n\n shadowCoord.z += shadowBias[ i ];\n\n #if defined( SHADOWMAP_TYPE_PCF )\n\n // Percentage-close filtering\n // (9 pixel kernel)\n // http://fabiensanglard.net/shadowmappingPCF/\n\n float shadow = 0.0;\n\n /*\n // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL\n // must enroll loop manually\n\n for ( float y = -1.25; y <= 1.25; y += 1.25 )\n for ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n\n // doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup\n //vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );\n\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n shadow += 1.0;\n\n }\n\n shadow /= 9.0;\n\n */\n\n const float shadowDelta = 1.0 / 9.0;\n\n float xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n float yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n float dx0 = -1.25 * xPixelOffset;\n float dy0 = -1.25 * yPixelOffset;\n float dx1 = 1.25 * xPixelOffset;\n float dy1 = 1.25 * yPixelOffset;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n // Percentage-close filtering\n // (9 pixel kernel)\n // http://fabiensanglard.net/shadowmappingPCF/\n\n float shadow = 0.0;\n\n float xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n float yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n float dx0 = -1.0 * xPixelOffset;\n float dy0 = -1.0 * yPixelOffset;\n float dx1 = 1.0 * xPixelOffset;\n float dy1 = 1.0 * yPixelOffset;\n\n mat3 shadowKernel;\n mat3 depthKernel;\n\n depthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n depthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n depthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n depthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n depthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n depthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n depthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n depthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n depthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n vec3 shadowZ = vec3( shadowCoord.z );\n shadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\n shadowKernel[0] *= vec3(0.25);\n\n shadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\n shadowKernel[1] *= vec3(0.25);\n\n shadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\n shadowKernel[2] *= vec3(0.25);\n\n vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\n\n shadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\n shadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\n\n vec4 shadowValues;\n shadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\n shadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\n shadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\n shadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\n\n shadow = dot( shadowValues, vec4( 1.0 ) );\n\n shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n #else\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n\n // spot with multiple shadows is darker\n\n shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n\n // spot with multiple shadows has the same color as single shadow spot\n\n // shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );\n\n #endif\n\n }\n\n\n #ifdef SHADOWMAP_DEBUG\n\n #ifdef SHADOWMAP_CASCADE\n\n if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n\n #else\n\n if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n\n #endif\n\n #endif\n\n }\n\n // NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014\n shadowColor = inputToLinear( shadowColor );\n\n gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n\n#endif\n"; +THREE.ShaderChunk[ 'shadowmap_fragment'] = "#ifdef USE_SHADOWMAP\n\n #ifdef SHADOWMAP_DEBUG\n\n vec3 frustumColors[3];\n frustumColors[0] = vec3( 1.0, 0.5, 0.0 );\n frustumColors[1] = vec3( 0.0, 1.0, 0.8 );\n frustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n\n #endif\n\n #ifdef SHADOWMAP_CASCADE\n\n int inFrustumCount = 0;\n\n #endif\n\n float fDepth;\n vec3 shadowColor = vec3( 1.0 );\n\n for( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n // if ( something && something ) breaks ATI OpenGL shader compiler\n // if ( all( something, something ) ) using this instead\n\n bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n bool inFrustum = all( inFrustumVec );\n\n // don't shadow pixels outside of light frustum\n // use just first frustum (for cascades)\n // don't shadow pixels behind far plane of light frustum\n\n #ifdef SHADOWMAP_CASCADE\n\n inFrustumCount += int( inFrustum );\n bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n\n #else\n\n bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n #endif\n\n bool frustumTest = all( frustumTestVec );\n\n if ( frustumTest ) {\n\n shadowCoord.z += shadowBias[ i ];\n\n #if defined( SHADOWMAP_TYPE_PCF )\n\n // Percentage-close filtering\n // (9 pixel kernel)\n // http://fabiensanglard.net/shadowmappingPCF/\n\n float shadow = 0.0;\n\n /*\n // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL\n // must enroll loop manually\n\n for ( float y = -1.25; y <= 1.25; y += 1.25 )\n for ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n\n // doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup\n //vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );\n\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n shadow += 1.0;\n\n }\n\n shadow /= 9.0;\n\n */\n\n const float shadowDelta = 1.0 / 9.0;\n\n float xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n float yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n float dx0 = -1.25 * xPixelOffset;\n float dy0 = -1.25 * yPixelOffset;\n float dx1 = 1.25 * xPixelOffset;\n float dy1 = 1.25 * yPixelOffset;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n if ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n // Percentage-close filtering\n // (9 pixel kernel)\n // http://fabiensanglard.net/shadowmappingPCF/\n\n float shadow = 0.0;\n\n float xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n float yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n float dx0 = -1.0 * xPixelOffset;\n float dy0 = -1.0 * yPixelOffset;\n float dx1 = 1.0 * xPixelOffset;\n float dy1 = 1.0 * yPixelOffset;\n\n mat3 shadowKernel;\n mat3 depthKernel;\n\n depthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n depthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n depthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n depthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n depthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n depthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n depthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n depthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n depthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n vec3 shadowZ = vec3( shadowCoord.z );\n shadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\n shadowKernel[0] *= vec3(0.25);\n\n shadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\n shadowKernel[1] *= vec3(0.25);\n\n shadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\n shadowKernel[2] *= vec3(0.25);\n\n vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\n\n shadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\n shadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\n\n vec4 shadowValues;\n shadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\n shadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\n shadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\n shadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\n\n shadow = dot( shadowValues, vec4( 1.0 ) );\n\n shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n #else\n\n vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n float fDepth = unpackDepth( rgbaDepth );\n\n if ( fDepth < shadowCoord.z )\n\n // spot with multiple shadows is darker\n\n shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n\n // spot with multiple shadows has the same color as single shadow spot\n\n // shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );\n\n #endif\n\n }\n\n\n #ifdef SHADOWMAP_DEBUG\n\n #ifdef SHADOWMAP_CASCADE\n\n if ( inFrustum && inFrustumCount == 1 ) outgoingLight *= frustumColors[ i ];\n\n #else\n\n if ( inFrustum ) outgoingLight *= frustumColors[ i ];\n\n #endif\n\n #endif\n\n }\n\n // NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014\n shadowColor = inputToLinear( shadowColor );\n\n outgoingLight = outgoingLight * shadowColor;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl @@ -16771,7 +16771,7 @@ THREE.ShaderChunk[ 'logdepthbuf_pars_fragment'] = "#ifdef USE_LOGDEPTHBUF\n\n un // File:src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl -THREE.ShaderChunk[ 'alphamap_fragment'] = "#ifdef USE_ALPHAMAP\n\n gl_FragColor.a *= texture2D( alphaMap, vUv ).g;\n\n#endif\n"; +THREE.ShaderChunk[ 'alphamap_fragment'] = "#ifdef USE_ALPHAMAP\n\n diffuseColor.a *= texture2D( alphaMap, vUv ).g;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/alphamap_pars_fragment.glsl @@ -17034,22 +17034,28 @@ THREE.ShaderLib = { "void main() {", - " gl_FragColor = vec4( diffuse, opacity );", + " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], + THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "alphamap_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], - THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], + + " outgoingLight = diffuseColor.rgb;", // simple shader + + THREE.ShaderChunk[ "lightmap_fragment" ], // TODO: Light map on an otherwise unlit surface doesn't make sense. THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], + THREE.ShaderChunk[ "shadowmap_fragment" ], // TODO: Shadows on an otherwise unlit surface doesn't make sense. THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -17145,10 +17151,12 @@ THREE.ShaderLib = { "void main() {", - " gl_FragColor = vec4( vec3( 1.0 ), opacity );", + " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( 1.0, 1.0, 1.0, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], + THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "alphamap_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], @@ -17159,18 +17167,17 @@ THREE.ShaderLib = { //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;", " if ( gl_FrontFacing )", - " gl_FragColor.xyz *= vLightFront;", + " outgoingLight += diffuseColor.rgb * vLightFront;", " else", - " gl_FragColor.xyz *= vLightBack;", + " outgoingLight += diffuseColor.rgb * vLightBack;", " #else", - " gl_FragColor.xyz *= vLightFront;", + " outgoingLight += diffuseColor.rgb * vLightFront;", " #endif", THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "envmap_fragment" ], THREE.ShaderChunk[ "shadowmap_fragment" ], @@ -17178,6 +17185,8 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -17287,10 +17296,12 @@ THREE.ShaderLib = { "void main() {", - " gl_FragColor = vec4( vec3( 1.0 ), opacity );", + " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], + THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "alphamap_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], @@ -17298,7 +17309,6 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "lights_phong_fragment" ], THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "envmap_fragment" ], THREE.ShaderChunk[ "shadowmap_fragment" ], @@ -17306,6 +17316,8 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -17367,15 +17379,21 @@ THREE.ShaderLib = { "void main() {", - " gl_FragColor = vec4( psColor, opacity );", + " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( psColor, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_particle_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "color_fragment" ], + THREE.ShaderChunk[ "alphatest_fragment" ], + + " outgoingLight = diffuseColor.rgb;", // simple shader + THREE.ShaderChunk[ "shadowmap_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -17446,12 +17464,15 @@ THREE.ShaderLib = { " }", - " gl_FragColor = vec4( diffuse, opacity );", + " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does + " vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "color_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], + " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + "}" ].join("\n") @@ -17508,7 +17529,7 @@ THREE.ShaderLib = { " #endif", " float color = 1.0 - smoothstep( mNear, mFar, depth );", - " gl_FragColor = vec4( vec3( color ), opacity );", + " gl_FragColor = vec4( vec3( color ), opacity );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects "}" @@ -20340,7 +20361,7 @@ THREE.WebGLRenderer = function ( parameters ) { _this.info.render.calls ++; _this.info.render.vertices += position.array.length / position.itemSize; - _this.info.render.faces += position.array.length / ( 3 * position.itemsize ); + _this.info.render.faces += position.array.length / ( 3 * position.itemSize ); } diff --git a/build/three.min.js b/build/three.min.js index 99a89150589a76..4933eef4d48b93 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -385,29 +385,29 @@ THREE.LensFlare.prototype.add=function(a,b,c,d,e,f){void 0===b&&(b=-1);void 0=== THREE.LensFlare.prototype.updateLensFlares=function(){var a,b=this.lensFlares.length,c,d=2*-this.positionScreen.x,e=2*-this.positionScreen.y;for(a=0;a 0.0 ) {\n\t return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent );\n\t}\n\treturn 1.0;\n}\n\nvec3 inputToLinear( in vec3 a ) {\n#ifdef GAMMA_INPUT\n\treturn pow( a, vec3( float( GAMMA_FACTOR ) ) );\n#else\n\treturn a;\n#endif\n}\nvec3 linearToOutput( in vec3 a ) {\n#ifdef GAMMA_OUTPUT\n\treturn pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );\n#else\n\treturn a;\n#endif\n}\n"; -THREE.ShaderChunk.alphatest_fragment="#ifdef ALPHATEST\n\n\tif ( gl_FragColor.a < ALPHATEST ) discard;\n\n#endif\n";THREE.ShaderChunk.lights_lambert_vertex="vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\tfloat dotProduct = dot( transformedNormal, dirVector );\n\tvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t#endif\n\n\t#endif\n\n\t#ifdef WRAP_AROUND\n\n\t\tvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\tdirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tdirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n\t\t#endif\n\n\t#endif\n\n\tvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n\t#endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\tpointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tpointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\tvLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n\t\t#endif\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\t\tlVector = normalize( lVector );\n\n\t\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\t\t\tvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\t\tvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\t\tspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n\t\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\t\tspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\tvLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n\t\t\t#endif\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\t\tfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n\t\tvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n\t\t#endif\n\n\t}\n\n#endif\n\nvLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive;\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive;\n\n#endif\n"; +THREE.ShaderChunk.alphatest_fragment="#ifdef ALPHATEST\n\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n\n#endif\n";THREE.ShaderChunk.lights_lambert_vertex="vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\tfloat dotProduct = dot( transformedNormal, dirVector );\n\tvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t#endif\n\n\t#endif\n\n\t#ifdef WRAP_AROUND\n\n\t\tvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\tdirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tdirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n\t\t#endif\n\n\t#endif\n\n\tvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n\t#endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\tpointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tpointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\tvLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n\t\t#endif\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\t\tlVector = normalize( lVector );\n\n\t\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\t\t\tvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\t\tvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\t\tspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n\t\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\t\tspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\tvLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n\t\t\t#endif\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\t\tfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n\t\tvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n\t\t#endif\n\n\t}\n\n#endif\n\nvLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive;\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive;\n\n#endif\n"; THREE.ShaderChunk.map_particle_pars_fragment="#ifdef USE_MAP\n\n\tuniform vec4 offsetRepeat;\n\tuniform sampler2D map;\n\n#endif\n";THREE.ShaderChunk.default_vertex="#ifdef USE_SKINNING\n\n\tvec4 mvPosition = modelViewMatrix * skinned;\n\n#elif defined( USE_MORPHTARGETS )\n\n\tvec4 mvPosition = modelViewMatrix * vec4( morphed, 1.0 );\n\n#else\n\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\n#endif\n\ngl_Position = projectionMatrix * mvPosition;\n"; THREE.ShaderChunk.map_pars_fragment="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\n#endif\n\n#ifdef USE_MAP\n\n\tuniform sampler2D map;\n\n#endif";THREE.ShaderChunk.skinnormal_vertex="#ifdef USE_SKINNING\n\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\n\t#ifdef USE_MORPHNORMALS\n\n\tvec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );\n\n\t#else\n\n\tvec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );\n\n\t#endif\n\n#endif\n"; -THREE.ShaderChunk.logdepthbuf_pars_vertex="#ifdef USE_LOGDEPTHBUF\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n\tuniform float logDepthBufFC;\n\n#endif";THREE.ShaderChunk.lightmap_pars_vertex="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\n#endif";THREE.ShaderChunk.lights_phong_fragment="#ifndef FLAT_SHADED\n\n\tvec3 normal = normalize( vNormal );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n\t#endif\n\n#else\n\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tvec3 pointDiffuse = vec3( 0.0 );\n\tvec3 pointSpecular = vec3( 0.0 );\n\n\tfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\t\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\tpointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n\t\t\t\t// specular\n\n\t\tvec3 pointHalfVector = normalize( lVector + viewPosition );\n\t\tfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n\t\tfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n\t\tpointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tvec3 spotDiffuse = vec3( 0.0 );\n\tvec3 spotSpecular = vec3( 0.0 );\n\n\tfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\t\t\t// diffuse\n\n\t\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\t\tfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\t\tvec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n\t\t\t#else\n\n\t\t\t\tfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t\t#endif\n\n\t\t\tspotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n\t\t\t\t\t// specular\n\n\t\t\tvec3 spotHalfVector = normalize( lVector + viewPosition );\n\t\t\tfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n\t\t\tfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n\t\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n\t\t\tspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n\tvec3 dirDiffuse = vec3( 0.0 );\n\tvec3 dirSpecular = vec3( 0.0 );\n\n\tfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\t\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\t\t\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, dirVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\tdirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\n\n\t\t// specular\n\n\t\tvec3 dirHalfVector = normalize( dirVector + viewPosition );\n\t\tfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n\t\tfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n\t\t/*\n\t\t// fresnel term from skin shader\n\t\tconst float F0 = 0.128;\n\n\t\tfloat base = 1.0 - dot( viewPosition, dirHalfVector );\n\t\tfloat exponential = pow( base, 5.0 );\n\n\t\tfloat fresnel = exponential + F0 * ( 1.0 - exponential );\n\t\t*/\n\n\t\t/*\n\t\t// fresnel term from fresnel shader\n\t\tconst float mFresnelBias = 0.08;\n\t\tconst float mFresnelScale = 0.3;\n\t\tconst float mFresnelPower = 5.0;\n\n\t\tfloat fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n\t\t*/\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t// \t\tdirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n\t\tdirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tvec3 hemiDiffuse = vec3( 0.0 );\n\tvec3 hemiSpecular = vec3( 0.0 );\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n\t\tvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\themiDiffuse += diffuse * hemiColor;\n\n\t\t// specular (sky light)\n\n\t\tvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n\t\tfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n\t\tfloat hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n\t\t// specular (ground light)\n\n\t\tvec3 lVectorGround = -lVector;\n\n\t\tvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n\t\tfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n\t\tfloat hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n\t\tfloat dotProductGround = dot( normal, lVectorGround );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n\t\tvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n\t\themiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n\t}\n\n#endif\n\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n\n#if MAX_DIR_LIGHTS > 0\n\n\ttotalDiffuse += dirDiffuse;\n\ttotalSpecular += dirSpecular;\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\ttotalDiffuse += hemiDiffuse;\n\ttotalSpecular += hemiSpecular;\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\ttotalDiffuse += pointDiffuse;\n\ttotalSpecular += pointSpecular;\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\ttotalDiffuse += spotDiffuse;\n\ttotalSpecular += spotSpecular;\n\n#endif\n\n#ifdef METAL\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );\n\n#else\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;\n\n#endif\n"; +THREE.ShaderChunk.logdepthbuf_pars_vertex="#ifdef USE_LOGDEPTHBUF\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n\tuniform float logDepthBufFC;\n\n#endif";THREE.ShaderChunk.lightmap_pars_vertex="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\n#endif";THREE.ShaderChunk.lights_phong_fragment="#ifndef FLAT_SHADED\n\n\tvec3 normal = normalize( vNormal );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n\t#endif\n\n#else\n\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\nvec3 totalDiffuseLight = vec3( 0.0 );\nvec3 totalSpecularLight = vec3( 0.0 );\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\ttotalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n\t\t\t\t// specular\n\n\t\tvec3 pointHalfVector = normalize( lVector + viewPosition );\n\t\tfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n\t\tfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\t// diffuse\n\n\t\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\t\tfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\t\tvec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n\t\t\t#else\n\n\t\t\t\tfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t\t#endif\n\n\t\t\ttotalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n\t\t\t// specular\n\n\t\t\tvec3 spotHalfVector = normalize( lVector + viewPosition );\n\t\t\tfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n\t\t\tfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n\t\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n\t\t\ttotalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\t\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, dirVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\ttotalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;\n\n\t\t// specular\n\n\t\tvec3 dirHalfVector = normalize( dirVector + viewPosition );\n\t\tfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n\t\tfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n\t\t/*\n\t\t// fresnel term from skin shader\n\t\tconst float F0 = 0.128;\n\n\t\tfloat base = 1.0 - dot( viewPosition, dirHalfVector );\n\t\tfloat exponential = pow( base, 5.0 );\n\n\t\tfloat fresnel = exponential + F0 * ( 1.0 - exponential );\n\t\t*/\n\n\t\t/*\n\t\t// fresnel term from fresnel shader\n\t\tconst float mFresnelBias = 0.08;\n\t\tconst float mFresnelScale = 0.3;\n\t\tconst float mFresnelPower = 5.0;\n\n\t\tfloat fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n\t\t*/\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t// \t\tdirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n\t\tvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\ttotalDiffuseLight += hemiColor;\n\n\t\t// specular (sky light)\n\n\t\tvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n\t\tfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n\t\tfloat hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n\t\t// specular (ground light)\n\n\t\tvec3 lVectorGround = -lVector;\n\n\t\tvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n\t\tfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n\t\tfloat hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n\t\tfloat dotProductGround = dot( normal, lVectorGround );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n\t\tvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n\t}\n\n#endif\n\n#ifdef METAL\n\n\toutgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * diffuse ) * specular + totalSpecularLight + emissive;\n\n#else\n\n\toutgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive;\n\n#endif\n"; THREE.ShaderChunk.fog_pars_fragment="#ifdef USE_FOG\n\n\tuniform vec3 fogColor;\n\n\t#ifdef FOG_EXP2\n\n\t\tuniform float fogDensity;\n\n\t#else\n\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n\n#endif";THREE.ShaderChunk.morphnormal_vertex="#ifdef USE_MORPHNORMALS\n\n\tvec3 morphedNormal = vec3( 0.0 );\n\n\tmorphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tmorphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tmorphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tmorphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n\n\tmorphedNormal += normal;\n\n#endif"; THREE.ShaderChunk.envmap_pars_fragment="#ifdef USE_ENVMAP\n\n\tuniform float reflectivity;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tuniform float refractionRatio;\n\n\t#else\n\n\t\tvarying vec3 vReflect;\n\n\t#endif\n\n#endif\n";THREE.ShaderChunk.logdepthbuf_fragment="#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n\n#endif"; THREE.ShaderChunk.normalmap_pars_fragment="#ifdef USE_NORMALMAP\n\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\n\t// Per-Pixel Tangent Space Normal Mapping\n\t// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html\n\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\n\t}\n\n#endif\n"; THREE.ShaderChunk.lights_phong_pars_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvarying vec3 vWorldPosition;\n\n#endif\n";THREE.ShaderChunk.lightmap_pars_fragment="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\tuniform sampler2D lightMap;\n\n#endif";THREE.ShaderChunk.shadowmap_vertex="#ifdef USE_SHADOWMAP\n\n\tfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n\t\tvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n\n\t}\n\n#endif"; -THREE.ShaderChunk.lights_phong_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvWorldPosition = worldPosition.xyz;\n\n#endif";THREE.ShaderChunk.map_fragment="#ifdef USE_MAP\n\n\tvec4 texelColor = texture2D( map, vUv );\n\n\ttexelColor.xyz = inputToLinear( texelColor.xyz );\n\n\tgl_FragColor = gl_FragColor * texelColor;\n\n#endif";THREE.ShaderChunk.lightmap_vertex="#ifdef USE_LIGHTMAP\n\n\tvUv2 = uv2;\n\n#endif";THREE.ShaderChunk.map_particle_fragment="#ifdef USE_MAP\n\n\tgl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\n#endif\n"; +THREE.ShaderChunk.lights_phong_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvWorldPosition = worldPosition.xyz;\n\n#endif";THREE.ShaderChunk.map_fragment="#ifdef USE_MAP\n\n\tvec4 texelColor = texture2D( map, vUv );\n\n\ttexelColor.xyz = inputToLinear( texelColor.xyz );\n\n\tdiffuseColor *= texelColor;\n\n#endif";THREE.ShaderChunk.lightmap_vertex="#ifdef USE_LIGHTMAP\n\n\tvUv2 = uv2;\n\n#endif";THREE.ShaderChunk.map_particle_fragment="#ifdef USE_MAP\n\n\tdiffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\n#endif\n"; THREE.ShaderChunk.color_pars_fragment="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif\n";THREE.ShaderChunk.color_vertex="#ifdef USE_COLOR\n\n\tvColor.xyz = inputToLinear( color.xyz );\n\n#endif";THREE.ShaderChunk.skinning_vertex="#ifdef USE_SKINNING\n\n\t#ifdef USE_MORPHTARGETS\n\n\tvec4 skinVertex = bindMatrix * vec4( morphed, 1.0 );\n\n\t#else\n\n\tvec4 skinVertex = bindMatrix * vec4( position, 1.0 );\n\n\t#endif\n\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\tskinned = bindMatrixInverse * skinned;\n\n#endif\n"; -THREE.ShaderChunk.envmap_pars_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvarying vec3 vReflect;\n\n\tuniform float refractionRatio;\n\n#endif\n";THREE.ShaderChunk.linear_to_gamma_fragment="\n\tgl_FragColor.xyz = linearToOutput( gl_FragColor.xyz );\n";THREE.ShaderChunk.color_pars_vertex="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif";THREE.ShaderChunk.lights_lambert_pars_vertex="uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n"; -THREE.ShaderChunk.map_pars_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n\n#endif\n";THREE.ShaderChunk.envmap_fragment="#ifdef USE_ENVMAP\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n\t\t// Transforming Normal Vectors with the Inverse Transformation\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n\t\t#else\n\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t\t#endif\n\n\t#else\n\n\t\tvec3 reflectVec = vReflect;\n\n\t#endif\n\n\t#ifdef DOUBLE_SIDED\n\t\tfloat flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\t#else\n\t\tfloat flipNormal = 1.0;\n\t#endif\n\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t\t\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#endif\n\n\tenvColor.xyz = inputToLinear( envColor.xyz );\n\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\n\t\tgl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\n\t\tgl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\n\t\tgl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;\n\n\t#endif\n\n#endif\n"; +THREE.ShaderChunk.envmap_pars_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvarying vec3 vReflect;\n\n\tuniform float refractionRatio;\n\n#endif\n";THREE.ShaderChunk.linear_to_gamma_fragment="\n\toutgoingLight = linearToOutput( outgoingLight );\n";THREE.ShaderChunk.color_pars_vertex="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif";THREE.ShaderChunk.lights_lambert_pars_vertex="uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n"; +THREE.ShaderChunk.map_pars_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n\n#endif\n";THREE.ShaderChunk.envmap_fragment="#ifdef USE_ENVMAP\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n\t\t// Transforming Normal Vectors with the Inverse Transformation\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n\t\t#else\n\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t\t#endif\n\n\t#else\n\n\t\tvec3 reflectVec = vReflect;\n\n\t#endif\n\n\t#ifdef DOUBLE_SIDED\n\t\tfloat flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\t#else\n\t\tfloat flipNormal = 1.0;\n\t#endif\n\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#endif\n\n\tenvColor.xyz = inputToLinear( envColor.xyz );\n\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\n\t#endif\n\n#endif\n"; THREE.ShaderChunk.specularmap_pars_fragment="#ifdef USE_SPECULARMAP\n\n\tuniform sampler2D specularMap;\n\n#endif";THREE.ShaderChunk.logdepthbuf_vertex="#ifdef USE_LOGDEPTHBUF\n\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\n#else\n\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.morphtarget_pars_vertex="#ifdef USE_MORPHTARGETS\n\n\t#ifndef USE_MORPHNORMALS\n\n\tuniform float morphTargetInfluences[ 8 ];\n\n\t#else\n\n\tuniform float morphTargetInfluences[ 4 ];\n\n\t#endif\n\n#endif"; -THREE.ShaderChunk.specularmap_fragment="float specularStrength;\n\n#ifdef USE_SPECULARMAP\n\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n\n#else\n\n\tspecularStrength = 1.0;\n\n#endif";THREE.ShaderChunk.fog_fragment="#ifdef USE_FOG\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\n\t#else\n\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\n\t#endif\n\n\t#ifdef FOG_EXP2\n\n\t\tfloat fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 );\n\t\tfogFactor = whiteCompliment( fogFactor );\n\n\t#else\n\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n\n\t#endif\n\t\n\tgl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n\n#endif"; +THREE.ShaderChunk.specularmap_fragment="float specularStrength;\n\n#ifdef USE_SPECULARMAP\n\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n\n#else\n\n\tspecularStrength = 1.0;\n\n#endif";THREE.ShaderChunk.fog_fragment="#ifdef USE_FOG\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\n\t#else\n\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\n\t#endif\n\n\t#ifdef FOG_EXP2\n\n\t\tfloat fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 );\n\t\tfogFactor = whiteCompliment( fogFactor );\n\n\t#else\n\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n\n\t#endif\n\t\n\toutgoingLight = mix( outgoingLight, fogColor, fogFactor );\n\n#endif"; THREE.ShaderChunk.bumpmap_pars_fragment="#ifdef USE_BUMPMAP\n\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\n\t// Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen\n\t// http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html\n\n\t// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)\n\n\tvec2 dHdxy_fwd() {\n\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\n\t\treturn vec2( dBx, dBy );\n\n\t}\n\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\n\t\tvec3 vSigmaX = dFdx( surf_pos );\n\t\tvec3 vSigmaY = dFdy( surf_pos );\n\t\tvec3 vN = surf_norm;\t\t// normalized\n\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\n\t}\n\n#endif\n"; THREE.ShaderChunk.defaultnormal_vertex="#ifdef USE_SKINNING\n\n\tvec3 objectNormal = skinnedNormal.xyz;\n\n#elif defined( USE_MORPHNORMALS )\n\n\tvec3 objectNormal = morphedNormal;\n\n#else\n\n\tvec3 objectNormal = normal;\n\n#endif\n\n#ifdef FLIP_SIDED\n\n\tobjectNormal = -objectNormal;\n\n#endif\n\nvec3 transformedNormal = normalMatrix * objectNormal;\n";THREE.ShaderChunk.lights_phong_pars_fragment="uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvarying vec3 vWorldPosition;\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n\nvarying vec3 vViewPosition;\n\n#ifndef FLAT_SHADED\n\n\tvarying vec3 vNormal;\n\n#endif\n"; THREE.ShaderChunk.skinbase_vertex="#ifdef USE_SKINNING\n\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n\n#endif";THREE.ShaderChunk.map_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n\n#endif"; -THREE.ShaderChunk.lightmap_fragment="#ifdef USE_LIGHTMAP\n\n\tgl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );\n\n#endif";THREE.ShaderChunk.shadowmap_pars_vertex="#ifdef USE_SHADOWMAP\n\n\tvarying vec4 vShadowCoord[ MAX_SHADOWS ];\n\tuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n\n#endif";THREE.ShaderChunk.color_fragment="#ifdef USE_COLOR\n\n\tgl_FragColor = gl_FragColor * vec4( vColor, 1.0 );\n\n#endif";THREE.ShaderChunk.morphtarget_vertex="#ifdef USE_MORPHTARGETS\n\n\tvec3 morphed = vec3( 0.0 );\n\tmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\tmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\tmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\tmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\n\t#ifndef USE_MORPHNORMALS\n\n\tmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\tmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\tmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\tmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\n\t#endif\n\n\tmorphed += position;\n\n#endif"; +THREE.ShaderChunk.lightmap_fragment="#ifdef USE_LIGHTMAP\n\n\toutgoingLight *= diffuseColor.xyz * texture2D( lightMap, vUv2 ).xyz;\n\n#endif";THREE.ShaderChunk.shadowmap_pars_vertex="#ifdef USE_SHADOWMAP\n\n\tvarying vec4 vShadowCoord[ MAX_SHADOWS ];\n\tuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n\n#endif";THREE.ShaderChunk.color_fragment="#ifdef USE_COLOR\n\n\tdiffuseColor.rgb *= vColor;\n\n#endif";THREE.ShaderChunk.morphtarget_vertex="#ifdef USE_MORPHTARGETS\n\n\tvec3 morphed = vec3( 0.0 );\n\tmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\tmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\tmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\tmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\n\t#ifndef USE_MORPHNORMALS\n\n\tmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\tmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\tmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\tmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\n\t#endif\n\n\tmorphed += position;\n\n#endif"; THREE.ShaderChunk.envmap_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvec3 worldNormal = transformDirection( objectNormal, modelMatrix );\n\n\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\n\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\n\t#else\n\n\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t#endif\n\n#endif\n"; -THREE.ShaderChunk.shadowmap_fragment="#ifdef USE_SHADOWMAP\n\n\t#ifdef SHADOWMAP_DEBUG\n\n\t\tvec3 frustumColors[3];\n\t\tfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\n\t\tfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\n\t\tfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n\n\t#endif\n\n\t#ifdef SHADOWMAP_CASCADE\n\n\t\tint inFrustumCount = 0;\n\n\t#endif\n\n\tfloat fDepth;\n\tvec3 shadowColor = vec3( 1.0 );\n\n\tfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n\t\tvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n\t\t\t\t// if ( something && something ) breaks ATI OpenGL shader compiler\n\t\t\t\t// if ( all( something, something ) ) using this instead\n\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\n\t\t\t\t// don't shadow pixels outside of light frustum\n\t\t\t\t// use just first frustum (for cascades)\n\t\t\t\t// don't shadow pixels behind far plane of light frustum\n\n\t\t#ifdef SHADOWMAP_CASCADE\n\n\t\t\tinFrustumCount += int( inFrustum );\n\t\t\tbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n\n\t\t#else\n\n\t\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n\t\t#endif\n\n\t\tbool frustumTest = all( frustumTestVec );\n\n\t\tif ( frustumTest ) {\n\n\t\t\tshadowCoord.z += shadowBias[ i ];\n\n\t\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\n\t\t\t\t\t\t// Percentage-close filtering\n\t\t\t\t\t\t// (9 pixel kernel)\n\t\t\t\t\t\t// http://fabiensanglard.net/shadowmappingPCF/\n\n\t\t\t\tfloat shadow = 0.0;\n\n\t\t/*\n\t\t\t\t\t\t// nested loops breaks shader compiler / validator on some ATI cards when using OpenGL\n\t\t\t\t\t\t// must enroll loop manually\n\n\t\t\t\tfor ( float y = -1.25; y <= 1.25; y += 1.25 )\n\t\t\t\t\tfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n\n\t\t\t\t\t\tvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n\n\t\t\t\t\t\t\t\t// doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup\n\t\t\t\t\t\t\t\t//vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );\n\n\t\t\t\t\t\tfloat fDepth = unpackDepth( rgbaDepth );\n\n\t\t\t\t\t\tif ( fDepth < shadowCoord.z )\n\t\t\t\t\t\t\tshadow += 1.0;\n\n\t\t\t\t}\n\n\t\t\t\tshadow /= 9.0;\n\n\t\t*/\n\n\t\t\t\tconst float shadowDelta = 1.0 / 9.0;\n\n\t\t\t\tfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n\t\t\t\tfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n\t\t\t\tfloat dx0 = -1.25 * xPixelOffset;\n\t\t\t\tfloat dy0 = -1.25 * yPixelOffset;\n\t\t\t\tfloat dx1 = 1.25 * xPixelOffset;\n\t\t\t\tfloat dy1 = 1.25 * yPixelOffset;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n\t\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n\t\t\t\t\t\t// Percentage-close filtering\n\t\t\t\t\t\t// (9 pixel kernel)\n\t\t\t\t\t\t// http://fabiensanglard.net/shadowmappingPCF/\n\n\t\t\t\tfloat shadow = 0.0;\n\n\t\t\t\tfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n\t\t\t\tfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n\t\t\t\tfloat dx0 = -1.0 * xPixelOffset;\n\t\t\t\tfloat dy0 = -1.0 * yPixelOffset;\n\t\t\t\tfloat dx1 = 1.0 * xPixelOffset;\n\t\t\t\tfloat dy1 = 1.0 * yPixelOffset;\n\n\t\t\t\tmat3 shadowKernel;\n\t\t\t\tmat3 depthKernel;\n\n\t\t\t\tdepthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n\t\t\t\tdepthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n\t\t\t\tdepthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n\t\t\t\tdepthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n\t\t\t\tdepthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n\t\t\t\tdepthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n\t\t\t\tdepthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n\t\t\t\tdepthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n\t\t\t\tdepthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n\t\t\t\tvec3 shadowZ = vec3( shadowCoord.z );\n\t\t\t\tshadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\n\t\t\t\tshadowKernel[0] *= vec3(0.25);\n\n\t\t\t\tshadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\n\t\t\t\tshadowKernel[1] *= vec3(0.25);\n\n\t\t\t\tshadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\n\t\t\t\tshadowKernel[2] *= vec3(0.25);\n\n\t\t\t\tvec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\n\n\t\t\t\tshadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\n\t\t\t\tshadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\n\n\t\t\t\tvec4 shadowValues;\n\t\t\t\tshadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\n\t\t\t\tshadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\n\t\t\t\tshadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\n\t\t\t\tshadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\n\n\t\t\t\tshadow = dot( shadowValues, vec4( 1.0 ) );\n\n\t\t\t\tshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n\t\t\t#else\n\n\t\t\t\tvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n\t\t\t\tfloat fDepth = unpackDepth( rgbaDepth );\n\n\t\t\t\tif ( fDepth < shadowCoord.z )\n\n\t\t// spot with multiple shadows is darker\n\n\t\t\t\t\tshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n\n\t\t// spot with multiple shadows has the same color as single shadow spot\n\n\t\t// \t\t\t\t\tshadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );\n\n\t\t\t#endif\n\n\t\t}\n\n\n\t\t#ifdef SHADOWMAP_DEBUG\n\n\t\t\t#ifdef SHADOWMAP_CASCADE\n\n\t\t\t\tif ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n\n\t\t\t#else\n\n\t\t\t\tif ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t}\n\n\t// NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014\n\tshadowColor = inputToLinear( shadowColor );\n\n\tgl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n\n#endif\n"; +THREE.ShaderChunk.shadowmap_fragment="#ifdef USE_SHADOWMAP\n\n\t#ifdef SHADOWMAP_DEBUG\n\n\t\tvec3 frustumColors[3];\n\t\tfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\n\t\tfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\n\t\tfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n\n\t#endif\n\n\t#ifdef SHADOWMAP_CASCADE\n\n\t\tint inFrustumCount = 0;\n\n\t#endif\n\n\tfloat fDepth;\n\tvec3 shadowColor = vec3( 1.0 );\n\n\tfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n\t\tvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\n\n\t\t\t\t// if ( something && something ) breaks ATI OpenGL shader compiler\n\t\t\t\t// if ( all( something, something ) ) using this instead\n\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\n\t\t\t\t// don't shadow pixels outside of light frustum\n\t\t\t\t// use just first frustum (for cascades)\n\t\t\t\t// don't shadow pixels behind far plane of light frustum\n\n\t\t#ifdef SHADOWMAP_CASCADE\n\n\t\t\tinFrustumCount += int( inFrustum );\n\t\t\tbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n\n\t\t#else\n\n\t\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\n\t\t#endif\n\n\t\tbool frustumTest = all( frustumTestVec );\n\n\t\tif ( frustumTest ) {\n\n\t\t\tshadowCoord.z += shadowBias[ i ];\n\n\t\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\n\t\t\t\t\t\t// Percentage-close filtering\n\t\t\t\t\t\t// (9 pixel kernel)\n\t\t\t\t\t\t// http://fabiensanglard.net/shadowmappingPCF/\n\n\t\t\t\tfloat shadow = 0.0;\n\n\t\t/*\n\t\t\t\t\t\t// nested loops breaks shader compiler / validator on some ATI cards when using OpenGL\n\t\t\t\t\t\t// must enroll loop manually\n\n\t\t\t\tfor ( float y = -1.25; y <= 1.25; y += 1.25 )\n\t\t\t\t\tfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n\n\t\t\t\t\t\tvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n\n\t\t\t\t\t\t\t\t// doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup\n\t\t\t\t\t\t\t\t//vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );\n\n\t\t\t\t\t\tfloat fDepth = unpackDepth( rgbaDepth );\n\n\t\t\t\t\t\tif ( fDepth < shadowCoord.z )\n\t\t\t\t\t\t\tshadow += 1.0;\n\n\t\t\t\t}\n\n\t\t\t\tshadow /= 9.0;\n\n\t\t*/\n\n\t\t\t\tconst float shadowDelta = 1.0 / 9.0;\n\n\t\t\t\tfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n\t\t\t\tfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n\t\t\t\tfloat dx0 = -1.25 * xPixelOffset;\n\t\t\t\tfloat dy0 = -1.25 * yPixelOffset;\n\t\t\t\tfloat dx1 = 1.25 * xPixelOffset;\n\t\t\t\tfloat dy1 = 1.25 * yPixelOffset;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\t\t\t\tif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\n\n\t\t\t\tshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n\t\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\n\t\t\t\t\t\t// Percentage-close filtering\n\t\t\t\t\t\t// (9 pixel kernel)\n\t\t\t\t\t\t// http://fabiensanglard.net/shadowmappingPCF/\n\n\t\t\t\tfloat shadow = 0.0;\n\n\t\t\t\tfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\n\t\t\t\tfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\n\n\t\t\t\tfloat dx0 = -1.0 * xPixelOffset;\n\t\t\t\tfloat dy0 = -1.0 * yPixelOffset;\n\t\t\t\tfloat dx1 = 1.0 * xPixelOffset;\n\t\t\t\tfloat dy1 = 1.0 * yPixelOffset;\n\n\t\t\t\tmat3 shadowKernel;\n\t\t\t\tmat3 depthKernel;\n\n\t\t\t\tdepthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\n\t\t\t\tdepthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\n\t\t\t\tdepthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\n\t\t\t\tdepthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\n\t\t\t\tdepthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\n\t\t\t\tdepthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\n\t\t\t\tdepthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\n\t\t\t\tdepthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\n\t\t\t\tdepthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\n\n\t\t\t\tvec3 shadowZ = vec3( shadowCoord.z );\n\t\t\t\tshadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\n\t\t\t\tshadowKernel[0] *= vec3(0.25);\n\n\t\t\t\tshadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\n\t\t\t\tshadowKernel[1] *= vec3(0.25);\n\n\t\t\t\tshadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\n\t\t\t\tshadowKernel[2] *= vec3(0.25);\n\n\t\t\t\tvec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\n\n\t\t\t\tshadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\n\t\t\t\tshadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\n\n\t\t\t\tvec4 shadowValues;\n\t\t\t\tshadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\n\t\t\t\tshadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\n\t\t\t\tshadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\n\t\t\t\tshadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\n\n\t\t\t\tshadow = dot( shadowValues, vec4( 1.0 ) );\n\n\t\t\t\tshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n\n\t\t\t#else\n\n\t\t\t\tvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\n\t\t\t\tfloat fDepth = unpackDepth( rgbaDepth );\n\n\t\t\t\tif ( fDepth < shadowCoord.z )\n\n\t\t// spot with multiple shadows is darker\n\n\t\t\t\t\tshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n\n\t\t// spot with multiple shadows has the same color as single shadow spot\n\n\t\t// \t\t\t\t\tshadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );\n\n\t\t\t#endif\n\n\t\t}\n\n\n\t\t#ifdef SHADOWMAP_DEBUG\n\n\t\t\t#ifdef SHADOWMAP_CASCADE\n\n\t\t\t\tif ( inFrustum && inFrustumCount == 1 ) outgoingLight *= frustumColors[ i ];\n\n\t\t\t#else\n\n\t\t\t\tif ( inFrustum ) outgoingLight *= frustumColors[ i ];\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t}\n\n\t// NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014\n\tshadowColor = inputToLinear( shadowColor );\n\n\toutgoingLight = outgoingLight * shadowColor;\n\n#endif\n"; THREE.ShaderChunk.worldpos_vertex="#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\n\t#ifdef USE_SKINNING\n\n\t\tvec4 worldPosition = modelMatrix * skinned;\n\n\t#elif defined( USE_MORPHTARGETS )\n\n\t\tvec4 worldPosition = modelMatrix * vec4( morphed, 1.0 );\n\n\t#else\n\n\t\tvec4 worldPosition = modelMatrix * vec4( position, 1.0 );\n\n\t#endif\n\n#endif\n";THREE.ShaderChunk.shadowmap_pars_fragment="#ifdef USE_SHADOWMAP\n\n\tuniform sampler2D shadowMap[ MAX_SHADOWS ];\n\tuniform vec2 shadowMapSize[ MAX_SHADOWS ];\n\n\tuniform float shadowDarkness[ MAX_SHADOWS ];\n\tuniform float shadowBias[ MAX_SHADOWS ];\n\n\tvarying vec4 vShadowCoord[ MAX_SHADOWS ];\n\n\tfloat unpackDepth( const in vec4 rgba_depth ) {\n\n\t\tconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\n\t\tfloat depth = dot( rgba_depth, bit_shift );\n\t\treturn depth;\n\n\t}\n\n#endif"; THREE.ShaderChunk.skinning_pars_vertex="#ifdef USE_SKINNING\n\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\n\t#ifdef BONE_TEXTURE\n\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureWidth;\n\t\tuniform int boneTextureHeight;\n\n\t\tmat4 getBoneMatrix( const in float i ) {\n\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureWidth ) );\n\t\t\tfloat y = floor( j / float( boneTextureWidth ) );\n\n\t\t\tfloat dx = 1.0 / float( boneTextureWidth );\n\t\t\tfloat dy = 1.0 / float( boneTextureHeight );\n\n\t\t\ty = dy * ( y + 0.5 );\n\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\n\t\t\treturn bone;\n\n\t\t}\n\n\t#else\n\n\t\tuniform mat4 boneGlobalMatrices[ MAX_BONES ];\n\n\t\tmat4 getBoneMatrix( const in float i ) {\n\n\t\t\tmat4 bone = boneGlobalMatrices[ int(i) ];\n\t\t\treturn bone;\n\n\t\t}\n\n\t#endif\n\n#endif\n"; -THREE.ShaderChunk.logdepthbuf_pars_fragment="#ifdef USE_LOGDEPTHBUF\n\n\tuniform float logDepthBufFC;\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\t#extension GL_EXT_frag_depth : enable\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.alphamap_fragment="#ifdef USE_ALPHAMAP\n\n\tgl_FragColor.a *= texture2D( alphaMap, vUv ).g;\n\n#endif\n";THREE.ShaderChunk.alphamap_pars_fragment="#ifdef USE_ALPHAMAP\n\n\tuniform sampler2D alphaMap;\n\n#endif\n"; +THREE.ShaderChunk.logdepthbuf_pars_fragment="#ifdef USE_LOGDEPTHBUF\n\n\tuniform float logDepthBufFC;\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\t#extension GL_EXT_frag_depth : enable\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.alphamap_fragment="#ifdef USE_ALPHAMAP\n\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n\n#endif\n";THREE.ShaderChunk.alphamap_pars_fragment="#ifdef USE_ALPHAMAP\n\n\tuniform sampler2D alphaMap;\n\n#endif\n"; THREE.UniformsUtils={merge:function(a){for(var b={},c=0;c dashSize ) {\n\t\tdiscard;\n\t}\n\tgl_FragColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3},opacity:{type:"f",value:1}},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.morphtarget_vertex, -THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float mNear;\nuniform float mFar;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {",THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\tfloat color = 1.0 - smoothstep( mNear, mFar, depth );\n\tgl_FragColor = vec4( vec3( color ), opacity );\n}"].join("\n")}, -normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvNormal = normalize( normalMatrix * normal );",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment, -"void main() {\n\tgl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex, -"}"].join("\n"),fragmentShader:["uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},equirect:{uniforms:{tEquirect:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex, -"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\nvec3 direction = normalize( vWorldPosition );\nvec2 sampleUV;\nsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\nsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\ngl_FragColor = texture2D( tEquirect, sampleUV );", -THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment, -"vec4 pack_depth( const in float depth ) {\n\tconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );\n\tres -= res.xxyz * bit_mask;\n\treturn res;\n}\nvoid main() {",THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );\n\t#else\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n\t#endif\n}"].join("\n")}}; +"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );", +THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,"\toutgoingLight = diffuseColor.rgb;",THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")}, +lambert:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",value:new THREE.Color(0)},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_lambert_pars_vertex, +THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex, +THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_lambert_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment, +THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( 1.0, 1.0, 1.0, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment, +"\t#ifdef DOUBLE_SIDED\n\t\tif ( gl_FrontFacing )\n\t\t\toutgoingLight += diffuseColor.rgb * vLightFront;\n\t\telse\n\t\t\toutgoingLight += diffuseColor.rgb * vLightBack;\n\t#else\n\t\toutgoingLight += diffuseColor.rgb * vLightFront;\n\t#endif",THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},phong:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common, +THREE.UniformsLib.bump,THREE.UniformsLib.normalmap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",value:new THREE.Color(0)},specular:{type:"c",value:new THREE.Color(1118481)},shininess:{type:"f",value:30},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex, +THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_phong_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex, +"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"\tvViewPosition = -mvPosition.xyz;",THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_phong_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["#define PHONG\nuniform vec3 diffuse;\nuniform float opacity;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;", +THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.lights_phong_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.bumpmap_pars_fragment,THREE.ShaderChunk.normalmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment, +"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.lights_phong_fragment,THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment, +THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},particle_basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.particle,THREE.UniformsLib.shadowmap]),vertexShader:["uniform float size;\nuniform float scale;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.color_vertex,"\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / length( mvPosition.xyz ) );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\tgl_Position = projectionMatrix * mvPosition;", +THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 psColor;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_particle_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( psColor, opacity );", +THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_particle_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphatest_fragment,"\toutgoingLight = diffuseColor.rgb;",THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},dashed:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,{scale:{type:"f",value:1},dashSize:{type:"f",value:1},totalSize:{type:"f",value:2}}]), +vertexShader:["uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.color_vertex,"\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;", +THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},depth:{uniforms:{mNear:{type:"f", +value:1},mFar:{type:"f",value:2E3},opacity:{type:"f",value:1}},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float mNear;\nuniform float mFar;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {",THREE.ShaderChunk.logdepthbuf_fragment, +"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\tfloat color = 1.0 - smoothstep( mNear, mFar, depth );\n\tgl_FragColor = vec4( vec3( color ), opacity );\n}"].join("\n")},normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvNormal = normalize( normalMatrix * normal );", +THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;", +THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );", +THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},equirect:{uniforms:{tEquirect:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;", +THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\nvec3 direction = normalize( vWorldPosition );\nvec2 sampleUV;\nsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\nsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\ngl_FragColor = texture2D( tEquirect, sampleUV );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex, +THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"vec4 pack_depth( const in float depth ) {\n\tconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );\n\tres -= res.xxyz * bit_mask;\n\treturn res;\n}\nvoid main() {", +THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );\n\t#else\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n\t#endif\n}"].join("\n")}}; THREE.WebGLRenderer=function(a){function b(a){var b=a.geometry;a=a.material;var c=b.vertices.length;if(a.attributes){void 0===b.__webglCustomAttributesList&&(b.__webglCustomAttributesList=[]);for(var d in a.attributes){var e=a.attributes[d];if(!e.__webglInitialized||e.createUniqueBuffers){e.__webglInitialized=!0;var f=1;"v2"===e.type?f=2:"v3"===e.type?f=3:"v4"===e.type?f=4:"c"===e.type&&(f=3);e.size=f;e.array=new Float32Array(c*f);e.buffer=m.createBuffer();e.buffer.belongsToAttribute=d;e.needsUpdate= !0}b.__webglCustomAttributesList.push(e)}}}function c(a,b){return a.material instanceof THREE.MeshFaceMaterial?a.material.materials[b.materialIndex]:a.material}function d(a,b,c,d){c=c.attributes;var e=b.attributes;b=b.attributesKeys;for(var f=0,g=b.length;f Date: Tue, 10 Mar 2015 00:28:30 +0100 Subject: [PATCH 281/333] ObjectLoader: Added PlaneBufferGeometry support. Fixes #6203. --- src/loaders/ObjectLoader.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 378d59fee41cd2..bcb53e6b1f99bb 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -85,8 +85,9 @@ THREE.ObjectLoader.prototype = { switch ( data.type ) { case 'PlaneGeometry': + case 'PlaneBufferGeometry': - geometry = new THREE.PlaneGeometry( + geometry = new THREE[ data.type ]( data.width, data.height, data.widthSegments, From a056e70e5b4a7073b84ce272a01448e759f37292 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 10 Mar 2015 00:28:41 +0100 Subject: [PATCH 282/333] Updated builds. --- build/three.js | 3 ++- build/three.min.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build/three.js b/build/three.js index 20166830921787..697d74a5176ae7 100644 --- a/build/three.js +++ b/build/three.js @@ -12680,8 +12680,9 @@ THREE.ObjectLoader.prototype = { switch ( data.type ) { case 'PlaneGeometry': + case 'PlaneBufferGeometry': - geometry = new THREE.PlaneGeometry( + geometry = new THREE[ data.type ]( data.width, data.height, data.widthSegments, diff --git a/build/three.min.js b/build/three.min.js index 4933eef4d48b93..ffa1a58dc6a230 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -280,8 +280,8 @@ THREE.MaterialLoader.prototype={constructor:THREE.MaterialLoader,load:function(a void 0!==a.uniforms&&(b.uniforms=a.uniforms);void 0!==a.vertexShader&&(b.vertexShader=a.vertexShader);void 0!==a.fragmentShader&&(b.fragmentShader=a.fragmentShader);void 0!==a.vertexColors&&(b.vertexColors=a.vertexColors);void 0!==a.shading&&(b.shading=a.shading);void 0!==a.blending&&(b.blending=a.blending);void 0!==a.side&&(b.side=a.side);void 0!==a.opacity&&(b.opacity=a.opacity);void 0!==a.transparent&&(b.transparent=a.transparent);void 0!==a.wireframe&&(b.wireframe=a.wireframe);void 0!==a.size&& (b.size=a.size);void 0!==a.sizeAttenuation&&(b.sizeAttenuation=a.sizeAttenuation);if(void 0!==a.materials)for(var c=0,d=a.materials.length;c Date: Mon, 9 Mar 2015 20:19:17 -0700 Subject: [PATCH 283/333] Improved the logic for float precision. This now happens in the JSON serialization process. Fixed a bug were light map exports were breaking because of texture use dependencies. --- .../blender/addons/io_three/exporter/_json.py | 6 +- .../addons/io_three/exporter/api/animation.py | 82 +++----- .../addons/io_three/exporter/api/material.py | 10 +- .../addons/io_three/exporter/api/mesh.py | 181 ++++++------------ .../addons/io_three/exporter/geometry.py | 20 +- .../addons/io_three/exporter/utilities.py | 43 ----- .../blender/tests/scripts/exporter.py | 2 + 7 files changed, 106 insertions(+), 238 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/_json.py b/utils/exporters/blender/addons/io_three/exporter/_json.py index 82362635fd8743..4d12a7f209282c 100644 --- a/utils/exporters/blender/addons/io_three/exporter/_json.py +++ b/utils/exporters/blender/addons/io_three/exporter/_json.py @@ -5,10 +5,10 @@ ## THREE override function def _json_floatstr(o): - s = str(o) - if ROUND is None: - return s + return str(o) + + s = str(round(o, ROUND)) if '.' in s and len(s[s.index('.'):]) > ROUND - 1: s = '%.{0}f'.format(ROUND) % o diff --git a/utils/exporters/blender/addons/io_three/exporter/api/animation.py b/utils/exporters/blender/addons/io_three/exporter/api/animation.py index 3d3551181488b6..c8909051c189ee 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/animation.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/animation.py @@ -1,7 +1,11 @@ +""" +Module for handling the parsing of skeletal animation data. +""" + import math import mathutils from bpy import data, context -from .. import constants, logger, utilities +from .. import constants, logger def pose_animation(armature, options): @@ -42,22 +46,19 @@ def _parse_action(func, armature, options): """ animations = [] logger.info("Parsing %d actions", len(data.actions)) - round_off, round_val = utilities.rounding(options) for action in data.actions: logger.info("Parsing action %s", action.name) - animation = func(action, armature, options, round_off, round_val) + animation = func(action, armature, options) animations.append(animation) return animations -def _parse_rest_action(action, armature, options, round_off, round_val): +def _parse_rest_action(action, armature, options): """ :param action: :param armature: :param options: - :param round_off: - :param round_val: """ end_frame = action.frame_range[1] @@ -91,19 +92,13 @@ def _parse_rest_action(action, armature, options, round_off, round_val): action, rotation_matrix) rot = _normalize_quaternion(rot) - if round_off: - pos_x, pos_y, pos_z = utilities.round_off( - [pos.x, pos.z, -pos.y], round_val) - rot_x, rot_y, rot_z, rot_w = utilities.round_off( - [rot.x, rot.z, -rot.y, rot.w], round_val) - else: - pos_x, pos_y, pos_z = pos.x, pos.z, -pos.y - rot_x, rot_y, rot_z, rot_w = rot.x, rot.z, -rot.y, rot.w + pos_x, pos_y, pos_z = pos.x, pos.z, -pos.y + rot_x, rot_y, rot_z, rot_w = rot.x, rot.z, -rot.y, rot.w if frame == start_frame: time = (frame * frame_step - start_frame) / fps - #@TODO: missing scale values + # @TODO: missing scale values keyframe = { constants.TIME: time, constants.POS: [pos_x, pos_y, pos_z], @@ -129,22 +124,22 @@ def _parse_rest_action(action, armature, options, round_off, round_val): # MIDDLE-FRAME: needs only one of the attributes, # can be an empty frame (optional frame) - elif pchange == True or rchange == True: + elif pchange is True or rchange is True: time = (frame * frame_step - start_frame) / fps - if pchange == True and rchange == True: + if pchange is True and rchange is True: keyframe = { constants.TIME: time, constants.POS: [pos_x, pos_y, pos_z], constants.ROT: [rot_x, rot_y, rot_z, rot_w] } - elif pchange == True: + elif pchange is True: keyframe = { constants.TIME: time, constants.POS: [pos_x, pos_y, pos_z] } - elif rchange == True: + elif rchange is True: keyframe = { constants.TIME: time, constants.ROT: [rot_x, rot_y, rot_z, rot_w] @@ -160,7 +155,7 @@ def _parse_rest_action(action, armature, options, round_off, round_val): animation = { constants.HIERARCHY: hierarchy, - constants.LENGTH:frame_length / fps, + constants.LENGTH: frame_length / fps, constants.FPS: fps, constants.NAME: action.name } @@ -168,20 +163,18 @@ def _parse_rest_action(action, armature, options, round_off, round_val): return animation -def _parse_pose_action(action, armature, options, round_off, round_val): +def _parse_pose_action(action, armature, options): """ :param action: :param armature: :param options: - :param round_off: - :param round_val: """ - #@TODO: this seems to fail in batch mode meaning the - # user has to have th GUI open. need to improve - # this logic to allow batch processing, if Blender - # chooses to behave.... + # @TODO: this seems to fail in batch mode meaning the + # user has to have th GUI open. need to improve + # this logic to allow batch processing, if Blender + # chooses to behave.... current_context = context.area.type context.area.type = 'DOPESHEET_EDITOR' context.space_data.mode = 'ACTION' @@ -285,27 +278,9 @@ def find_keyframe_at(channel, frame): schange = True or has_keyframe_at( channels_scale[bone_index], frame) - if round_off: - pos = ( - utilities.round_off(pos.x, round_val), - utilities.round_off(pos.z, round_val), - -utilities.round_off(pos.y, round_val) - ) - rot = ( - utilities.round_off(rot.x, round_val), - utilities.round_off(rot.z, round_val), - -utilities.round_off(rot.y, round_val), - utilities.round_off(rot.w, round_val) - ) - scl = ( - utilities.round_off(scl.x, round_val), - utilities.round_off(scl.z, round_val), - utilities.round_off(scl.y, round_val) - ) - else: - pos = (pos.x, pos.z, -pos.y) - rot = (rot.x, rot.z, -rot.y, rot.w) - scl = (scl.x, scl.z, scl.y) + pos = (pos.x, pos.z, -pos.y) + rot = (rot.x, rot.z, -rot.y, rot.w) + scl = (scl.x, scl.z, scl.y) keyframe = {constants.TIME: time} if frame == start_frame or frame == end_frame: @@ -349,7 +324,7 @@ def find_keyframe_at(channel, frame): animation = { constants.HIERARCHY: hierarchy, - constants.LENGTH:frame_length, + constants.LENGTH: frame_length, constants.FPS: fps, constants.NAME: action.name } @@ -373,7 +348,7 @@ def _find_channels(action, bone, channel_type): for index, group in enumerate(action.groups): if group.name == bone.name: group_index = index - #@TODO: break? + # @TODO: break? if group_index > -1: for channel in action.groups[group_index].channels: @@ -426,8 +401,7 @@ def _position(bone, frame, action, armature_matrix): for channel in action.fcurves: data_path = channel.data_path - if bone_label in data_path and \ - "location" in data_path: + if bone_label in data_path and "location" in data_path: has_changed = _handle_position_channel( channel, frame, position) change = change or has_changed @@ -497,8 +471,7 @@ def _rotation(bone, frame, action, armature_matrix): for channel in action.fcurves: data_path = channel.data_path - if bone_label in data_path and \ - "quaternion" in data_path: + if bone_label in data_path and "quaternion" in data_path: has_changed = _handle_rotation_channel( channel, frame, rotation) change = change or has_changed @@ -602,4 +575,3 @@ def _normalize_quaternion(quat): enum.z = quat.z * length enum.w = quat.w * length return enum - diff --git a/utils/exporters/blender/addons/io_three/exporter/api/material.py b/utils/exporters/blender/addons/io_three/exporter/api/material.py index e2dbb5c9c24712..df81eaef5adf4e 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/material.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/material.py @@ -179,7 +179,7 @@ def light_map(material): """ logger.debug("material.light_map(%s)", material) - for texture in _valid_textures(material): + for texture in _valid_textures(material, strict_use=False): if texture.use_map_color_diffuse and \ texture.blend_type == MULTIPLY: return texture.texture @@ -370,7 +370,7 @@ def wireframe(material): return material.type == WIRE -def _valid_textures(material): +def _valid_textures(material, strict_use=True): """ :param material: @@ -380,7 +380,11 @@ def _valid_textures(material): for texture in material.texture_slots: if not texture: continue - if texture.texture.type != IMAGE or not texture.use: + if strict_use: + in_use = texture.use + else: + in_use = True + if texture.texture.type != IMAGE or not in_use: continue logger.debug("Valid texture found %s", texture) yield texture diff --git a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py index b7e87f9e26d2a2..6373e43040cb17 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/mesh.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/mesh.py @@ -1,3 +1,9 @@ +""" +Blender API for querying mesh data. Animation data is also +handled here since Three.js associates the animation (skeletal, +morph targets) with the geometry nodes. +""" + import operator from bpy import data, types, context from . import material, texture, animation @@ -37,6 +43,7 @@ def skeletal_animation(mesh, options): :param mesh: :param options: + :rtype: [] """ logger.debug("mesh.animation(%s, %s)", mesh, options) @@ -47,16 +54,16 @@ def skeletal_animation(mesh, options): return [] anim_type = options.get(constants.ANIMATION) - #pose_position = armature.data.pose_position +# pose_position = armature.data.pose_position dispatch = { constants.POSE: animation.pose_animation, constants.REST: animation.rest_animation } func = dispatch[anim_type] - #armature.data.pose_position = anim_type.upper() +# armature.data.pose_position = anim_type.upper() animations = func(armature, options) - #armature.data.pose_position = pose_position +# armature.data.pose_position = pose_position return animations @@ -67,6 +74,7 @@ def bones(mesh, options): :param mesh: :param options: + :rtype: [], {} """ logger.debug("mesh.bones(%s)", mesh) @@ -75,15 +83,14 @@ def bones(mesh, options): if not armature: return [], {} - round_off, round_val = utilities.rounding(options) anim_type = options.get(constants.ANIMATION) - #pose_position = armature.data.pose_position +# pose_position = armature.data.pose_position if anim_type == constants.OFF: - logger.info("Animation type not set, defaulting "\ - "to using REST position for the armature.") + logger.info("Animation type not set, defaulting " + "to using REST position for the armature.") func = _rest_bones - #armature.data.pose_position = "REST" +# armature.data.pose_position = "REST" else: dispatch = { constants.REST: _rest_bones, @@ -91,24 +98,23 @@ def bones(mesh, options): } logger.info("Using %s for the armature", anim_type) func = dispatch[anim_type] - #armature.data.pose_position = anim_type.upper() +# armature.data.pose_position = anim_type.upper() - bones_, bone_map = func(armature, round_off, round_val) - #armature.data.pose_position = pose_position + bones_, bone_map = func(armature) +# armature.data.pose_position = pose_position return (bones_, bone_map) @_mesh -def buffer_normal(mesh, options): +def buffer_normal(mesh): """ :param mesh: - :param options: + :rtype: [] """ normals_ = [] - round_off, round_val = utilities.rounding(options) for face in mesh.tessfaces: vert_count = len(face.vertices) @@ -119,24 +125,20 @@ def buffer_normal(mesh, options): for vertex_index in face.vertices: normal = mesh.vertices[vertex_index].normal vector = (normal.x, normal.y, normal.z) - if round_off: - vector = utilities.round_off(vector, round_val) - normals_.extend(vector) return normals_ @_mesh -def buffer_position(mesh, options): +def buffer_position(mesh): """ :param mesh: - :param options: + :rtype: [] """ position = [] - round_off, round_val = utilities.rounding(options) for face in mesh.tessfaces: vert_count = len(face.vertices) @@ -147,35 +149,29 @@ def buffer_position(mesh, options): for vertex_index in face.vertices: vertex = mesh.vertices[vertex_index] vector = (vertex.co.x, vertex.co.y, vertex.co.z) - if round_off: - vector = utilities.round_off(vector, round_val) - position.extend(vector) return position @_mesh -def buffer_uv(mesh, options): +def buffer_uv(mesh): """ :param mesh: - :param options: + :rtype: [] """ + uvs_ = [] if len(mesh.uv_layers) is 0: - return + return uvs_ elif len(mesh.uv_layers) > 1: # if memory serves me correctly buffer geometry # only uses one UV layer logger.warning("%s has more than 1 UV layer", mesh.name) - round_off, round_val = utilities.rounding(options) - uvs_ = [] for uv_data in mesh.uv_layers[0].data: uv_tuple = (uv_data.uv[0], uv_data.uv[1]) - if round_off: - uv_tuple = utilities.round_off(uv_tuple, round_val) uvs_.extend(uv_tuple) return uvs_ @@ -195,10 +191,6 @@ def faces(mesh, options): logger.info("Has UVs = %s", vertex_uv) logger.info("Has vertex colours = %s", has_colors) - round_off, round_val = utilities.rounding(options) - if round_off: - logger.debug("Rounding off of vectors set to %s", round_off) - opt_colours = options[constants.COLORS] and has_colors opt_uvs = options[constants.UVS] and vertex_uv opt_materials = options.get(constants.FACE_MATERIALS) @@ -208,8 +200,8 @@ def faces(mesh, options): logger.debug("Materials enabled = %s", opt_materials) logger.debug("Normals enabled = %s", opt_normals) - uv_layers = _uvs(mesh, options) if opt_uvs else None - vertex_normals = _normals(mesh, options) if opt_normals else None + uv_layers = _uvs(mesh) if opt_uvs else None + vertex_normals = _normals(mesh) if opt_normals else None vertex_colours = vertex_colors(mesh) if opt_colours else None faces_data = [] @@ -252,17 +244,14 @@ def faces(mesh, options): if mask[constants.MATERIALS]: face_data.append(face.material_index) - #@TODO: this needs the same optimization as what - # was done for colours and normals + # @TODO: this needs the same optimization as what + # was done for colours and normals if uv_layers: for index, uv_layer in enumerate(uv_layers): layer = mesh.tessface_uv_textures[index] for uv_data in layer.data[face.index].uv: uv_tuple = (uv_data[0], uv_data[1]) - if round_off: - uv_tuple = utilities.round_off( - uv_tuple, round_val) face_data.append(uv_layer.index(uv_tuple)) mask[constants.UVS] = True @@ -270,8 +259,6 @@ def faces(mesh, options): for vertex in face.vertices: normal = mesh.vertices[vertex].normal normal = (normal.x, normal.y, normal.z) - if round_off: - normal = utilities.round_off(normal, round_val) face_data.append(normal_indices[str(normal)]) mask[constants.NORMALS] = True @@ -310,7 +297,6 @@ def morph_targets(mesh, options): frame_step) morphs = [] - round_off, round_val = utilities.rounding(options) for frame in scene_frames: logger.info("Processing data at frame %d", frame) @@ -319,15 +305,7 @@ def morph_targets(mesh, options): vertices_ = object_.extract_mesh(obj, options).vertices[:] for vertex in vertices_: - if round_off: - vectors = [ - utilities.round_off(vertex.co.x, round_val), - utilities.round_off(vertex.co.y, round_val), - utilities.round_off(vertex.co.z, round_val) - ] - else: - vectors = [vertex.co.x, vertex.co.y, vertex.co.z] - morphs[-1].extend(vectors) + morphs[-1].extend([vertex.co.x, vertex.co.y, vertex.co.z]) context.scene.frame_set(original_frame, 0.0) morphs_detected = False @@ -449,17 +427,17 @@ def materials(mesh, options): @_mesh -def normals(mesh, options): +def normals(mesh): """ :param mesh: - :param options: + :rtype: [] """ - logger.debug("mesh.normals(%s, %s)", mesh, options) + logger.debug("mesh.normals(%s)", mesh) normal_vectors = [] - for vector in _normals(mesh, options): + for vector in _normals(mesh): normal_vectors.extend(vector) return normal_vectors @@ -544,16 +522,16 @@ def _registration(file_path, file_name): @_mesh -def uvs(mesh, options): +def uvs(mesh): """ :param mesh: - :param options: + :rtype: [] """ - logger.debug("mesh.uvs(%s, %s)", mesh, options) + logger.debug("mesh.uvs(%s)", mesh) uvs_ = [] - for layer in _uvs(mesh, options): + for layer in _uvs(mesh): uvs_.append([]) logger.info("Parsing UV layer %d", len(uvs_)) for pair in layer: @@ -594,24 +572,18 @@ def vertex_colors(mesh): @_mesh -def vertices(mesh, options): +def vertices(mesh): """ :param mesh: - :param options: + :rtype: [] """ - logger.debug("mesh.vertices(%s, %s)", mesh, options) + logger.debug("mesh.vertices(%s)", mesh) vertices_ = [] - round_off, round_val = utilities.rounding(options) - for vertex in mesh.vertices: - vector = (vertex.co.x, vertex.co.y, vertex.co.z) - if round_off: - vector = utilities.round_off(vector, round_val) - - vertices_.extend(vector) + vertices_.extend((vertex.co.x, vertex.co.y, vertex.co.z)) return vertices_ @@ -740,15 +712,14 @@ def _diffuse_map(mat): return diffuse -def _normals(mesh, options): +def _normals(mesh): """ :param mesh: - :param options: + :rtype: [] """ vectors = [] - round_off, round_val = utilities.rounding(options) vectors_ = {} for face in mesh.tessfaces: @@ -756,8 +727,6 @@ def _normals(mesh, options): for vertex_index in face.vertices: normal = mesh.vertices[vertex_index].normal vector = (normal.x, normal.y, normal.z) - if round_off: - vector = utilities.round_off(vector, round_val) str_vec = str(vector) try: @@ -769,23 +738,19 @@ def _normals(mesh, options): return vectors -def _uvs(mesh, options): +def _uvs(mesh): """ :param mesh: - :param options: """ uv_layers = [] - round_off, round_val = utilities.rounding(options) for layer in mesh.uv_layers: uv_layers.append([]) for uv_data in layer.data: uv_tuple = (uv_data.uv[0], uv_data.uv[1]) - if round_off: - uv_tuple = utilities.round_off(uv_tuple, round_val) if uv_tuple not in uv_layers[-1]: uv_layers[-1].append(uv_tuple) @@ -853,12 +818,11 @@ def _skinning_data(mesh, bone_map, influences, array_index): return manifest -def _pose_bones(armature, round_off, round_val): +def _pose_bones(armature): """ :param armature: - :param round_off: - :param round_val: + :rtype: [], {} """ bones_ = [] @@ -889,44 +853,22 @@ def _pose_bones(armature, round_off, round_val): bone_map[bone_count] = bone_count pos, rot, scl = bone_matrix.decompose() - if round_off: - pos = ( - utilities.round_off(pos.x, round_val), - utilities.round_off(pos.z, round_val), - -utilities.round_off(pos.y, round_val) - ) - rot = ( - utilities.round_off(rot.x, round_val), - utilities.round_off(rot.z, round_val), - -utilities.round_off(rot.y, round_val), - utilities.round_off(rot.w, round_val) - ) - scl = ( - utilities.round_off(scl.x, round_val), - utilities.round_off(scl.z, round_val), - utilities.round_off(scl.y, round_val) - ) - else: - pos = (pos.x, pos.z, -pos.y) - rot = (rot.x, rot.z, -rot.y, rot.w) - scl = (scl.x, scl.z, scl.y) bones_.append({ constants.PARENT: bone_index, constants.NAME: armature_bone.name, - constants.POS: pos, - constants.ROTQ: rot, - constants.SCL: scl + constants.POS: (pos.x, pos.z, -pos.y), + constants.ROTQ: (rot.x, rot.z, -rot.y, rot.w), + constants.SCL: (scl.x, scl.z, scl.y) }) return bones_, bone_map -def _rest_bones(armature, round_off, round_val): +def _rest_bones(armature): """ :param armature: - :param round_off: - :param round_val: + :rtype: [], {} """ bones_ = [] @@ -955,21 +897,16 @@ def _rest_bones(armature, round_off, round_val): index += 1 bone_world_pos = armature.matrix_world * bone_pos - if round_off: - x_axis = utilities.round_off(bone_world_pos.x, round_val) - y_axis = utilities.round_off(bone_world_pos.z, round_val) - z_axis = -utilities.round_off(bone_world_pos.y, round_val) - else: - x_axis = bone_world_pos.x - y_axis = bone_world_pos.z - z_axis = -bone_world_pos.y + x_axis = bone_world_pos.x + y_axis = bone_world_pos.z + z_axis = -bone_world_pos.y logger.debug("Adding bone %s at: %s, %s", bone.name, bone_index, bone_index_rel) bone_map[bone_count] = bone_index_rel bone_index_rel += 1 - #@TODO: the rotq probably should not have these - # hard coded values + # @TODO: the rotq probably should not have these + # hard coded values bones_.append({ constants.PARENT: bone_index, constants.NAME: bone.name, @@ -980,5 +917,3 @@ def _rest_bones(armature, round_off, round_val): bone_count += 1 return (bones_, bone_map) - - diff --git a/utils/exporters/blender/addons/io_three/exporter/geometry.py b/utils/exporters/blender/addons/io_three/exporter/geometry.py index 3c456e35da7d62..c44d56c6873efe 100644 --- a/utils/exporters/blender/addons/io_three/exporter/geometry.py +++ b/utils/exporters/blender/addons/io_three/exporter/geometry.py @@ -1,3 +1,7 @@ +""" +Module for creating Three.js geometry JSON nodes. +""" + import os from .. import constants, logger from . import base_classes, io, api @@ -42,11 +46,8 @@ def animation_filename(self): key = '' for key in (constants.MORPH_TARGETS, constants.ANIMATION): - try: - self[key] + if key in self.keys(): break - except KeyError: - pass else: logger.info("%s has no animation data", self.node) return @@ -367,7 +368,7 @@ def _parse_buffer_geometry(self): if not option: continue - array = func(self.node, self.options) or [] + array = func(self.node) or [] if not array: logger.warning("No array could be made for %s", key) continue @@ -382,13 +383,11 @@ def _parse_geometry(self): """Parse the geometry to Three.Geometry specs""" if self.options.get(constants.VERTICES): logger.info("Parsing %s", constants.VERTICES) - self[constants.VERTICES] = api.mesh.vertices( - self.node, self.options) or [] + self[constants.VERTICES] = api.mesh.vertices(self.node) or [] if self.options.get(constants.NORMALS): logger.info("Parsing %s", constants.NORMALS) - self[constants.NORMALS] = api.mesh.normals( - self.node, self.options) or [] + self[constants.NORMALS] = api.mesh.normals(self.node) or [] if self.options.get(constants.COLORS): logger.info("Parsing %s", constants.COLORS) @@ -402,8 +401,7 @@ def _parse_geometry(self): if self.options.get(constants.UVS): logger.info("Parsing %s", constants.UVS) - self[constants.UVS] = api.mesh.uvs( - self.node, self.options) or [] + self[constants.UVS] = api.mesh.uvs(self.node) or [] if self.options.get(constants.FACES): logger.info("Parsing %s", constants.FACES) diff --git a/utils/exporters/blender/addons/io_three/exporter/utilities.py b/utils/exporters/blender/addons/io_three/exporter/utilities.py index 87e773cfaf7a2c..feb6b7d79afa5a 100644 --- a/utils/exporters/blender/addons/io_three/exporter/utilities.py +++ b/utils/exporters/blender/addons/io_three/exporter/utilities.py @@ -68,46 +68,3 @@ def rgb2int(rgb): colour = (int(rgb[0]*255) << 16) + (int(rgb[1]*255) << 8) + int(rgb[2]*255) return colour - - -def round_off(value, ndigits=ROUND): - """Round off values to specified limit - - :param value: value(s) to round off - :param ndigits: limit (Default value = ROUND) - :type value: float|list|tuple - :return: the same data type that was passed - :rtype: float|list|tuple - - """ - is_tuple = isinstance(value, tuple) - is_list = isinstance(value, list) - - value = list(value) if is_tuple else value - value = [value] if not is_list and not is_tuple else value - - value = [round(val, ndigits) for val in value] - - if is_tuple: - value = tuple(value) - elif not is_list: - value = value[0] - - return value - - -def rounding(options): - """By evaluation the options determine if precision was - enabled and what the value is - - :type options: dict - :rtype: bool, int - - """ - round_off_ = options.get(constants.ENABLE_PRECISION) - if round_off_: - round_val = options[constants.PRECISION] - else: - round_val = None - - return (round_off_, round_val) diff --git a/utils/exporters/blender/tests/scripts/exporter.py b/utils/exporters/blender/tests/scripts/exporter.py index e8f8659529f695..11c448a1b5ef7b 100755 --- a/utils/exporters/blender/tests/scripts/exporter.py +++ b/utils/exporters/blender/tests/scripts/exporter.py @@ -27,6 +27,8 @@ def parse_args(): def main(): args = parse_args() + args[constants.ENABLE_PRECISION] = True + args[constants.INDENT] = True if args[constants.SCENE]: io_three.exporter.export_scene(args['filepath'], args) else: From 7cb225bf60e46aa9005614eb7c768cdf0f5ffe28 Mon Sep 17 00:00:00 2001 From: Joshua Koo Date: Tue, 10 Mar 2015 11:21:03 +0800 Subject: [PATCH 284/333] Fix build.js compilation (shaders weren't packaged correctly) - shaders are now encoded as a string - works with node.js eg - node build.js --include common --include extras --output ../../build/three.js - node build.js --include common --include extras --minify --output ../../build/three.min.js --- utils/build/build.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/utils/build/build.js b/utils/build/build.js index 036e1191925e4c..ed6f5206df745e 100644 --- a/utils/build/build.js +++ b/utils/build/build.js @@ -50,15 +50,21 @@ function main() { buffer.push('// File:' + files[ j ]); buffer.push('\n\n'); + + contents = fs.readFileSync( file, 'utf8' ); + if( file.indexOf( '.glsl') >= 0 ) { - buffer.push('THREE.ShaderChunk[\'' + path.basename(file, '.glsl') + '\'] = "'); - buffer.push(fs.readFileSync( file, 'utf8' )); - buffer.push('";\n\n'); - } - else { + + buffer.push( 'THREE.ShaderChunk[ \'' + path.basename( file, '.glsl' ) + '\' ] =') + buffer.push( JSON.stringify( contents ) ); + buffer.push( ';\n\n' ); + + } else { + sources.push( file ); - buffer.push( fs.readFileSync( file, 'utf8' ) ); - buffer.push('\n'); + buffer.push( contents ); + buffer.push( '\n' ); + } } From afb699b1eb9464aa3ddc03e1d4cb069b50856bf0 Mon Sep 17 00:00:00 2001 From: Arthur Silber Date: Tue, 10 Mar 2015 10:17:39 +0100 Subject: [PATCH 285/333] Updates default values for EdgesHelper, uses internal degToRad function, updates documentation --- src/extras/helpers/EdgesHelper.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/extras/helpers/EdgesHelper.js b/src/extras/helpers/EdgesHelper.js index 1416ab909a388a..e355f4f6974e6e 100644 --- a/src/extras/helpers/EdgesHelper.js +++ b/src/extras/helpers/EdgesHelper.js @@ -2,19 +2,18 @@ * @author WestLangley / http://github.com/WestLangley * @param object THREE.Mesh whose geometry will be used * @param hex line color - * @param thresholdAngle the minimum difference in degree between two - * faces needed to create an edge. A value of 10 means that an edge is only - * created if two face normals are at least at a 10° angle to one another + * @param thresholdAngle the minimim angle (in degrees), + * between the face normals of adjacent faces, + * that is required to render an edge. A value of 10 means + * an edge is only rendered if the angle is at least 10 degrees. */ THREE.EdgesHelper = function ( object, hex, thresholdAngle ) { var color = ( hex !== undefined ) ? hex : 0xffffff; - thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 10; - - thresholdAngle = thresholdAngle * 0.0175; //deg -> radian - var thresholdDot = Math.cos( thresholdAngle ); + thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 0.1; + var thresholdDot = Math.cos( THREE.Math.degToRad( thresholdAngle ) ); var edge = [ 0, 0 ], hash = {}; var sortFunction = function ( a, b ) { return a - b }; From de45fafa7e89ee03758ed7382da31383365835bb Mon Sep 17 00:00:00 2001 From: Arthur Silber Date: Tue, 10 Mar 2015 13:50:01 +0100 Subject: [PATCH 286/333] Updates EdgesHelper documentation --- docs/api/extras/helpers/EdgesHelper.html | 6 ++++-- src/extras/helpers/EdgesHelper.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/api/extras/helpers/EdgesHelper.html b/docs/api/extras/helpers/EdgesHelper.html index 69f99bfc0c3223..d3b11734d3ee23 100644 --- a/docs/api/extras/helpers/EdgesHelper.html +++ b/docs/api/extras/helpers/EdgesHelper.html @@ -27,10 +27,12 @@

    Example

    Constructor

    -

    [name]( [page:Object3D object], [page:Color color] )

    +

    [name]( [page:Object3D object], [page:Color color], [page:Float thresholdAngle] )

    object -- Object of which to draw edges
    - color -- Color of the edges. + color -- Color of the edges.
    + thresholdAngle -- the minimim angle (in degrees), between the face normals of adjacent faces, that is required to render an edge. Default is 0.1. +
    Creates a [page:Line], showing only the "hard" edges of the passed object; specifically, no edge will be drawn between faces which are adjacent and coplanar (or nearly coplanar). diff --git a/src/extras/helpers/EdgesHelper.js b/src/extras/helpers/EdgesHelper.js index e355f4f6974e6e..733f105152eab8 100644 --- a/src/extras/helpers/EdgesHelper.js +++ b/src/extras/helpers/EdgesHelper.js @@ -2,7 +2,7 @@ * @author WestLangley / http://github.com/WestLangley * @param object THREE.Mesh whose geometry will be used * @param hex line color - * @param thresholdAngle the minimim angle (in degrees), + * @param thresholdAngle the minimim angle (in degrees), * between the face normals of adjacent faces, * that is required to render an edge. A value of 10 means * an edge is only rendered if the angle is at least 10 degrees. From fcb425ebe1f1024af0bbe60b97679e98512a4d11 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 10 Mar 2015 14:15:00 -0400 Subject: [PATCH 287/333] fix deferred rendering broken by outgoing light refactor. --- examples/js/ShaderDeferred.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/js/ShaderDeferred.js b/examples/js/ShaderDeferred.js index 336cca21167835..db6cf7d0c58463 100644 --- a/examples/js/ShaderDeferred.js +++ b/examples/js/ShaderDeferred.js @@ -187,7 +187,8 @@ THREE.ShaderDeferred = { "const float opacity = 1.0;", - "gl_FragColor = vec4( diffuse, opacity );", + "vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does + "vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "map_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], @@ -195,6 +196,8 @@ THREE.ShaderDeferred = { THREE.ShaderChunk[ "lightmap_fragment" ], THREE.ShaderChunk[ "color_fragment" ], + "outgoingLight = diffuseColor.rgb;", + "#ifdef USE_ENVMAP", "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );", @@ -230,15 +233,15 @@ THREE.ShaderDeferred = { "if ( combine == 1 ) {", - "gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularStrength * reflectivity );", + "outgoingLight = mix( outgoingLight, cubeColor.xyz, specularStrength * reflectivity );", "} else if ( combine == 2 ) {", - "gl_FragColor.xyz += cubeColor.xyz * specularStrength * reflectivity;", + "outgoingLight += cubeColor.xyz * specularStrength * reflectivity;", "} else {", - "gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * cubeColor.xyz, specularStrength * reflectivity );", + "outgoingLight = mix( outgoingLight.xyz, diffuseColor.xyz * cubeColor.xyz, specularStrength * reflectivity );", "}", @@ -267,7 +270,7 @@ THREE.ShaderDeferred = { // diffuse color - "gl_FragColor.x = vec3_to_float( compressionScale * gl_FragColor.xyz );", + "gl_FragColor.x = vec3_to_float( compressionScale * outgoingLight.xyz );", // specular color From 49c8b96e0de7b78153d90102a13babadb247298a Mon Sep 17 00:00:00 2001 From: repsac Date: Tue, 10 Mar 2015 12:07:18 -0700 Subject: [PATCH 288/333] Improved the JSON serialization by using the "%g" formatter https://github.com/mrdoob/three.js/issues/6206#issuecomment-78119093 This also removes the `while` loop and should help improve the serialization speed of the JSON --- .../blender/addons/io_three/exporter/_json.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/exporter/_json.py b/utils/exporters/blender/addons/io_three/exporter/_json.py index 4d12a7f209282c..50031c323d07a8 100644 --- a/utils/exporters/blender/addons/io_three/exporter/_json.py +++ b/utils/exporters/blender/addons/io_three/exporter/_json.py @@ -5,18 +5,10 @@ ## THREE override function def _json_floatstr(o): - if ROUND is None: - return str(o) + if ROUND is not None: + o = round(o, ROUND) - s = str(round(o, ROUND)) - - if '.' in s and len(s[s.index('.'):]) > ROUND - 1: - s = '%.{0}f'.format(ROUND) % o - while '.' in s and s[-1] == '0': - s = s[:-1] # this actually removes the last '0' from the string - if s[-1] == '.': # added this test to avoid leaving '0.' instead of '0.0', - s += '0' # which would throw an error while loading the file - return s + return '%g' % o def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, From 498b29f7ee9acf8d3e91a2cefd863928ded489f9 Mon Sep 17 00:00:00 2001 From: makc Date: Tue, 10 Mar 2015 20:52:36 +0100 Subject: [PATCH 289/333] fixes #6166 --- src/loaders/BufferGeometryLoader.js | 6 +++--- src/loaders/ObjectLoader.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/loaders/BufferGeometryLoader.js b/src/loaders/BufferGeometryLoader.js index 7dc26fb25b4091..a7333e94cdde03 100644 --- a/src/loaders/BufferGeometryLoader.js +++ b/src/loaders/BufferGeometryLoader.js @@ -36,7 +36,7 @@ THREE.BufferGeometryLoader.prototype = { var geometry = new THREE.BufferGeometry(); - var attributes = json.attributes; + var attributes = json.data.attributes; for ( var key in attributes ) { @@ -47,7 +47,7 @@ THREE.BufferGeometryLoader.prototype = { } - var offsets = json.offsets; + var offsets = json.data.offsets; if ( offsets !== undefined ) { @@ -55,7 +55,7 @@ THREE.BufferGeometryLoader.prototype = { } - var boundingSphere = json.boundingSphere; + var boundingSphere = json.data.boundingSphere; if ( boundingSphere !== undefined ) { diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index dea8b86f120362..66563fd2a0eed2 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -182,7 +182,7 @@ THREE.ObjectLoader.prototype = { case 'BufferGeometry': - geometry = bufferGeometryLoader.parse( data.data ); + geometry = bufferGeometryLoader.parse( data ); break; From 952ebaa87e3a04d24d0c557cdf65e8557ab9862a Mon Sep 17 00:00:00 2001 From: makc Date: Tue, 10 Mar 2015 21:03:55 +0100 Subject: [PATCH 290/333] fixing the model for examples/webgl_geometry_colors_lookuptable.html --- examples/models/json/pressure.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/models/json/pressure.json b/examples/models/json/pressure.json index a2884345e77c58..1232c83cab7840 100644 --- a/examples/models/json/pressure.json +++ b/examples/models/json/pressure.json @@ -3,6 +3,9 @@ "version": 4, "type": "BufferGeometry" }, + "uuid": "AF2ADB07-FBC5-4BAE-AD60-123456789ABC", + "type": "BufferGeometry", + "data": { "attributes": { "position": { "itemSize": 3, @@ -15,4 +18,5 @@ "array": [1693.7626953125 ,1693.7630615234375 ,1693.763427734375 ,1693.7626953125 ,1693.4378662109375 ,1693.7630615234375 ,1693.7626953125 ,1693.7630615234375 ,1693.7630615234375 ,1693.4378662109375 ,1693.7626953125 ,1693.64208984375 ,1693.763427734375 ,1693.7630615234375 ,1693.7635498046875 ,1693.8665771484375 ,1694.043212890625 ,1693.7635498046875 ,1693.763427734375 ,1693.7635498046875 ,1694.043212890625 ,1693.763427734375 ,1693.64208984375 ,1693.7626953125 ,1693.763427734375 ,1694.043212890625 ,1693.64208984375 ,1692.494140625 ,1692.4864501953125 ,1692.0390625 ,1693.6607666015625 ,1693.660888671875 ,1693.660888671875 ,1693.660888671875 ,1693.6607666015625 ,1693.66064453125 ,1693.660888671875 ,1693.66064453125 ,1693.6607666015625 ,1694.043212890625 ,1693.7384033203125 ,1693.660888671875 ,1693.7384033203125 ,1693.660888671875 ,1693.660888671875 ,1693.660888671875 ,1693.6885986328125 ,1694.043212890625 ,1693.64208984375 ,1693.6885986328125 ,1693.6607666015625 ,1693.660888671875 ,1693.6607666015625 ,1693.6885986328125 ,1693.660888671875 ,1693.66064453125 ,1693.6607666015625 ,1693.660888671875 ,1693.7384033203125 ,1693.604248046875 ,1693.66064453125 ,1693.660888671875 ,1693.604248046875 ,1693.7630615234375 ,1693.7630615234375 ,1693.7635498046875 ,1694.043212890625 ,1694.03564453125 ,1693.7384033203125 ,1692.979736328125 ,1693.001220703125 ,1693.0499267578125 ,1692.026123046875 ,1693.0009765625 ,1692.979736328125 ,1693.001220703125 ,1692.979736328125 ,1693.0009765625 ,1693.001220703125 ,1693.0010986328125 ,1693.0009765625 ,1692.9134521484375 ,1693.0140380859375 ,1693.0009765625 ,1693.001220703125 ,1693.0009765625 ,1693.0140380859375 ,1693.001220703125 ,1693.001220703125 ,1693.0010986328125 ,1693.0140380859375 ,1693.063232421875 ,1693.001220703125 ,1693.001220703125 ,1693.001220703125 ,1693.063232421875 ,1693.462646484375 ,1693.063232421875 ,1693.0140380859375 ,1692.2333984375 ,1692.0390625 ,1692.4864501953125 ,1692.494140625 ,1692.2333984375 ,1692.4864501953125 ,1693.462646484375 ,1693.0140380859375 ,1693.4378662109375 ,1693.66064453125 ,1693.6607666015625 ,1693.66064453125 ,1693.604248046875 ,1693.552734375 ,1693.66064453125 ,1693.552734375 ,1693.66064453125 ,1693.66064453125 ,1693.66064453125 ,1693.462646484375 ,1693.64208984375 ,1693.66064453125 ,1693.552734375 ,1693.462646484375 ,1693.66064453125 ,1693.64208984375 ,1693.6607666015625 ,1693.8665771484375 ,1693.7630615234375 ,1693.4378662109375 ,1693.8438720703125 ,1693.083984375 ,1693.7384033203125 ,1691.991943359375 ,1691.950927734375 ,1693.604248046875 ,1693.063232421875 ,1693.0499267578125 ,1693.001220703125 ,1693.001220703125 ,1693.001220703125 ,1693.0499267578125 ,1693.063232421875 ,1693.462646484375 ,1693.0499267578125 ,1693.001220703125 ,1693.0010986328125 ,1693.0010986328125 ,1693.001220703125 ,1693.001220703125 ,1693.0010986328125 ,1693.604248046875 ,1692.0390625 ,1691.991943359375 ,1692.4864501953125 ,1692.494140625 ,1692.494140625 ,1692.026123046875 ,1692.538330078125 ,1693.0140380859375 ,1693.604248046875 ,1691.950927734375 ,1692.026123046875 ,1693.86083984375 ,1693.8665771484375 ,1693.4378662109375 ,1693.8665771484375 ,1693.86083984375 ,1694.043212890625 ,1693.7635498046875 ,1693.7630615234375 ,1693.8665771484375 ,1692.4945068359375 ,1692.2333984375 ,1692.494140625 ,1692.026123046875 ,1693.0140380859375 ,1692.9134521484375 ,1692.5889892578125 ,1692.494140625 ,1693.604248046875 ,1692.5889892578125 ,1693.604248046875 ,1692.598876953125 ,1693.604248046875 ,1692.494140625 ,1692.0390625 ,1694.043212890625 ,1693.6885986328125 ,1693.64208984375 ,1692.4945068359375 ,1692.494140625 ,1692.4942626953125 ,1692.15234375 ,1692.223876953125 ,1692.026123046875 ,1693.6707763671875 ,1693.083984375 ,1693.8438720703125 ,1693.7384033203125 ,1693.083984375 ,1693.604248046875 ,1693.083984375 ,1692.4945068359375 ,1692.598876953125 ,1692.598876953125 ,1692.4945068359375 ,1692.4942626953125 ,1692.979736328125 ,1693.462646484375 ,1693.604248046875 ,1693.552734375 ,1693.604248046875 ,1693.462646484375 ,1692.026123046875 ,1692.223876953125 ,1692.538330078125 ,1693.462646484375 ,1693.4378662109375 ,1693.64208984375 ,1693.0499267578125 ,1693.462646484375 ,1692.979736328125 ,1693.604248046875 ,1693.083984375 ,1692.598876953125 ,1692.026123046875 ,1692.9134521484375 ,1693.0009765625 ,1693.0009765625 ,1693.0009765625 ,1692.9134521484375 ,1693.0009765625 ,1693.0010986328125 ,1693.0010986328125 ,1693.0009765625 ,1693.0010986328125 ,1693.0009765625 ,1693.0009765625 ,1693.0010986328125 ,1693.001220703125 ,1693.604248046875 ,1692.026123046875 ,1692.979736328125 ,1692.0390625 ,1692.0303955078125 ,1691.991943359375 ,1692.0390625 ,1692.0306396484375 ,1692.0303955078125 ,1691.605712890625 ,1692.0306396484375 ,1692.1171875 ,1692.0306396484375 ,1692.0390625 ,1692.1171875 ,1691.991943359375 ,1692.0303955078125 ,1691.605712890625 ,1692.0306396484375 ,1691.605712890625 ,1692.0303955078125 ,1691.991943359375 ,1691.605712890625 ,1690.4541015625 ,1694.115234375 ,1694.019775390625 ,1693.7384033203125 ,1694.117919921875 ,1694.115234375 ,1693.7384033203125 ,1694.019775390625 ,1693.8438720703125 ,1693.7384033203125 ,1693.083984375 ,1692.2333984375 ,1692.4945068359375 ,-22.078006744384766 ,-14.041504859924316 ,-18.67672348022461 ,-22.078006744384766 ,-18.395246505737305 ,-14.041504859924316 ,-22.078006744384766 ,-22.34345817565918 ,-23.613245010375977 ,-22.078006744384766 ,-18.67672348022461 ,-22.34345817565918 ,-14.041504859924316 ,-10.522645950317383 ,-18.67672348022461 ,-8.074176788330078 ,-4.114527225494385 ,-3.990647077560425 ,-8.074176788330078 ,-4.152342319488525 ,-4.114527225494385 ,-7.093686103820801 ,-4.152342319488525 ,-8.074176788330078 ,-3.124228000640869 ,-8.074176788330078 ,-3.990647077560425 ,-8.074176788330078 ,-3.124228000640869 ,-14.250904083251953 ,-8.074176788330078 ,-14.250904083251953 ,-10.522645950317383 ,-8.074176788330078 ,-7.460494041442871 ,-7.093686103820801 ,-7.460494041442871 ,-8.074176788330078 ,-10.522645950317383 ,-3.124228000640869 ,-12.568105697631836 ,-15.349625587463379 ,-3.124228000640869 ,-3.8040237426757812 ,-12.568105697631836 ,-3.124228000640869 ,-15.349625587463379 ,-14.250904083251953 ,1653.762939453125 ,1654.4324951171875 ,1653.921875 ,1653.921875 ,1652.6387939453125 ,1655.2957763671875 ,1591.3856201171875 ,1591.477294921875 ,1591.5047607421875 ,1591.3856201171875 ,1591.5047607421875 ,1591.5128173828125 ,1591.477294921875 ,1591.3856201171875 ,1604.1265869140625 ,1591.3856201171875 ,1614.6343994140625 ,1604.1265869140625 ,1599.342529296875 ,1588.2908935546875 ,1591.5128173828125 ,1591.3856201171875 ,1591.5128173828125 ,1588.2908935546875 ,1591.3856201171875 ,1588.2908935546875 ,1614.6343994140625 ,1604.1265869140625 ,1614.6343994140625 ,1638.3662109375 ,1588.2908935546875 ,1612.8060302734375 ,1614.6343994140625 ,1599.342529296875 ,1612.8060302734375 ,1588.2908935546875 ,-18.67672348022461 ,-16.697416305541992 ,-22.34345817565918 ,1653.921875 ,1654.4324951171875 ,1652.6387939453125 ,1692.598876953125 ,1692.4942626953125 ,1692.4942626953125 ,1692.4942626953125 ,1692.494140625 ,1692.494140625 ,1692.4942626953125 ,1692.494140625 ,1692.4942626953125 ,1692.598876953125 ,1692.4942626953125 ,1692.5889892578125 ,1692.494140625 ,1692.5889892578125 ,1692.4942626953125 ,1658.14501953125 ,1653.60546875 ,1660.2691650390625 ,1660.2691650390625 ,1662.6553955078125 ,1662.9305419921875 ,1653.762939453125 ,1653.8194580078125 ,1654.4324951171875 ,1589.9910888671875 ,1595.1080322265625 ,1583.322509765625 ,1589.9910888671875 ,1586.9632568359375 ,1593.12060546875 ,1589.9910888671875 ,1566.90966796875 ,1586.9632568359375 ,1589.9910888671875 ,1583.322509765625 ,1566.90966796875 ,1561.478515625 ,1555.912109375 ,1566.90966796875 ,1561.478515625 ,1566.90966796875 ,1583.322509765625 ,1583.322509765625 ,1561.940673828125 ,1561.478515625 ,1578.15625 ,1586.9632568359375 ,1569.218505859375 ,1586.9632568359375 ,1566.90966796875 ,1569.218505859375 ,1569.218505859375 ,1566.90966796875 ,1564.7476806640625 ,1569.218505859375 ,1556.6446533203125 ,1578.15625 ,1569.218505859375 ,1564.7476806640625 ,1556.6446533203125 ,-89.8196029663086 ,-150.53488159179688 ,-109.00877380371094 ,-89.8196029663086 ,-133.311767578125 ,-150.53488159179688 ,-109.00877380371094 ,-34.57811737060547 ,-89.8196029663086 ,-109.00877380371094 ,-157.6728057861328 ,-103.03058624267578 ,-109.00877380371094 ,-103.03058624267578 ,-34.57811737060547 ,-109.00877380371094 ,-150.53488159179688 ,-157.6728057861328 ,-89.8196029663086 ,-34.57811737060547 ,-36.70216751098633 ,-89.8196029663086 ,-66.08543395996094 ,-133.311767578125 ,-89.8196029663086 ,-36.70216751098633 ,-66.08543395996094 ,-34.57811737060547 ,-103.03058624267578 ,-63.30964660644531 ,-63.30964660644531 ,8.339337348937988 ,-34.57811737060547 ,-63.30964660644531 ,-56.809120178222656 ,8.339337348937988 ,-63.30964660644531 ,-103.03058624267578 ,-56.809120178222656 ,-34.57811737060547 ,8.339337348937988 ,2.1524689197540283 ,-157.6728057861328 ,-160.4052734375 ,-103.03058624267578 ,-160.4052734375 ,-174.69415283203125 ,-160.4145050048828 ,-160.4052734375 ,-157.6728057861328 ,-174.69415283203125 ,-160.4052734375 ,-126.63951873779297 ,-56.809120178222656 ,-160.4052734375 ,-160.4145050048828 ,-126.63951873779297 ,-160.4052734375 ,-56.809120178222656 ,-103.03058624267578 ,-56.809120178222656 ,-126.63951873779297 ,-51.2064323425293 ,-160.4145050048828 ,-115.750732421875 ,-126.63951873779297 ,-160.4145050048828 ,-192.82810974121094 ,-115.750732421875 ,-160.4145050048828 ,-185.39739990234375 ,-192.82810974121094 ,-160.4145050048828 ,-174.69415283203125 ,-185.39739990234375 ,-126.63951873779297 ,-77.1824951171875 ,-51.2064323425293 ,-126.63951873779297 ,-115.750732421875 ,-77.1824951171875 ,-185.39739990234375 ,-206.7493438720703 ,-192.82810974121094 ,-185.39739990234375 ,-174.69415283203125 ,-206.7493438720703 ,-192.82810974121094 ,-206.7493438720703 ,-199.23886108398438 ,-192.82810974121094 ,-173.3287353515625 ,-115.750732421875 ,-192.82810974121094 ,-199.23886108398438 ,-173.3287353515625 ,-115.750732421875 ,-100.14134216308594 ,-77.1824951171875 ,-115.750732421875 ,-173.3287353515625 ,-100.14134216308594 ,-179.4665985107422 ,-169.84422302246094 ,-206.7493438720703 ,-179.4665985107422 ,-206.7493438720703 ,-174.69415283203125 ,-179.4665985107422 ,-174.69415283203125 ,-171.90296936035156 ,-169.84422302246094 ,-176.05056762695312 ,-206.7493438720703 ,-206.7493438720703 ,-176.05056762695312 ,-207.0570831298828 ,-176.05056762695312 ,-130.2546844482422 ,-207.0570831298828 ,-206.7493438720703 ,-207.0570831298828 ,-208.20806884765625 ,-206.7493438720703 ,-208.20806884765625 ,-199.23886108398438 ,-173.3287353515625 ,-199.23886108398438 ,-123.43728637695312 ,-173.3287353515625 ,-123.43728637695312 ,-100.14134216308594 ,-207.0570831298828 ,-154.3573760986328 ,-201.90676879882812 ,-207.0570831298828 ,-130.2546844482422 ,-154.3573760986328 ,-208.20806884765625 ,-207.0570831298828 ,-201.90676879882812 ,-199.23886108398438 ,-145.39947509765625 ,-123.43728637695312 ,-154.3573760986328 ,-143.7244415283203 ,-201.90676879882812 ,-154.3573760986328 ,-78.17221069335938 ,-143.7244415283203 ,-201.90676879882812 ,-143.7244415283203 ,-162.1982421875 ,-208.20806884765625 ,-162.1982421875 ,-199.23886108398438 ,-208.20806884765625 ,-201.90676879882812 ,-162.1982421875 ,-199.23886108398438 ,-162.1982421875 ,-145.39947509765625 ,-154.3573760986328 ,-101.03582763671875 ,-78.17221069335938 ,-154.3573760986328 ,-130.2546844482422 ,-101.03582763671875 ,-78.17221069335938 ,-62.0050163269043 ,-143.7244415283203 ,-143.7244415283203 ,-117.98065185546875 ,-162.1982421875 ,-143.7244415283203 ,-62.0050163269043 ,-117.98065185546875 ,-62.0050163269043 ,-33.88139724731445 ,-46.53553771972656 ,-62.0050163269043 ,-59.29496765136719 ,-33.88139724731445 ,-62.0050163269043 ,-78.17221069335938 ,-59.29496765136719 ,-62.0050163269043 ,-46.53553771972656 ,-117.98065185546875 ,-117.98065185546875 ,-81.39241027832031 ,-162.1982421875 ,-117.98065185546875 ,-46.53553771972656 ,-81.39241027832031 ,-46.53553771972656 ,-33.88139724731445 ,-15.475028991699219 ,-46.53553771972656 ,-15.475028991699219 ,-13.398571968078613 ,-33.88139724731445 ,-42.675846099853516 ,-15.475028991699219 ,-33.88139724731445 ,-56.601097106933594 ,-42.675846099853516 ,-33.88139724731445 ,-59.29496765136719 ,-56.601097106933594 ,-46.53553771972656 ,-13.398571968078613 ,-21.310529708862305 ,-15.475028991699219 ,-12.716116905212402 ,-13.398571968078613 ,-15.475028991699219 ,-42.675846099853516 ,-12.716116905212402 ,-13.398571968078613 ,-12.716116905212402 ,1.7251709699630737 ,-13.398571968078613 ,1.7251709699630737 ,-21.310529708862305 ,-42.675846099853516 ,-55.921024322509766 ,-12.716116905212402 ,1660.006591796875 ,1669.516845703125 ,1676.0706787109375 ,1676.0706787109375 ,1668.263916015625 ,1660.006591796875 ,1.7251709699630737 ,11.736113548278809 ,-21.310529708862305 ,1.7251709699630737 ,-5.650778770446777 ,11.736113548278809 ,11.736113548278809 ,12.619827270507812 ,14.872888565063477 ,11.736113548278809 ,-5.650778770446777 ,12.619827270507812 ,11.736113548278809 ,14.872888565063477 ,-21.310529708862305 ,1660.006591796875 ,1664.9896240234375 ,1658.31884765625 ,-5.650778770446777 ,-16.302066802978516 ,12.619827270507812 ,-5.650778770446777 ,-41.81604766845703 ,-16.302066802978516 ,-32.67344665527344 ,-48.96576690673828 ,-27.70221519470215 ,-32.67344665527344 ,-27.70221519470215 ,-5.650778770446777 ,-32.67344665527344 ,-5.650778770446777 ,1.7251709699630737 ,-32.67344665527344 ,1.7251709699630737 ,-12.716116905212402 ,-48.96576690673828 ,-115.81771850585938 ,-27.70221519470215 ,-48.96576690673828 ,-55.921024322509766 ,-115.81771850585938 ,-48.96576690673828 ,-32.67344665527344 ,-55.921024322509766 ,-27.70221519470215 ,-115.81771850585938 ,-41.81604766845703 ,-27.70221519470215 ,-41.81604766845703 ,-5.650778770446777 ,-115.81771850585938 ,-153.8647003173828 ,-41.81604766845703 ,-115.81771850585938 ,-141.76710510253906 ,-153.8647003173828 ,-41.81604766845703 ,-153.8647003173828 ,-141.81932067871094 ,1653.60546875 ,1646.0224609375 ,1656.8359375 ,1646.0224609375 ,1643.9544677734375 ,1651.05126953125 ,1645.3182373046875 ,1647.8907470703125 ,1646.0880126953125 ,1646.0880126953125 ,1650.7645263671875 ,1643.419677734375 ,1646.0880126953125 ,1643.419677734375 ,1645.3182373046875 ,1684.72509765625 ,1683.3270263671875 ,1684.0565185546875 ,1683.3270263671875 ,1680.6246337890625 ,1684.0565185546875 ,1600.574462890625 ,1597.1424560546875 ,1608.5126953125 ,1600.574462890625 ,1595.56201171875 ,1597.1424560546875 ,1600.574462890625 ,1599.3277587890625 ,1595.56201171875 ,1604.699951171875 ,1600.057861328125 ,1594.5146484375 ,-56.809120178222656 ,18.396892547607422 ,8.339337348937988 ,-56.809120178222656 ,-51.2064323425293 ,-25.64232063293457 ,-56.809120178222656 ,-25.64232063293457 ,18.396892547607422 ,8.339337348937988 ,18.396892547607422 ,49.47584915161133 ,8.339337348937988 ,49.47584915161133 ,2.1524689197540283 ,18.396892547607422 ,43.552696228027344 ,49.47584915161133 ,18.396892547607422 ,40.656192779541016 ,43.552696228027344 ,18.396892547607422 ,-25.64232063293457 ,-3.302182912826538 ,18.396892547607422 ,-3.302182912826538 ,40.656192779541016 ,49.47584915161133 ,74.95420837402344 ,2.1524689197540283 ,-51.2064323425293 ,-77.1824951171875 ,-41.43098068237305 ,-51.2064323425293 ,-41.43098068237305 ,-25.64232063293457 ,-77.1824951171875 ,-100.14134216308594 ,-34.37968444824219 ,-77.1824951171875 ,-34.37968444824219 ,-41.43098068237305 ,1584.2979736328125 ,1579.9024658203125 ,1586.1710205078125 ,1584.2979736328125 ,1586.1710205078125 ,1591.043701171875 ,1584.2979736328125 ,1567.23486328125 ,1575.6142578125 ,-100.14134216308594 ,-48.63642501831055 ,-34.37968444824219 ,-100.14134216308594 ,-123.43728637695312 ,-48.63642501831055 ,-169.84422302246094 ,-179.4665985107422 ,-172.1576690673828 ,-169.84422302246094 ,-172.1576690673828 ,-162.84446716308594 ,-169.84422302246094 ,-162.84446716308594 ,-176.05056762695312 ,-179.4665985107422 ,-172.62753295898438 ,-172.1576690673828 ,-179.4665985107422 ,-173.61891174316406 ,-172.62753295898438 ,-123.43728637695312 ,-105.95997619628906 ,-48.63642501831055 ,-123.43728637695312 ,-145.39947509765625 ,-105.95997619628906 ,-48.63642501831055 ,-105.95997619628906 ,-39.77711486816406 ,-34.37968444824219 ,-48.63642501831055 ,-19.138835906982422 ,-34.37968444824219 ,-2.8962490558624268 ,-41.43098068237305 ,-48.63642501831055 ,-39.77711486816406 ,-19.138835906982422 ,-176.05056762695312 ,-138.59707641601562 ,-130.2546844482422 ,-176.05056762695312 ,-162.84446716308594 ,-138.59707641601562 ,-105.95997619628906 ,-74.04899597167969 ,-39.77711486816406 ,-130.2546844482422 ,-119.7644271850586 ,-101.03582763671875 ,-130.2546844482422 ,-138.59707641601562 ,-119.7644271850586 ,-105.95997619628906 ,-112.6689453125 ,-74.04899597167969 ,-105.95997619628906 ,-145.39947509765625 ,-112.6689453125 ,-101.03582763671875 ,-105.42487335205078 ,-84.01447296142578 ,-101.03582763671875 ,-84.01447296142578 ,-78.17221069335938 ,-101.03582763671875 ,-119.7644271850586 ,-105.42487335205078 ,-105.42487335205078 ,-119.7644271850586 ,-116.43907928466797 ,-84.01447296142578 ,-59.29496765136719 ,-78.17221069335938 ,-84.01447296142578 ,-83.364990234375 ,-59.29496765136719 ,-84.01447296142578 ,-97.04484558105469 ,-83.364990234375 ,-84.01447296142578 ,-105.42487335205078 ,-97.04484558105469 ,-59.29496765136719 ,-83.364990234375 ,-56.601097106933594 ,-85.35469818115234 ,-46.41098403930664 ,-114.72260284423828 ,-85.35469818115234 ,-114.72260284423828 ,-121.46614837646484 ,-85.35469818115234 ,-121.46614837646484 ,-162.1982421875 ,-85.35469818115234 ,-42.26219940185547 ,-46.41098403930664 ,-85.35469818115234 ,-162.1982421875 ,-81.39241027832031 ,-85.35469818115234 ,-81.39241027832031 ,-42.26219940185547 ,-46.41098403930664 ,13.099784851074219 ,-48.63685607910156 ,-46.41098403930664 ,-48.63685607910156 ,-114.72260284423828 ,-46.41098403930664 ,-3.9420969486236572 ,13.099784851074219 ,-46.41098403930664 ,-42.26219940185547 ,-3.9420969486236572 ,-114.72260284423828 ,-48.63685607910156 ,-112.6689453125 ,-56.601097106933594 ,-88.66790771484375 ,-106.64468383789062 ,-56.601097106933594 ,-106.64468383789062 ,-42.675846099853516 ,-88.66790771484375 ,-83.364990234375 ,-92.26326751708984 ,-88.66790771484375 ,-56.601097106933594 ,-83.364990234375 ,-88.66790771484375 ,-92.26326751708984 ,-106.64468383789062 ,12.619827270507812 ,30.269346237182617 ,14.872888565063477 ,12.619827270507812 ,-56.9789924621582 ,30.269346237182617 ,12.619827270507812 ,-16.302066802978516 ,-56.9789924621582 ,14.872888565063477 ,30.269346237182617 ,23.160655975341797 ,14.872888565063477 ,-3.9420969486236572 ,-21.310529708862305 ,14.872888565063477 ,23.160655975341797 ,-3.9420969486236572 ,-106.64468383789062 ,-55.921024322509766 ,-42.675846099853516 ,30.269346237182617 ,-56.9789924621582 ,38.12131881713867 ,30.269346237182617 ,38.12131881713867 ,23.160655975341797 ,1595.56201171875 ,1589.62109375 ,1592.21435546875 ,1595.56201171875 ,1592.21435546875 ,1597.1424560546875 ,1599.3277587890625 ,1588.5467529296875 ,1595.56201171875 ,1599.3277587890625 ,1596.0208740234375 ,1588.5467529296875 ,1558.611572265625 ,1563.7801513671875 ,1556.9703369140625 ,1563.7801513671875 ,1565.1370849609375 ,1556.9703369140625 ,-39.77711486816406 ,-74.04899597167969 ,-33.32817077636719 ,-39.77711486816406 ,-33.32817077636719 ,-13.140868186950684 ,-39.77711486816406 ,-13.140868186950684 ,-19.138835906982422 ,-33.32817077636719 ,-74.04899597167969 ,-47.92860794067383 ,1644.2950439453125 ,1643.993896484375 ,1643.5936279296875 ,1644.2950439453125 ,1642.0712890625 ,1645.3931884765625 ,1643.5936279296875 ,1645.533203125 ,1644.2950439453125 ,1643.5936279296875 ,1643.993896484375 ,1643.3203125 ,1643.5936279296875 ,1643.3203125 ,1645.533203125 ,1644.2950439453125 ,1631.4022216796875 ,1642.0712890625 ,1644.2950439453125 ,1645.533203125 ,1631.4022216796875 ,-141.20297241210938 ,-139.79461669921875 ,-160.13168334960938 ,-139.79461669921875 ,-141.20297241210938 ,-116.43907928466797 ,1645.790283203125 ,1645.3931884765625 ,1647.38427734375 ,1645.790283203125 ,1644.2950439453125 ,1645.3931884765625 ,1645.790283203125 ,1643.993896484375 ,1644.2950439453125 ,1645.790283203125 ,1643.9893798828125 ,1643.993896484375 ,38.12131881713867 ,-56.9789924621582 ,-33.199073791503906 ,38.12131881713867 ,-33.199073791503906 ,18.952594757080078 ,1672.689208984375 ,1678.28515625 ,1673.563720703125 ,1672.689208984375 ,1678.9876708984375 ,1678.28515625 ,1662.4249267578125 ,1661.6611328125 ,1659.3795166015625 ,1662.4249267578125 ,1665.322509765625 ,1661.6611328125 ,1600.8250732421875 ,1598.179443359375 ,1600.48583984375 ,1586.4669189453125 ,1592.21435546875 ,1589.62109375 ,1586.4669189453125 ,1584.6922607421875 ,1573.8131103515625 ,1586.4669189453125 ,1589.62109375 ,1584.6922607421875 ,43.1501350402832 ,57.81092834472656 ,11.090381622314453 ,43.1501350402832 ,11.090381622314453 ,5.952480792999268 ,43.1501350402832 ,5.952480792999268 ,28.987707138061523 ,57.81092834472656 ,40.29792022705078 ,11.090381622314453 ,57.81092834472656 ,68.86013793945312 ,40.29792022705078 ,5.952480792999268 ,0.48955801129341125 ,28.987707138061523 ,-45.7297248840332 ,14.137516021728516 ,-65.73291778564453 ,-45.7297248840332 ,-65.73291778564453 ,-79.09713745117188 ,-45.7297248840332 ,-48.63685607910156 ,14.137516021728516 ,-45.7297248840332 ,-79.09713745117188 ,-64.88725280761719 ,-45.7297248840332 ,-64.88725280761719 ,-48.63685607910156 ,14.137516021728516 ,-60.94996643066406 ,-65.73291778564453 ,14.137516021728516 ,-22.468109130859375 ,-60.94996643066406 ,-65.73291778564453 ,-73.2208480834961 ,-79.09713745117188 ,-65.73291778564453 ,-73.13835144042969 ,-73.2208480834961 ,-65.73291778564453 ,-60.94996643066406 ,-73.13835144042969 ,-60.94996643066406 ,-22.468109130859375 ,-73.13835144042969 ,1601.3475341796875 ,1598.990234375 ,1600.99267578125 ,1598.990234375 ,1601.3475341796875 ,1597.3072509765625 ,1598.990234375 ,1594.9661865234375 ,1596.012939453125 ,1598.990234375 ,1596.012939453125 ,1600.99267578125 ,1596.012939453125 ,1575.8009033203125 ,1565.6654052734375 ,1596.012939453125 ,1565.6654052734375 ,1600.99267578125 ,1575.8009033203125 ,1596.181396484375 ,1565.6654052734375 ,1565.6654052734375 ,1545.984375 ,1600.99267578125 ,1565.6654052734375 ,1602.4049072265625 ,1545.984375 ,963.9760131835938 ,984.8864135742188 ,1007.3907470703125 ,963.9760131835938 ,1007.3907470703125 ,706.0634765625 ,819.7655639648438 ,832.3193969726562 ,840.5704345703125 ,819.7655639648438 ,840.5704345703125 ,795.2511596679688 ,819.7655639648438 ,795.2511596679688 ,807.5975952148438 ,819.7655639648438 ,807.5975952148438 ,832.3193969726562 ,626.4420776367188 ,639.5640869140625 ,513.69580078125 ,626.4420776367188 ,664.9578857421875 ,639.5640869140625 ,513.69580078125 ,639.5640869140625 ,481.72210693359375 ,626.4420776367188 ,466.0267333984375 ,495.27227783203125 ,626.4420776367188 ,513.69580078125 ,466.0267333984375 ,1678.83642578125 ,1676.6839599609375 ,1665.4837646484375 ,1678.83642578125 ,1661.302978515625 ,1667.8065185546875 ,1678.83642578125 ,1665.4837646484375 ,1661.302978515625 ,1678.83642578125 ,1667.8065185546875 ,1684.8160400390625 ,179.0661163330078 ,128.33255004882812 ,175.15267944335938 ,179.0661163330078 ,175.15267944335938 ,130.03395080566406 ,179.0661163330078 ,174.18772888183594 ,128.33255004882812 ,179.0661163330078 ,130.03395080566406 ,180.8580780029297 ,179.0661163330078 ,191.36724853515625 ,174.18772888183594 ,179.0661163330078 ,180.8580780029297 ,191.36724853515625 ,-142.7968292236328 ,-141.91162109375 ,-142.61868286132812 ,-142.7968292236328 ,-142.61868286132812 ,-145.7958221435547 ,-141.91162109375 ,-142.7968292236328 ,-145.95632934570312 ,-141.91162109375 ,-140.02178955078125 ,-137.036376953125 ,-141.91162109375 ,-137.036376953125 ,-142.61868286132812 ,-47.92860794067383 ,-53.22135925292969 ,-33.32817077636719 ,-47.92860794067383 ,-60.414794921875 ,-53.22135925292969 ,-47.92860794067383 ,-74.04899597167969 ,-60.414794921875 ,-53.22135925292969 ,-60.414794921875 ,-59.342620849609375 ,-53.22135925292969 ,-59.342620849609375 ,-78.13453674316406 ,-53.22135925292969 ,-78.13453674316406 ,-44.69572830200195 ,-53.22135925292969 ,-29.316699981689453 ,-33.32817077636719 ,-53.22135925292969 ,-44.69572830200195 ,-29.316699981689453 ,-33.32817077636719 ,-29.316699981689453 ,-13.140868186950684 ,-59.342620849609375 ,-60.414794921875 ,-86.93660736083984 ,-59.342620849609375 ,-96.71630096435547 ,-78.13453674316406 ,-59.342620849609375 ,-86.93660736083984 ,-96.71630096435547 ,-60.414794921875 ,-73.13835144042969 ,-86.93660736083984 ,-86.93660736083984 ,-72.85733032226562 ,-84.05589294433594 ,-86.93660736083984 ,-73.13835144042969 ,-72.85733032226562 ,-86.93660736083984 ,-84.05589294433594 ,-96.71630096435547 ,1635.4061279296875 ,1592.3297119140625 ,1611.879638671875 ,1635.4061279296875 ,1626.4022216796875 ,1592.3297119140625 ,1635.4061279296875 ,1632.160400390625 ,1626.4022216796875 ,1661.914794921875 ,1647.9464111328125 ,1660.8126220703125 ,1661.914794921875 ,1660.7340087890625 ,1647.9464111328125 ,1661.914794921875 ,1660.8126220703125 ,1672.9698486328125 ,1661.914794921875 ,1672.9698486328125 ,1672.689208984375 ,1677.3021240234375 ,1680.966064453125 ,1683.5225830078125 ,1677.3021240234375 ,1683.5225830078125 ,1683.33642578125 ,1680.966064453125 ,1682.1451416015625 ,1683.5225830078125 ,1680.966064453125 ,1677.3021240234375 ,1670.2049560546875 ,1661.6611328125 ,1660.7755126953125 ,1659.3795166015625 ,1615.9779052734375 ,1608.087646484375 ,1611.5498046875 ,1615.9779052734375 ,1617.1231689453125 ,1608.087646484375 ,1611.5498046875 ,1608.087646484375 ,1608.2562255859375 ,1611.5498046875 ,1608.2562255859375 ,1608.4158935546875 ,1615.9779052734375 ,1615.1318359375 ,1620.0291748046875 ,1615.9779052734375 ,1611.5498046875 ,1615.1318359375 ,1615.9779052734375 ,1620.0291748046875 ,1617.1231689453125 ,1601.3475341796875 ,1600.99267578125 ,1602.775390625 ,1602.775390625 ,1604.4119873046875 ,1601.3475341796875 ,787.8994750976562 ,754.8847045898438 ,757.044189453125 ,824.8201904296875 ,787.9410400390625 ,804.499267578125 ,824.8201904296875 ,831.0919189453125 ,805.5436401367188 ,824.8201904296875 ,828.9366455078125 ,831.0919189453125 ,974.2076416015625 ,890.9190673828125 ,1028.039306640625 ,974.2076416015625 ,1028.039306640625 ,1072.1270751953125 ,396.64276123046875 ,212.82652282714844 ,411.1473388671875 ,396.64276123046875 ,411.1473388671875 ,431.29559326171875 ,396.64276123046875 ,466.0267333984375 ,212.82652282714844 ,1570.0733642578125 ,1561.3687744140625 ,1562.0313720703125 ,-15.03766918182373 ,-3.633512020111084 ,-8.213500022888184 ,-15.03766918182373 ,-8.213500022888184 ,-8.421085357666016 ,-15.03766918182373 ,-29.316699981689453 ,-3.633512020111084 ,-8.213500022888184 ,0.48955801129341125 ,-8.421085357666016 ,-96.71630096435547 ,-109.1400146484375 ,-115.4434585571289 ,-96.71630096435547 ,-115.4434585571289 ,-78.13453674316406 ,-96.71630096435547 ,-84.05589294433594 ,-109.1400146484375 ,-78.13453674316406 ,-115.4434585571289 ,-76.51492309570312 ,-78.13453674316406 ,-76.51492309570312 ,-44.69572830200195 ,1668.092529296875 ,1662.9295654296875 ,1655.194580078125 ,1668.092529296875 ,1655.194580078125 ,1664.110107421875 ,1668.092529296875 ,1677.809814453125 ,1662.9295654296875 ,1666.6029052734375 ,1662.61865234375 ,1665.784912109375 ,1669.9600830078125 ,1668.779541015625 ,1666.6029052734375 ,1666.6029052734375 ,1665.784912109375 ,1669.9600830078125 ,1667.4793701171875 ,1671.78515625 ,1671.0203857421875 ,1667.4793701171875 ,1671.0203857421875 ,1660.8375244140625 ,1671.78515625 ,1678.3294677734375 ,1671.0203857421875 ,1669.9600830078125 ,1665.1942138671875 ,1672.67822265625 ,1669.9600830078125 ,1662.9033203125 ,1665.1942138671875 ,1647.4891357421875 ,1665.1942138671875 ,1662.9033203125 ,1653.5064697265625 ,1648.0313720703125 ,1643.0556640625 ,1648.0313720703125 ,1653.5064697265625 ,1651.9884033203125 ,1648.0313720703125 ,1643.0020751953125 ,1643.0556640625 ,1648.0313720703125 ,1645.1719970703125 ,1643.0020751953125 ,1631.489013671875 ,1622.14599609375 ,1631.9801025390625 ,1631.489013671875 ,1631.9801025390625 ,1643.0556640625 ,1631.489013671875 ,1643.0556640625 ,1643.0020751953125 ,1652.5924072265625 ,1648.6241455078125 ,1650.722900390625 ,1652.5924072265625 ,1650.722900390625 ,1650.67578125 ,1652.5924072265625 ,1650.67578125 ,1653.3548583984375 ,1652.5924072265625 ,1653.3548583984375 ,1650.55078125 ,1652.5924072265625 ,1650.55078125 ,1648.6241455078125 ,1602.5233154296875 ,1601.251953125 ,1602.4737548828125 ,1602.5233154296875 ,1602.937255859375 ,1601.9359130859375 ,1602.5233154296875 ,1602.4737548828125 ,1603.4041748046875 ,1602.5233154296875 ,1603.4041748046875 ,1602.937255859375 ,1602.5233154296875 ,1601.9359130859375 ,1601.251953125 ,1601.251953125 ,1601.906982421875 ,1602.0751953125 ,1601.251953125 ,1602.0751953125 ,1602.4737548828125 ,1574.4058837890625 ,1598.534423828125 ,1527.1690673828125 ,1574.4058837890625 ,1527.1690673828125 ,1520.814453125 ,1574.4058837890625 ,1520.814453125 ,1535.486572265625 ,1598.534423828125 ,1523.725830078125 ,1527.1690673828125 ,1598.534423828125 ,1692.1318359375 ,1523.725830078125 ,1574.4058837890625 ,1595.8814697265625 ,1598.534423828125 ,1574.4058837890625 ,1635.144775390625 ,1595.8814697265625 ,754.792236328125 ,759.50927734375 ,750.8538208007812 ,754.792236328125 ,750.8538208007812 ,752.9854125976562 ,759.50927734375 ,767.7692260742188 ,747.1206665039062 ,759.50927734375 ,754.792236328125 ,787.9410400390625 ,759.50927734375 ,787.9410400390625 ,767.7692260742188 ,759.50927734375 ,747.1206665039062 ,750.8538208007812 ,835.016357421875 ,822.2063598632812 ,826.7001342773438 ,826.7001342773438 ,822.2063598632812 ,816.6506958007812 ,826.7001342773438 ,839.0542602539062 ,835.016357421875 ,1286.781494140625 ,1347.615478515625 ,1312.53857421875 ,1286.781494140625 ,1312.53857421875 ,1264.9102783203125 ,1587.611083984375 ,1587.00634765625 ,1589.919189453125 ,1587.00634765625 ,1587.611083984375 ,1588.2427978515625 ,1587.00634765625 ,1586.2974853515625 ,1589.919189453125 ,1591.425537109375 ,1587.5968017578125 ,1574.3280029296875 ,1591.425537109375 ,1574.3280029296875 ,1573.8773193359375 ,1591.425537109375 ,1573.8773193359375 ,1583.346435546875 ,-170.53453063964844 ,-171.6670379638672 ,-168.3688507080078 ,-170.53453063964844 ,-168.3688507080078 ,-168.31546020507812 ,-170.53453063964844 ,-168.31546020507812 ,-165.09109497070312 ,-171.6670379638672 ,-170.3991241455078 ,-168.3688507080078 ,-170.53453063964844 ,-165.09109497070312 ,-149.0703582763672 ,1589.7457275390625 ,1574.4034423828125 ,1581.365966796875 ,1589.7457275390625 ,1583.048095703125 ,1576.6949462890625 ,1589.7457275390625 ,1576.6949462890625 ,1574.4034423828125 ,1581.365966796875 ,1578.88525390625 ,1589.28662109375 ,1581.365966796875 ,1589.28662109375 ,1589.7457275390625 ,1581.365966796875 ,1574.4034423828125 ,1578.88525390625 ,-146.88943481445312 ,-170.53453063964844 ,-149.0703582763672 ,1584.7598876953125 ,1604.6942138671875 ,1588.1116943359375 ,1588.1116943359375 ,1623.9122314453125 ,1611.879638671875 ,1588.1116943359375 ,1604.6942138671875 ,1623.9122314453125 ,1668.779541015625 ,1668.600830078125 ,1666.97705078125 ,1668.779541015625 ,1670.8912353515625 ,1668.600830078125 ,1669.9600830078125 ,1672.989013671875 ,1668.779541015625 ,1668.779541015625 ,1672.989013671875 ,1670.8912353515625 ,1669.9600830078125 ,1679.5113525390625 ,1672.989013671875 ,1669.9600830078125 ,1672.67822265625 ,1679.5113525390625 ,1682.659912109375 ,1679.5113525390625 ,1672.67822265625 ,1682.659912109375 ,1672.67822265625 ,1675.47314453125 ,1669.422119140625 ,1668.8963623046875 ,1672.3447265625 ,1669.422119140625 ,1669.1170654296875 ,1668.8963623046875 ,1669.422119140625 ,1670.5738525390625 ,1669.1170654296875 ,1669.422119140625 ,1672.3447265625 ,1670.5738525390625 ,1668.8963623046875 ,1669.373046875 ,1672.3447265625 ,1668.8963623046875 ,1666.7664794921875 ,1669.373046875 ,1668.8963623046875 ,1669.1170654296875 ,1668.46630859375 ,1668.8963623046875 ,1668.46630859375 ,1666.7664794921875 ,1672.3447265625 ,1669.373046875 ,1671.40869140625 ,1603.279296875 ,1604.43994140625 ,1603.49072265625 ,1603.279296875 ,1609.2413330078125 ,1604.43994140625 ,1603.279296875 ,1610.650146484375 ,1609.2413330078125 ,2391.385498046875 ,2080.4912109375 ,1980.4984130859375 ,2391.385498046875 ,1980.4984130859375 ,2119.65625 ,1395.549560546875 ,1249.8555908203125 ,1409.114990234375 ,1395.549560546875 ,1409.114990234375 ,1487.9423828125 ,255.31051635742188 ,249.11463928222656 ,238.97511291503906 ,255.31051635742188 ,297.4990234375 ,249.11463928222656 ,1571.35205078125 ,1563.31787109375 ,1536.8348388671875 ,1643.8046875 ,1623.39892578125 ,1614.394775390625 ,1643.8046875 ,1614.394775390625 ,1615.4398193359375 ,1643.8046875 ,1615.4398193359375 ,1617.8851318359375 ,1643.8046875 ,1617.8851318359375 ,1632.698974609375 ,17.356164932250977 ,73.47518157958984 ,130.1804656982422 ,1608.6427001953125 ,1614.394775390625 ,1623.39892578125 ,1592.60205078125 ,1592.45556640625 ,1595.38623046875 ,1592.60205078125 ,1595.38623046875 ,1598.5628662109375 ,1592.8089599609375 ,1595.5892333984375 ,1593.73681640625 ,1589.6549072265625 ,1586.105712890625 ,1592.8089599609375 ,1592.8089599609375 ,1586.105712890625 ,1583.74853515625 ,1592.8089599609375 ,1583.74853515625 ,1587.5968017578125 ,1592.8089599609375 ,1587.5968017578125 ,1595.5892333984375 ,1589.7457275390625 ,1591.1009521484375 ,1590.2808837890625 ,1589.7457275390625 ,1590.2808837890625 ,1588.25830078125 ,1589.7457275390625 ,1589.28662109375 ,1591.1009521484375 ,1591.1009521484375 ,1589.28662109375 ,1589.6549072265625 ,1590.2808837890625 ,1589.70556640625 ,1588.25830078125 ,1590.2808837890625 ,1591.1009521484375 ,1593.73681640625 ,1594.6444091796875 ,1589.70556640625 ,1590.2808837890625 ,1594.6444091796875 ,1592.0350341796875 ,1589.70556640625 ,1594.6444091796875 ,1597.8408203125 ,1592.0350341796875 ,1590.2808837890625 ,1593.73681640625 ,1594.6444091796875 ,1594.6444091796875 ,1593.73681640625 ,1597.8408203125 ,1593.73681640625 ,1591.1009521484375 ,1592.8089599609375 ,1636.6739501953125 ,1636.2884521484375 ,1636.0416259765625 ,1636.6739501953125 ,1636.0416259765625 ,1638.38623046875 ,1365.138916015625 ,1338.2554931640625 ,1416.5341796875 ,1365.138916015625 ,1337.89208984375 ,1338.2554931640625 ,1338.2554931640625 ,1426.50927734375 ,1416.5341796875 ,793.1922607421875 ,783.279052734375 ,784.7091674804688 ,793.1922607421875 ,785.9707641601562 ,783.279052734375 ,687.8463134765625 ,804.3577270507812 ,729.5888061523438 ,804.7008056640625 ,690.8013305664062 ,831.5140991210938 ,577.8530883789062 ,561.6047973632812 ,570.5283203125 ,570.5283203125 ,561.6047973632812 ,461.52252197265625 ,570.5283203125 ,461.52252197265625 ,500.4654235839844 ,570.5283203125 ,659.8430786132812 ,577.8530883789062 ,570.5283203125 ,500.4654235839844 ,659.8430786132812 ,-33.623085021972656 ,36.17856216430664 ,43.51447677612305 ,43.51447677612305 ,81.85975646972656 ,-33.623085021972656 ,43.51447677612305 ,36.17856216430664 ,143.64382934570312 ,43.51447677612305 ,143.64382934570312 ,81.85975646972656 ,-161.3847198486328 ,-159.86285400390625 ,-158.8724822998047 ,-161.3847198486328 ,-158.8724822998047 ,-168.5785675048828 ,-161.3847198486328 ,-156.71910095214844 ,-151.15257263183594 ,-161.3847198486328 ,-151.15257263183594 ,-159.86285400390625 ,-159.86285400390625 ,-151.15257263183594 ,-158.8724822998047 ,-158.8724822998047 ,-223.46041870117188 ,-168.5785675048828 ,-158.8724822998047 ,-160.0223388671875 ,-223.46041870117188 ,1598.5628662109375 ,1595.38623046875 ,1596.6580810546875 ,1598.5628662109375 ,1596.6580810546875 ,1599.1964111328125 ,32.23271942138672 ,57.19397735595703 ,70.94438171386719 ,57.19397735595703 ,32.23271942138672 ,-1.4779369831085205 ,-101.66226959228516 ,-107.33910369873047 ,-111.78158569335938 ,-107.33910369873047 ,-101.66226959228516 ,-101.7322006225586 ,-111.78158569335938 ,-107.33910369873047 ,-121.79351806640625 ,1416.5341796875 ,1426.50927734375 ,1408.5682373046875 ,850.3648681640625 ,842.852294921875 ,843.8851318359375 ,850.3648681640625 ,843.8851318359375 ,853.804443359375 ,850.3648681640625 ,853.804443359375 ,850.6434326171875 ,850.3648681640625 ,850.6434326171875 ,842.852294921875 ,-111.78158569335938 ,-121.79351806640625 ,-115.61714172363281 ,-121.79351806640625 ,-107.33910369873047 ,-122.85227966308594 ,-101.66226959228516 ,-111.78158569335938 ,-103.09947967529297 ,-153.8604736328125 ,-155.86891174316406 ,-151.68954467773438 ,-153.8604736328125 ,-151.51779174804688 ,-154.77008056640625 ,-153.8604736328125 ,-151.68954467773438 ,-151.51779174804688 ,-153.8604736328125 ,-154.77008056640625 ,-155.86891174316406 ,-151.68954467773438 ,-155.86891174316406 ,-150.98208618164062 ,-151.68954467773438 ,-150.98208618164062 ,-149.96043395996094 ,-126.32351684570312 ,-121.79351806640625 ,-134.15402221679688 ,-126.32351684570312 ,-132.725341796875 ,-132.94859313964844 ,-126.32351684570312 ,-134.15402221679688 ,-132.725341796875 ,-115.61714172363281 ,-109.3658218383789 ,-111.78158569335938 ,-115.61714172363281 ,-121.79351806640625 ,-126.32351684570312 ,-123.66742706298828 ,-115.61714172363281 ,-129.9468536376953 ,-123.66742706298828 ,-129.9468536376953 ,-126.44894409179688 ,-123.66742706298828 ,-113.3846435546875 ,-115.61714172363281 ,-123.66742706298828 ,-126.44894409179688 ,-113.3846435546875 ,-115.61714172363281 ,-109.99552917480469 ,-109.3658218383789 ,-115.61714172363281 ,-113.3846435546875 ,-109.99552917480469 ,-109.3658218383789 ,-103.09947967529297 ,-111.78158569335938 ,1847.626220703125 ,1932.8714599609375 ,1831.2437744140625 ,1847.626220703125 ,1833.514404296875 ,1932.8714599609375 ,1847.626220703125 ,1831.2437744140625 ,1798.1724853515625 ,1932.8714599609375 ,1833.514404296875 ,1936.465576171875 ,1932.8714599609375 ,1940.2425537109375 ,1831.2437744140625 ,1696.6854248046875 ,1555.0970458984375 ,1549.762451171875 ,1696.6854248046875 ,1539.79345703125 ,1555.0970458984375 ,1487.403564453125 ,1523.0828857421875 ,1539.79345703125 ,1539.79345703125 ,1523.0828857421875 ,1555.0970458984375 ,791.40380859375 ,797.864990234375 ,789.9561767578125 ,791.40380859375 ,793.5814208984375 ,806.5706176757812 ,808.4400634765625 ,830.1715087890625 ,840.1530151367188 ,808.4400634765625 ,825.4397583007812 ,830.1715087890625 ,808.4400634765625 ,795.55419921875 ,790.466796875 ,808.4400634765625 ,790.466796875 ,825.4397583007812 ,789.7568359375 ,797.0664672851562 ,779.9949951171875 ,789.7568359375 ,812.1361083984375 ,797.0664672851562 ,789.7568359375 ,766.7696533203125 ,812.1361083984375 ,789.7568359375 ,688.0762329101562 ,766.7696533203125 ,789.7568359375 ,779.9949951171875 ,688.0762329101562 ,797.0664672851562 ,810.6036987304688 ,779.9949951171875 ,797.0664672851562 ,812.1361083984375 ,810.6036987304688 ,892.685302734375 ,880.9247436523438 ,880.638427734375 ,892.685302734375 ,880.638427734375 ,894.0360717773438 ,880.9247436523438 ,892.685302734375 ,867.0675048828125 ,880.9247436523438 ,867.0675048828125 ,841.958740234375 ,880.9247436523438 ,862.8421630859375 ,880.638427734375 ,880.9247436523438 ,874.3663940429688 ,862.8421630859375 ,880.9247436523438 ,841.958740234375 ,874.3663940429688 ,-164.4443359375 ,-166.4710693359375 ,-162.0017547607422 ,-164.4443359375 ,-162.0017547607422 ,-161.59715270996094 ,-164.4443359375 ,-161.59715270996094 ,-160.6448974609375 ,-164.4443359375 ,-160.6448974609375 ,-166.4710693359375 ,-166.4710693359375 ,-166.76596069335938 ,-162.0017547607422 ,-166.4710693359375 ,-165.97145080566406 ,-166.76596069335938 ,-162.0017547607422 ,-155.74285888671875 ,-161.59715270996094 ,-162.0017547607422 ,-146.23471069335938 ,-155.74285888671875 ,-155.74285888671875 ,-146.23471069335938 ,-149.89404296875 ,-155.74285888671875 ,-149.89404296875 ,-152.16177368164062 ,-155.74285888671875 ,-152.16177368164062 ,-161.59715270996094 ,-146.23471069335938 ,-144.7054901123047 ,-149.89404296875 ,-144.7054901123047 ,-146.23471069335938 ,-123.2982406616211 ,-144.7054901123047 ,-137.40309143066406 ,-149.89404296875 ,-144.7054901123047 ,-115.09960174560547 ,-137.40309143066406 ,-144.7054901123047 ,-123.2982406616211 ,-115.09960174560547 ,-137.40309143066406 ,-115.09960174560547 ,-125.6171646118164 ,-137.40309143066406 ,-125.6171646118164 ,-118.78472900390625 ,-137.40309143066406 ,-118.78472900390625 ,-149.89404296875 ,-115.09960174560547 ,-102.12205505371094 ,-125.6171646118164 ,-125.6171646118164 ,-102.12205505371094 ,-118.78472900390625 ,-115.09960174560547 ,-123.2982406616211 ,-96.9683609008789 ,-115.09960174560547 ,-96.9683609008789 ,-62.83191680908203 ,-115.09960174560547 ,-62.83191680908203 ,-102.12205505371094 ,-129.9468536376953 ,-132.94859313964844 ,-134.471923828125 ,-129.9468536376953 ,-115.61714172363281 ,-132.94859313964844 ,-129.9468536376953 ,-134.471923828125 ,-131.45623779296875 ,-129.9468536376953 ,-131.45623779296875 ,-126.44894409179688 ,-132.94859313964844 ,-134.7921905517578 ,-135.33396911621094 ,-132.94859313964844 ,-135.33396911621094 ,-134.471923828125 ,-120.89374542236328 ,-114.18744659423828 ,-113.3846435546875 ,-120.89374542236328 ,-113.3846435546875 ,-126.44894409179688 ,-126.44894409179688 ,-126.67088317871094 ,-120.89374542236328 ,-126.44894409179688 ,-131.45623779296875 ,-126.67088317871094 ,-114.18744659423828 ,-110.6700439453125 ,-113.3846435546875 ,-114.18744659423828 ,-110.80560302734375 ,-110.6700439453125 ,1359.5948486328125 ,1384.667236328125 ,1464.8760986328125 ,1359.5948486328125 ,1350.0614013671875 ,1384.667236328125 ,1384.667236328125 ,1350.0614013671875 ,1512.47705078125 ,788.2352294921875 ,792.322509765625 ,780.2868041992188 ,788.2352294921875 ,780.2868041992188 ,781.9956665039062 ,788.2352294921875 ,781.9956665039062 ,785.249267578125 ,792.322509765625 ,767.6109008789062 ,780.2868041992188 ,792.322509765625 ,785.7398681640625 ,767.6109008789062 ,780.2868041992188 ,775.3634033203125 ,779.1621704101562 ,780.2868041992188 ,779.1621704101562 ,781.9956665039062 ,780.2868041992188 ,767.6109008789062 ,775.3634033203125 ,785.7398681640625 ,792.322509765625 ,788.6294555664062 ,779.6307373046875 ,779.1621704101562 ,775.3634033203125 ,779.6307373046875 ,776.696533203125 ,773.294677734375 ,779.6307373046875 ,764.2892456054688 ,776.696533203125 ,779.6307373046875 ,775.3634033203125 ,764.2892456054688 ,779.1621704101562 ,779.6307373046875 ,772.681884765625 ,779.1621704101562 ,772.681884765625 ,781.9956665039062 ,775.3634033203125 ,767.6109008789062 ,764.2892456054688 ,808.3765869140625 ,798.1151123046875 ,818.6195068359375 ,808.3765869140625 ,818.6195068359375 ,836.4472045898438 ,808.3765869140625 ,773.4005737304688 ,784.005615234375 ,808.3765869140625 ,784.005615234375 ,798.1151123046875 ,808.3765869140625 ,816.8065795898438 ,773.4005737304688 ,798.1151123046875 ,795.92529296875 ,818.6195068359375 ,798.1151123046875 ,784.005615234375 ,795.92529296875 ,776.2487182617188 ,778.8511962890625 ,781.0104370117188 ,778.8511962890625 ,776.2487182617188 ,766.9347534179688 ,778.8511962890625 ,780.2534790039062 ,781.0104370117188 ,-149.80459594726562 ,-141.76776123046875 ,-140.76263427734375 ,-149.80459594726562 ,-150.2718048095703 ,-141.76776123046875 ,-149.80459594726562 ,-153.2115020751953 ,-150.2718048095703 ,-141.76776123046875 ,-150.2718048095703 ,-141.77560424804688 ,-140.76263427734375 ,-141.76776123046875 ,-140.2793426513672 ,-141.77560424804688 ,-155.69383239746094 ,-146.58180236816406 ,-141.77560424804688 ,-150.2718048095703 ,-155.69383239746094 ,-161.59715270996094 ,-156.4678955078125 ,-160.6448974609375 ,-146.58180236816406 ,-149.55140686035156 ,-144.30014038085938 ,-146.58180236816406 ,-144.30014038085938 ,-141.77560424804688 ,-146.58180236816406 ,-155.69383239746094 ,-149.55140686035156 ,-161.59715270996094 ,-152.16177368164062 ,-156.4678955078125 ,-141.77560424804688 ,-144.30014038085938 ,-141.23570251464844 ,-141.77560424804688 ,-141.23570251464844 ,-139.9047393798828 ,-149.55140686035156 ,-143.6384735107422 ,-144.30014038085938 ,-149.55140686035156 ,-152.16177368164062 ,-140.2585906982422 ,-144.30014038085938 ,-143.6384735107422 ,-141.23570251464844 ,-149.55140686035156 ,-140.2585906982422 ,-143.6384735107422 ,-152.16177368164062 ,-149.55140686035156 ,-156.4678955078125 ,-137.3450927734375 ,-138.72853088378906 ,-143.6384735107422 ,-137.3450927734375 ,-133.25196838378906 ,-131.45623779296875 ,-137.3450927734375 ,-134.471923828125 ,-138.72853088378906 ,-137.3450927734375 ,-131.45623779296875 ,-134.471923828125 ,-138.72853088378906 ,-136.73898315429688 ,-138.8554229736328 ,-138.72853088378906 ,-134.471923828125 ,-136.73898315429688 ,-138.72853088378906 ,-138.8554229736328 ,-141.23570251464844 ,-138.72853088378906 ,-141.23570251464844 ,-143.6384735107422 ,-137.3450927734375 ,-140.2585906982422 ,-133.25196838378906 ,-137.3450927734375 ,-143.6384735107422 ,-140.2585906982422 ,-152.16177368164062 ,-149.89404296875 ,-118.78472900390625 ,-133.25196838378906 ,-126.92286682128906 ,-126.67088317871094 ,-133.25196838378906 ,-126.67088317871094 ,-131.45623779296875 ,-133.25196838378906 ,-118.78472900390625 ,-126.92286682128906 ,-133.25196838378906 ,-140.2585906982422 ,-118.78472900390625 ,-126.92286682128906 ,-120.89374542236328 ,-126.67088317871094 ,-126.92286682128906 ,-118.78472900390625 ,-120.89374542236328 ,-114.18744659423828 ,-115.13775634765625 ,-110.80560302734375 ,-114.18744659423828 ,-120.89374542236328 ,-115.13775634765625 ,-110.80560302734375 ,-108.56073760986328 ,-110.6700439453125 ,1001.5288696289062 ,1146.396484375 ,978.33642578125 ,1001.5288696289062 ,963.122314453125 ,1125.4884033203125 ,1001.5288696289062 ,1125.4884033203125 ,1146.396484375 ,1146.396484375 ,1125.4884033203125 ,1347.417236328125 ,978.33642578125 ,1181.88525390625 ,974.5388793945312 ,978.33642578125 ,974.5388793945312 ,746.8749389648438 ,978.33642578125 ,746.8749389648438 ,1001.5288696289062 ,978.33642578125 ,1146.396484375 ,1181.88525390625 ,974.5388793945312 ,945.4508056640625 ,746.8749389648438 ,839.9677124023438 ,881.2029418945312 ,867.7277221679688 ,839.9677124023438 ,816.025146484375 ,881.3502807617188 ,839.9677124023438 ,881.3502807617188 ,881.2029418945312 ,816.025146484375 ,839.9677124023438 ,781.9956665039062 ,816.025146484375 ,781.9956665039062 ,771.46240234375 ,810.2232055664062 ,810.397705078125 ,826.6268310546875 ,810.2232055664062 ,800.3818359375 ,810.397705078125 ,810.2232055664062 ,795.9059448242188 ,800.3818359375 ,810.2232055664062 ,801.8882446289062 ,795.9059448242188 ,810.2232055664062 ,826.6268310546875 ,799.5333251953125 ,810.2232055664062 ,799.5333251953125 ,801.8882446289062 ,810.397705078125 ,800.3818359375 ,846.9815063476562 ,810.397705078125 ,846.9815063476562 ,826.6268310546875 ,826.6268310546875 ,835.8551025390625 ,799.5333251953125 ,800.3818359375 ,795.9059448242188 ,791.2133178710938 ,799.8658447265625 ,794.6962890625 ,792.6576538085938 ,799.8658447265625 ,814.707275390625 ,794.6962890625 ,799.8658447265625 ,825.8290405273438 ,814.707275390625 ,794.6962890625 ,814.707275390625 ,766.9347534179688 ,794.6962890625 ,773.19140625 ,792.6576538085938 ,794.6962890625 ,766.9347534179688 ,773.19140625 ,814.707275390625 ,825.8290405273438 ,828.5111694335938 ,814.707275390625 ,825.109130859375 ,766.9347534179688 ,814.707275390625 ,828.5111694335938 ,825.109130859375 ,776.2487182617188 ,773.19140625 ,766.9347534179688 ,780.2534790039062 ,778.8511962890625 ,858.2318115234375 ,781.0104370117188 ,780.2534790039062 ,809.3809204101562 ,887.1495361328125 ,870.020751953125 ,876.9880981445312 ,887.1495361328125 ,890.9203491210938 ,894.6041259765625 ,887.1495361328125 ,876.9880981445312 ,890.9203491210938 ,887.1495361328125 ,809.3809204101562 ,870.020751953125 ,887.1495361328125 ,900.3047485351562 ,809.3809204101562 ,887.1495361328125 ,894.6041259765625 ,900.3047485351562 ,870.020751953125 ,858.2318115234375 ,876.9880981445312 ,870.020751953125 ,809.3809204101562 ,858.2318115234375 ,876.9880981445312 ,858.2318115234375 ,887.5587158203125 ,876.9880981445312 ,887.5587158203125 ,890.9203491210938 ,873.7798461914062 ,896.1288452148438 ,848.0089111328125 ,873.7798461914062 ,848.0089111328125 ,874.5257568359375 ,896.1288452148438 ,819.2005615234375 ,848.0089111328125 ,896.1288452148438 ,852.0985717773438 ,819.2005615234375 ,848.0089111328125 ,868.7754516601562 ,874.5257568359375 ,752.8126220703125 ,888.6819458007812 ,749.3441162109375 ,752.8126220703125 ,749.3441162109375 ,746.8749389648438 ,752.8126220703125 ,945.4508056640625 ,888.6819458007812 ,752.8126220703125 ,746.8749389648438 ,945.4508056640625 ,888.6819458007812 ,979.0418090820312 ,874.2781982421875 ,888.6819458007812 ,874.2781982421875 ,735.97314453125 ,888.6819458007812 ,735.97314453125 ,749.3441162109375 ,749.3441162109375 ,856.3151245117188 ,835.4879760742188 ,749.3441162109375 ,735.97314453125 ,856.3151245117188 ,749.3441162109375 ,835.4879760742188 ,746.8749389648438 ,874.2781982421875 ,979.0418090820312 ,1023.9290161132812 ,874.2781982421875 ,773.2101440429688 ,735.97314453125 ,874.2781982421875 ,1023.9290161132812 ,922.0027465820312 ,874.2781982421875 ,922.0027465820312 ,773.2101440429688 ,979.0418090820312 ,1127.7244873046875 ,1023.9290161132812 ,979.0418090820312 ,1017.6915893554688 ,1127.7244873046875 ,979.0418090820312 ,888.6819458007812 ,1017.6915893554688 ,735.97314453125 ,773.2101440429688 ,856.3151245117188 ,1023.9290161132812 ,1014.1249389648438 ,922.0027465820312 ,1023.9290161132812 ,1056.8111572265625 ,1014.1249389648438 ,1023.9290161132812 ,1127.7244873046875 ,1056.8111572265625 ,773.2101440429688 ,827.0269775390625 ,856.3151245117188 ,773.2101440429688 ,858.8248901367188 ,827.0269775390625 ,773.2101440429688 ,818.9485473632812 ,858.8248901367188 ,827.0269775390625 ,894.9439086914062 ,856.3151245117188 ,827.0269775390625 ,858.8248901367188 ,894.9439086914062 ,773.2101440429688 ,922.0027465820312 ,818.9485473632812 ,922.0027465820312 ,1014.1249389648438 ,818.9485473632812 ,1014.1249389648438 ,1002.829345703125 ,973.200927734375 ,1014.1249389648438 ,1056.8111572265625 ,1002.829345703125 ,1014.1249389648438 ,973.200927734375 ,818.9485473632812 ,858.8248901367188 ,818.9485473632812 ,812.9592895507812 ,858.8248901367188 ,889.2929077148438 ,894.9439086914062 ,818.9485473632812 ,795.1342163085938 ,812.9592895507812 ,818.9485473632812 ,894.9827880859375 ,795.1342163085938 ,795.9059448242188 ,815.16357421875 ,792.5941162109375 ,795.9059448242188 ,801.8882446289062 ,815.16357421875 ,795.9059448242188 ,792.5941162109375 ,791.2133178710938 ,791.2133178710938 ,792.5941162109375 ,792.6576538085938 ,792.6576538085938 ,803.7923583984375 ,799.8658447265625 ,792.6576538085938 ,792.5941162109375 ,803.7923583984375 ,803.7923583984375 ,868.508056640625 ,799.8658447265625 ,799.8658447265625 ,868.508056640625 ,825.8290405273438 ,828.5111694335938 ,845.7063598632812 ,825.109130859375 ,828.5111694335938 ,842.575927734375 ,845.7063598632812 ,894.6041259765625 ,890.9203491210938 ,885.3508911132812 ,894.6041259765625 ,891.906494140625 ,900.3047485351562 ,894.6041259765625 ,899.0311279296875 ,891.906494140625 ,894.6041259765625 ,885.3508911132812 ,899.0311279296875 ,890.9203491210938 ,887.5587158203125 ,885.3508911132812 ,-153.8647003173828 ,-126.86888122558594 ,-141.81932067871094 ,-153.8647003173828 ,-125.65872192382812 ,-126.86888122558594 ,-153.8647003173828 ,-141.76710510253906 ,-125.65872192382812 ,-141.81932067871094 ,-126.86888122558594 ,-134.5867919921875 ,-56.9789924621582 ,-178.3269805908203 ,-106.60688781738281 ,-56.9789924621582 ,-106.60688781738281 ,-33.199073791503906 ,-56.9789924621582 ,-141.6046600341797 ,-178.3269805908203 ,-178.3269805908203 ,-141.6046600341797 ,-158.51458740234375 ,-178.3269805908203 ,-159.72174072265625 ,-106.60688781738281 ,-106.84722137451172 ,-106.27518463134766 ,-113.3846435546875 ,-106.84722137451172 ,-108.56073760986328 ,-102.38587188720703 ,-106.84722137451172 ,-102.38587188720703 ,-106.27518463134766 ,-106.84722137451172 ,-113.3846435546875 ,-110.6700439453125 ,-106.84722137451172 ,-110.6700439453125 ,-108.56073760986328 ,-106.27518463134766 ,-102.38587188720703 ,-102.3046875 ,-106.27518463134766 ,-102.3046875 ,-103.09947967529297 ,-106.27518463134766 ,-103.09947967529297 ,-109.99552917480469 ,-106.27518463134766 ,-109.99552917480469 ,-113.3846435546875 ,-103.09947967529297 ,-102.16619873046875 ,-98.61194610595703 ,-126.86888122558594 ,-134.8258514404297 ,-134.5867919921875 ,-126.86888122558594 ,-125.65872192382812 ,-134.8258514404297 ,-134.5867919921875 ,-134.8258514404297 ,-143.6565399169922 ,-134.5867919921875 ,-141.90310668945312 ,-141.81932067871094 ,-134.5867919921875 ,-143.6565399169922 ,-148.56201171875 ,-134.5867919921875 ,-148.56201171875 ,-141.90310668945312 ,-141.81932067871094 ,-141.6046600341797 ,-56.9789924621582 ,-141.81932067871094 ,-141.90310668945312 ,-141.6046600341797 ,-141.90310668945312 ,-148.56201171875 ,-141.6046600341797 ,-141.6046600341797 ,-148.56201171875 ,-158.51458740234375 ,-178.3269805908203 ,-158.51458740234375 ,-157.3513946533203 ,-178.3269805908203 ,-157.3513946533203 ,-159.72174072265625 ,-102.38587188720703 ,-108.56073760986328 ,-104.18303680419922 ,-108.56073760986328 ,-110.80560302734375 ,-104.18303680419922 ,-102.38587188720703 ,-100.93913269042969 ,-102.3046875 ,-102.3046875 ,-102.16619873046875 ,-103.09947967529297 ,-102.3046875 ,-98.2369613647461 ,-102.16619873046875 ,-102.3046875 ,-100.93913269042969 ,-99.1752700805664 ,-102.3046875 ,-99.1752700805664 ,-98.2369613647461 ,-103.09947967529297 ,-109.3658218383789 ,-109.99552917480469 ,-98.61194610595703 ,-102.16619873046875 ,-98.2369613647461 ,-103.09947967529297 ,-98.61194610595703 ,-101.66226959228516 ,-134.8258514404297 ,-125.65872192382812 ,-123.67655181884766 ,-134.8258514404297 ,-123.67655181884766 ,-119.85173034667969 ,-125.65872192382812 ,-122.0211410522461 ,-123.67655181884766 ,-125.65872192382812 ,-141.76710510253906 ,-122.0211410522461 ,-134.8258514404297 ,-139.55381774902344 ,-143.6565399169922 ,-134.8258514404297 ,-133.02630615234375 ,-139.55381774902344 ,-143.6565399169922 ,-139.55381774902344 ,-152.6786346435547 ,-143.6565399169922 ,-152.6786346435547 ,-148.56201171875 ,-148.56201171875 ,-152.6786346435547 ,-158.51458740234375 ,-158.51458740234375 ,-152.6786346435547 ,-155.8262939453125 ,-158.51458740234375 ,-155.8262939453125 ,-157.3513946533203 ,-157.3513946533203 ,-155.8262939453125 ,-155.9889678955078 ,-157.3513946533203 ,-155.9889678955078 ,-159.72174072265625 ,-159.72174072265625 ,-155.9889678955078 ,-174.0264892578125 ,-158.2633514404297 ,-157.1273193359375 ,-156.88607788085938 ,-158.2633514404297 ,-163.55294799804688 ,-157.1273193359375 ,-158.2633514404297 ,-156.88607788085938 ,-145.12283325195312 ,-158.2633514404297 ,-153.1248779296875 ,-163.55294799804688 ,-163.55294799804688 ,-158.48971557617188 ,-166.1304168701172 ,-163.55294799804688 ,-153.1248779296875 ,-158.48971557617188 ,-158.2633514404297 ,-145.12283325195312 ,-153.1248779296875 ,-153.1248779296875 ,-145.12283325195312 ,-142.57838439941406 ,-153.1248779296875 ,-142.57838439941406 ,-158.48971557617188 ,-100.93913269042969 ,-102.38587188720703 ,-99.1752700805664 ,-98.2369613647461 ,-99.1752700805664 ,-97.44277954101562 ,-98.2369613647461 ,-95.26194763183594 ,-93.75887298583984 ,-98.2369613647461 ,-93.75887298583984 ,-98.61194610595703 ,-98.61194610595703 ,-93.75887298583984 ,-101.66226959228516 ,-97.59538269042969 ,-123.67655181884766 ,-115.22801971435547 ,-97.59538269042969 ,-106.22950744628906 ,-123.67655181884766 ,-97.59538269042969 ,-115.22801971435547 ,-103.65386962890625 ,-123.67655181884766 ,-122.0211410522461 ,-115.22801971435547 ,-123.67655181884766 ,-106.22950744628906 ,-119.85173034667969 ,-122.0211410522461 ,-141.76710510253906 ,-115.22801971435547 ,-119.85173034667969 ,-109.67659759521484 ,-116.0752944946289 ,-119.85173034667969 ,-106.22950744628906 ,-109.67659759521484 ,-119.85173034667969 ,-116.0752944946289 ,-133.02630615234375 ,-119.85173034667969 ,-133.02630615234375 ,-134.8258514404297 ,-139.55381774902344 ,-138.4840850830078 ,-152.6786346435547 ,-139.55381774902344 ,-132.5778350830078 ,-138.4840850830078 ,-139.55381774902344 ,-133.02630615234375 ,-132.5778350830078 ,-152.6786346435547 ,-138.4840850830078 ,-143.77261352539062 ,-152.6786346435547 ,-143.77261352539062 ,-153.3959197998047 ,-152.6786346435547 ,-153.3959197998047 ,-155.8262939453125 ,-155.8262939453125 ,-153.3959197998047 ,-153.1425323486328 ,-156.88607788085938 ,-157.1273193359375 ,-155.9889678955078 ,-156.88607788085938 ,-155.9889678955078 ,-155.8262939453125 ,-156.88607788085938 ,-153.1425323486328 ,-152.23672485351562 ,-156.88607788085938 ,-155.8262939453125 ,-153.1425323486328 ,-157.1273193359375 ,-163.55294799804688 ,-174.0264892578125 ,-157.1273193359375 ,-174.0264892578125 ,-155.9889678955078 ,-156.88607788085938 ,-152.23672485351562 ,-149.2755126953125 ,-156.88607788085938 ,-149.2755126953125 ,-145.12283325195312 ,-99.1752700805664 ,-96.71883392333984 ,-97.44277954101562 ,-97.44277954101562 ,-95.26194763183594 ,-98.2369613647461 ,-94.73629760742188 ,-91.68816375732422 ,-97.59538269042969 ,-94.73629760742188 ,-90.65093231201172 ,-91.68816375732422 ,-97.59538269042969 ,-91.68816375732422 ,-95.26612854003906 ,-97.59538269042969 ,-103.65386962890625 ,-94.73629760742188 ,-97.59538269042969 ,-95.26612854003906 ,-106.22950744628906 ,-106.22950744628906 ,-95.26612854003906 ,-109.67659759521484 ,-116.0752944946289 ,-109.67659759521484 ,-105.48239135742188 ,-116.0752944946289 ,-105.48239135742188 ,-119.74090576171875 ,-116.0752944946289 ,-119.74090576171875 ,-132.5778350830078 ,-116.0752944946289 ,-132.5778350830078 ,-133.02630615234375 ,-138.4840850830078 ,-133.3418731689453 ,-143.77261352539062 ,-138.4840850830078 ,-132.5778350830078 ,-133.3418731689453 ,-143.77261352539062 ,-133.3418731689453 ,-145.09791564941406 ,-143.77261352539062 ,-145.09791564941406 ,-153.3959197998047 ,-153.3959197998047 ,-145.09791564941406 ,-149.7155303955078 ,-153.3959197998047 ,-149.7155303955078 ,-148.2396697998047 ,-153.3959197998047 ,-148.2396697998047 ,-153.1425323486328 ,-152.23672485351562 ,-144.7930145263672 ,-149.2755126953125 ,-152.23672485351562 ,-148.2396697998047 ,-144.7930145263672 ,-152.23672485351562 ,-153.1425323486328 ,-148.2396697998047 ,-149.2755126953125 ,-144.7930145263672 ,-143.49606323242188 ,-149.2755126953125 ,-140.21238708496094 ,-145.12283325195312 ,-96.71883392333984 ,-99.1752700805664 ,-102.38587188720703 ,-96.71883392333984 ,-93.51314544677734 ,-97.44277954101562 ,-96.71883392333984 ,-92.32088470458984 ,-93.51314544677734 ,-95.26194763183594 ,-87.01240539550781 ,-93.75887298583984 ,-85.38648986816406 ,-86.18479919433594 ,-85.63018035888672 ,-85.38648986816406 ,-84.56776428222656 ,-86.18479919433594 ,-85.38648986816406 ,-85.63018035888672 ,-89.28755950927734 ,-85.63018035888672 ,-87.42422485351562 ,-89.28755950927734 ,-86.18479919433594 ,-87.75070190429688 ,-86.91287994384766 ,-86.18479919433594 ,-84.56776428222656 ,-87.75070190429688 ,-86.18479919433594 ,-86.91287994384766 ,-85.63018035888672 ,-87.75070190429688 ,-84.56776428222656 ,-90.6207275390625 ,-86.91287994384766 ,-86.76862335205078 ,-85.63018035888672 ,-86.91287994384766 ,-90.04814910888672 ,-86.76862335205078 ,-91.68816375732422 ,-93.7254867553711 ,-93.45565032958984 ,-91.68816375732422 ,-93.45565032958984 ,-95.26612854003906 ,-95.26612854003906 ,-93.45565032958984 ,-94.79926300048828 ,-95.26612854003906 ,-94.79926300048828 ,-109.67659759521484 ,-109.67659759521484 ,-94.79926300048828 ,-105.48239135742188 ,-105.48239135742188 ,-94.88229370117188 ,-100.07647705078125 ,-105.48239135742188 ,-94.79926300048828 ,-94.88229370117188 ,-105.48239135742188 ,-100.07647705078125 ,-112.67081451416016 ,-105.48239135742188 ,-112.67081451416016 ,-119.74090576171875 ,-119.74090576171875 ,-112.67081451416016 ,-133.3418731689453 ,-119.74090576171875 ,-133.3418731689453 ,-132.5778350830078 ,-133.3418731689453 ,-132.75430297851562 ,-145.09791564941406 ,-133.3418731689453 ,-112.67081451416016 ,-132.75430297851562 ,-145.09791564941406 ,-132.75430297851562 ,-139.8619842529297 ,-145.09791564941406 ,-139.8619842529297 ,-149.7155303955078 ,-149.7155303955078 ,-139.8619842529297 ,-139.96591186523438 ,-149.7155303955078 ,-139.96591186523438 ,-148.2396697998047 ,-144.7930145263672 ,-135.4174346923828 ,-143.49606323242188 ,-144.7930145263672 ,-136.0892333984375 ,-135.4174346923828 ,-144.7930145263672 ,-148.2396697998047 ,-136.0892333984375 ,-143.49606323242188 ,-135.4174346923828 ,-140.21238708496094 ,-143.49606323242188 ,-140.21238708496094 ,-149.2755126953125 ,-93.51314544677734 ,-92.32088470458984 ,-90.53404235839844 ,-90.37690734863281 ,-97.44277954101562 ,-93.51314544677734 ,-90.37690734863281 ,-93.51314544677734 ,-90.53404235839844 ,-87.01240539550781 ,-84.56776428222656 ,-85.38648986816406 ,-87.01240539550781 ,-83.4723129272461 ,-84.56776428222656 ,-85.38648986816406 ,-89.28755950927734 ,-87.01240539550781 ,-87.01240539550781 ,-89.28755950927734 ,-93.75887298583984 ,-84.56776428222656 ,-83.4723129272461 ,-83.28272247314453 ,-84.56776428222656 ,-83.28272247314453 ,-84.9426040649414 ,-84.56776428222656 ,-84.9426040649414 ,-86.72351837158203 ,-84.56776428222656 ,-86.72351837158203 ,-90.6207275390625 ,-87.75070190429688 ,-90.6207275390625 ,-91.68816375732422 ,-87.75070190429688 ,-91.68816375732422 ,-90.65093231201172 ,-87.75070190429688 ,-90.65093231201172 ,-86.91287994384766 ,-90.6207275390625 ,-86.72351837158203 ,-91.98957824707031 ,-90.6207275390625 ,-91.98957824707031 ,-93.7254867553711 ,-90.6207275390625 ,-93.7254867553711 ,-91.68816375732422 ,-93.7254867553711 ,-91.69267272949219 ,-93.45565032958984 ,-93.7254867553711 ,-93.24769592285156 ,-91.69267272949219 ,-93.45565032958984 ,-91.69267272949219 ,-94.79926300048828 ,-94.79926300048828 ,-91.69267272949219 ,-94.88229370117188 ,-100.07647705078125 ,-91.13378143310547 ,-112.67081451416016 ,-100.07647705078125 ,-94.88229370117188 ,-91.13378143310547 ,-112.67081451416016 ,-91.13378143310547 ,-107.97970581054688 ,-132.75430297851562 ,-107.97970581054688 ,-115.40184020996094 ,-132.75430297851562 ,-112.67081451416016 ,-107.97970581054688 ,-132.75430297851562 ,-115.40184020996094 ,-122.41194152832031 ,-132.75430297851562 ,-122.41194152832031 ,-139.8619842529297 ,-139.8619842529297 ,-122.41194152832031 ,-129.6157989501953 ,-139.8619842529297 ,-129.6157989501953 ,-139.96591186523438 ,-139.96591186523438 ,-129.6157989501953 ,-126.85875701904297 ,-139.96591186523438 ,-126.85875701904297 ,-136.0892333984375 ,-139.96591186523438 ,-136.0892333984375 ,-148.2396697998047 ,-135.4174346923828 ,-125.73169708251953 ,-129.81137084960938 ,-135.4174346923828 ,-136.0892333984375 ,-125.73169708251953 ,-135.4174346923828 ,-129.81137084960938 ,-140.21238708496094 ,-83.4723129272461 ,-81.9102554321289 ,-83.28272247314453 ,-83.28272247314453 ,-81.9102554321289 ,-84.9426040649414 ,-84.9426040649414 ,-81.9102554321289 ,-86.72351837158203 ,-86.72351837158203 ,-81.9102554321289 ,-90.42567443847656 ,-86.72351837158203 ,-90.42567443847656 ,-91.98957824707031 ,-91.98957824707031 ,-90.42567443847656 ,-93.24769592285156 ,-91.98957824707031 ,-93.24769592285156 ,-93.7254867553711 ,-91.69267272949219 ,-93.24769592285156 ,-92.181640625 ,-91.69267272949219 ,-92.181640625 ,-87.67280578613281 ,-91.69267272949219 ,-87.67280578613281 ,-94.88229370117188 ,-94.88229370117188 ,-87.67280578613281 ,-91.13378143310547 ,-91.13378143310547 ,-87.67280578613281 ,-79.22007751464844 ,-91.13378143310547 ,-79.22007751464844 ,-85.71516418457031 ,-91.13378143310547 ,-85.71516418457031 ,-107.97970581054688 ,-107.97970581054688 ,-85.71516418457031 ,-96.38621520996094 ,-115.40184020996094 ,-111.41121673583984 ,-122.41194152832031 ,-115.40184020996094 ,-96.38621520996094 ,-111.41121673583984 ,-115.40184020996094 ,-107.97970581054688 ,-96.38621520996094 ,-122.41194152832031 ,-111.41121673583984 ,-129.6157989501953 ,-129.6157989501953 ,-111.41121673583984 ,-112.71226501464844 ,-129.6157989501953 ,-112.71226501464844 ,-126.85875701904297 ,-126.85875701904297 ,-112.71226501464844 ,-114.71903991699219 ,-126.85875701904297 ,-114.71903991699219 ,-125.73169708251953 ,-126.85875701904297 ,-125.73169708251953 ,-136.0892333984375 ,-129.81137084960938 ,-125.73169708251953 ,-121.1949462890625 ,-129.81137084960938 ,-121.1949462890625 ,-122.27922821044922 ,-140.21238708496094 ,-129.81137084960938 ,-126.61785888671875 ,-120.02518463134766 ,-96.33409881591797 ,-97.66888427734375 ,-120.02518463134766 ,-97.66888427734375 ,-110.61604309082031 ,-81.23848724365234 ,-84.9164047241211 ,-90.37690734863281 ,-81.23848724365234 ,-78.29945373535156 ,-77.36997985839844 ,-81.23848724365234 ,-90.37690734863281 ,-78.29945373535156 ,-84.9164047241211 ,-95.26194763183594 ,-97.44277954101562 ,-84.9164047241211 ,-97.44277954101562 ,-90.37690734863281 ,-81.9102554321289 ,-79.91511535644531 ,-81.42041778564453 ,-81.9102554321289 ,-81.42041778564453 ,-83.84855651855469 ,-81.9102554321289 ,-83.84855651855469 ,-90.42567443847656 ,-90.42567443847656 ,-83.84855651855469 ,-92.06124114990234 ,-90.42567443847656 ,-92.06124114990234 ,-92.181640625 ,-90.42567443847656 ,-92.181640625 ,-93.24769592285156 ,-92.181640625 ,-92.06124114990234 ,-89.97572326660156 ,-92.181640625 ,-89.97572326660156 ,-87.67280578613281 ,-87.67280578613281 ,-89.97572326660156 ,-79.22007751464844 ,-79.22007751464844 ,-68.94243621826172 ,-85.71516418457031 ,-85.71516418457031 ,-68.94243621826172 ,-73.03630065917969 ,-85.71516418457031 ,-73.03630065917969 ,-96.38621520996094 ,-96.38621520996094 ,-73.03630065917969 ,-83.12718200683594 ,-111.41121673583984 ,-83.12718200683594 ,-87.04235076904297 ,-111.41121673583984 ,-96.38621520996094 ,-83.12718200683594 ,-111.41121673583984 ,-87.04235076904297 ,-94.39046478271484 ,-111.41121673583984 ,-94.39046478271484 ,-112.71226501464844 ,-112.71226501464844 ,-94.39046478271484 ,-99.29127502441406 ,-112.71226501464844 ,-99.29127502441406 ,-114.71903991699219 ,-114.71903991699219 ,-99.29127502441406 ,-106.61231994628906 ,-114.71903991699219 ,-106.61231994628906 ,-121.1949462890625 ,-114.71903991699219 ,-121.1949462890625 ,-125.73169708251953 ,-121.1949462890625 ,-94.82251739501953 ,-122.27922821044922 ,-121.1949462890625 ,-106.61231994628906 ,-94.82251739501953 ,-122.27922821044922 ,-94.82251739501953 ,-126.61785888671875 ,-122.27922821044922 ,-126.61785888671875 ,-129.81137084960938 ,-126.61785888671875 ,-94.82251739501953 ,-80.566162109375 ,-126.61785888671875 ,-96.33409881591797 ,-120.02518463134766 ,-126.61785888671875 ,-80.566162109375 ,-96.33409881591797 ,-96.33409881591797 ,-80.566162109375 ,-68.3465347290039 ,-96.33409881591797 ,-68.3465347290039 ,-97.66888427734375 ,-120.02518463134766 ,-137.97515869140625 ,-126.61785888671875 ,-97.66888427734375 ,-68.3465347290039 ,-56.8443603515625 ,-97.66888427734375 ,-56.8443603515625 ,-92.81271362304688 ,-78.29945373535156 ,-70.33815002441406 ,-77.36997985839844 ,-77.36997985839844 ,-70.33815002441406 ,-77.83845520019531 ,-77.36997985839844 ,-77.83845520019531 ,-79.01948547363281 ,-77.36997985839844 ,-79.01948547363281 ,-81.23848724365234 ,-81.23848724365234 ,-79.01948547363281 ,-81.50568389892578 ,-81.23848724365234 ,-81.50568389892578 ,-84.9164047241211 ,-79.91511535644531 ,-81.9102554321289 ,-81.50568389892578 ,-79.91511535644531 ,-81.50568389892578 ,-79.01948547363281 ,-79.91511535644531 ,-79.01948547363281 ,-77.83845520019531 ,-81.9102554321289 ,-83.4723129272461 ,-81.50568389892578 ,-81.50568389892578 ,-83.4723129272461 ,-84.9164047241211 ,-79.91511535644531 ,-77.78589630126953 ,-81.42041778564453 ,-81.42041778564453 ,-77.78589630126953 ,-81.4166488647461 ,-81.42041778564453 ,-81.4166488647461 ,-83.84855651855469 ,-83.84855651855469 ,-81.4166488647461 ,-87.15206146240234 ,-83.84855651855469 ,-87.15206146240234 ,-92.06124114990234 ,-89.97572326660156 ,-87.15206146240234 ,-81.43994903564453 ,-89.97572326660156 ,-92.06124114990234 ,-87.15206146240234 ,-89.97572326660156 ,-81.43994903564453 ,-79.22007751464844 ,-79.22007751464844 ,-81.43994903564453 ,-68.94243621826172 ,-68.94243621826172 ,-81.43994903564453 ,-69.30514526367188 ,-68.94243621826172 ,-69.30514526367188 ,-60.12433624267578 ,-68.94243621826172 ,-60.12433624267578 ,-73.03630065917969 ,-73.03630065917969 ,-60.12433624267578 ,-65.90319061279297 ,-73.03630065917969 ,-65.90319061279297 ,-83.12718200683594 ,-87.04235076904297 ,-65.90319061279297 ,-72.32738494873047 ,-87.04235076904297 ,-83.12718200683594 ,-65.90319061279297 ,-87.04235076904297 ,-72.32738494873047 ,-94.39046478271484 ,-94.39046478271484 ,-72.32738494873047 ,-79.54258728027344 ,-94.39046478271484 ,-79.54258728027344 ,-99.29127502441406 ,-99.29127502441406 ,-79.54258728027344 ,-88.9444351196289 ,-99.29127502441406 ,-88.9444351196289 ,-106.61231994628906 ,-106.61231994628906 ,-88.9444351196289 ,-99.28434753417969 ,-94.82251739501953 ,-72.6328353881836 ,-80.566162109375 ,-80.566162109375 ,-72.6328353881836 ,-56.925743103027344 ,-80.566162109375 ,-56.925743103027344 ,-68.3465347290039 ,-68.3465347290039 ,-56.925743103027344 ,-56.8443603515625 ,-78.29945373535156 ,-70.5509262084961 ,-70.33815002441406 ,-78.29945373535156 ,-86.68527221679688 ,-70.5509262084961 ,-70.33815002441406 ,-58.645137786865234 ,-65.74654388427734 ,-70.33815002441406 ,-65.74654388427734 ,-77.83845520019531 ,-70.33815002441406 ,-70.5509262084961 ,-58.645137786865234 ,-77.83845520019531 ,-77.0380859375 ,-77.78589630126953 ,-77.83845520019531 ,-77.78589630126953 ,-79.91511535644531 ,-77.78589630126953 ,-76.242919921875 ,-74.4120864868164 ,-77.78589630126953 ,-74.4120864868164 ,-81.4166488647461 ,-81.4166488647461 ,-74.4120864868164 ,-75.67717742919922 ,-81.4166488647461 ,-75.67717742919922 ,-87.15206146240234 ,-87.15206146240234 ,-75.67717742919922 ,-79.80250549316406 ,-81.43994903564453 ,-87.15206146240234 ,-79.92711639404297 ,-81.43994903564453 ,-79.92711639404297 ,-69.30514526367188 ,-69.30514526367188 ,-57.89311599731445 ,-60.12433624267578 ,-60.12433624267578 ,-57.89311599731445 ,-53.890235900878906 ,-60.12433624267578 ,-53.890235900878906 ,-65.90319061279297 ,-65.90319061279297 ,-53.890235900878906 ,-55.82514953613281 ,-72.32738494873047 ,-65.90319061279297 ,-57.94358825683594 ,-72.32738494873047 ,-57.94358825683594 ,-65.2627182006836 ,-72.32738494873047 ,-65.2627182006836 ,-79.54258728027344 ,-79.54258728027344 ,-65.2627182006836 ,-77.3141098022461 ,-79.54258728027344 ,-77.3141098022461 ,-88.9444351196289 ,-88.9444351196289 ,-77.3141098022461 ,-87.57783508300781 ,-88.9444351196289 ,-87.57783508300781 ,-99.28434753417969 ,-99.28434753417969 ,-87.57783508300781 ,-94.82251739501953 ,-99.28434753417969 ,-94.82251739501953 ,-106.61231994628906 ,-94.82251739501953 ,-78.99258422851562 ,-56.15263366699219 ,-94.82251739501953 ,-56.15263366699219 ,-72.6328353881836 ,-72.6328353881836 ,-56.15263366699219 ,-48.157745361328125 ,-72.6328353881836 ,-48.157745361328125 ,-43.429832458496094 ,-72.6328353881836 ,-43.429832458496094 ,-56.925743103027344 ,-56.925743103027344 ,-43.429832458496094 ,-40.58008575439453 ,-56.925743103027344 ,-40.58008575439453 ,-56.8443603515625 ,-58.645137786865234 ,-70.5509262084961 ,-56.35728454589844 ,-58.645137786865234 ,-56.35728454589844 ,-68.80435180664062 ,-58.645137786865234 ,-68.80435180664062 ,-65.74654388427734 ,-65.74654388427734 ,-68.80435180664062 ,-77.0380859375 ,-65.74654388427734 ,-77.0380859375 ,-77.83845520019531 ,-77.0380859375 ,-68.80435180664062 ,-76.242919921875 ,-77.0380859375 ,-76.242919921875 ,-77.78589630126953 ,-74.4120864868164 ,-71.69428253173828 ,-67.0969009399414 ,-74.4120864868164 ,-76.242919921875 ,-71.69428253173828 ,-74.4120864868164 ,-67.0969009399414 ,-75.67717742919922 ,-75.67717742919922 ,-67.0969009399414 ,-63.71357727050781 ,-75.67717742919922 ,-63.71357727050781 ,-64.62432861328125 ,-75.67717742919922 ,-64.62432861328125 ,-79.80250549316406 ,-79.80250549316406 ,-64.62432861328125 ,-66.99131774902344 ,-79.80250549316406 ,-66.99131774902344 ,-79.92711639404297 ,-79.80250549316406 ,-79.92711639404297 ,-87.15206146240234 ,-79.92711639404297 ,-66.99131774902344 ,-69.30514526367188 ,-69.30514526367188 ,-66.99131774902344 ,-57.89311599731445 ,-57.89311599731445 ,-52.7409782409668 ,-56.23590087890625 ,-57.89311599731445 ,-66.99131774902344 ,-52.7409782409668 ,-57.89311599731445 ,-56.23590087890625 ,-56.03821563720703 ,-57.89311599731445 ,-56.03821563720703 ,-53.890235900878906 ,-53.890235900878906 ,-56.03821563720703 ,-53.030174255371094 ,-53.890235900878906 ,-53.030174255371094 ,-55.82514953613281 ,-55.82514953613281 ,-53.030174255371094 ,-54.61420822143555 ,-55.82514953613281 ,-54.61420822143555 ,-57.94358825683594 ,-55.82514953613281 ,-57.94358825683594 ,-65.90319061279297 ,-57.94358825683594 ,-54.61420822143555 ,-65.2627182006836 ,-65.2627182006836 ,-54.61420822143555 ,-68.67185974121094 ,-65.2627182006836 ,-68.67185974121094 ,-77.3141098022461 ,-77.3141098022461 ,-68.67185974121094 ,-87.57783508300781 ,-87.57783508300781 ,-68.67185974121094 ,-72.34418487548828 ,-87.57783508300781 ,-72.34418487548828 ,-78.99258422851562 ,-87.57783508300781 ,-78.99258422851562 ,-94.82251739501953 ,-56.15263366699219 ,-52.57469177246094 ,-43.0850830078125 ,-56.15263366699219 ,-78.99258422851562 ,-52.57469177246094 ,-56.15263366699219 ,-43.0850830078125 ,-35.77240753173828 ,-56.15263366699219 ,-35.77240753173828 ,-48.157745361328125 ,-48.157745361328125 ,-35.77240753173828 ,-43.429832458496094 ,-43.429832458496094 ,-35.77240753173828 ,-35.76103973388672 ,-43.429832458496094 ,-35.76103973388672 ,-40.58008575439453 ,-58.127685546875 ,-68.52424621582031 ,-65.2342300415039 ,-58.127685546875 ,-65.2342300415039 ,-58.43694305419922 ,-58.127685546875 ,-64.88554382324219 ,-68.52424621582031 ,-68.52424621582031 ,-64.88554382324219 ,-74.24273681640625 ,-56.35728454589844 ,-51.92376708984375 ,-38.45083236694336 ,-56.35728454589844 ,-38.45083236694336 ,-68.80435180664062 ,-68.80435180664062 ,-38.45083236694336 ,-49.919212341308594 ,-68.80435180664062 ,-49.919212341308594 ,-64.96870422363281 ,-68.80435180664062 ,-64.96870422363281 ,-71.69428253173828 ,-68.80435180664062 ,-71.69428253173828 ,-76.242919921875 ,-67.0969009399414 ,-64.29334259033203 ,-56.296722412109375 ,-67.0969009399414 ,-71.69428253173828 ,-64.29334259033203 ,-67.0969009399414 ,-56.296722412109375 ,-63.71357727050781 ,-63.71357727050781 ,-56.296722412109375 ,-46.73856735229492 ,-63.71357727050781 ,-46.73856735229492 ,-64.62432861328125 ,-64.62432861328125 ,-46.73856735229492 ,-46.87852096557617 ,-64.62432861328125 ,-46.87852096557617 ,-66.99131774902344 ,-66.99131774902344 ,-46.87852096557617 ,-48.328758239746094 ,-66.99131774902344 ,-48.328758239746094 ,-52.7409782409668 ,-56.23590087890625 ,-51.37636184692383 ,-56.03821563720703 ,-56.23590087890625 ,-52.7409782409668 ,-51.37636184692383 ,-56.03821563720703 ,-51.37636184692383 ,-57.73455810546875 ,-56.03821563720703 ,-57.73455810546875 ,-53.030174255371094 ,-53.030174255371094 ,-57.73455810546875 ,-57.43354034423828 ,-53.030174255371094 ,-57.43354034423828 ,-54.61420822143555 ,-54.61420822143555 ,-57.43354034423828 ,-60.55412292480469 ,-54.61420822143555 ,-60.55412292480469 ,-68.67185974121094 ,-68.67185974121094 ,-60.55412292480469 ,-66.08497619628906 ,-68.67185974121094 ,-66.08497619628906 ,-59.98164367675781 ,-68.67185974121094 ,-59.98164367675781 ,-72.34418487548828 ,-72.34418487548828 ,-59.98164367675781 ,-41.20072937011719 ,-72.34418487548828 ,-41.20072937011719 ,-52.57469177246094 ,-72.34418487548828 ,-52.57469177246094 ,-78.99258422851562 ,-43.0850830078125 ,-30.437400817871094 ,-35.77240753173828 ,-43.0850830078125 ,-41.20072937011719 ,-30.437400817871094 ,-43.0850830078125 ,-52.57469177246094 ,-41.20072937011719 ,-35.77240753173828 ,-30.437400817871094 ,-35.76103973388672 ,-35.76103973388672 ,-30.437400817871094 ,-31.25475311279297 ,-35.76103973388672 ,-31.25475311279297 ,-40.58008575439453 ,-40.58008575439453 ,-31.25475311279297 ,-34.880271911621094 ,-40.58008575439453 ,-34.880271911621094 ,-39.263126373291016 ,-39.263126373291016 ,-43.8705940246582 ,-40.58008575439453 ,-39.263126373291016 ,-34.880271911621094 ,-38.70508575439453 ,-39.263126373291016 ,-49.75644302368164 ,-43.8705940246582 ,-43.8705940246582 ,-49.75644302368164 ,-56.8443603515625 ,-43.8705940246582 ,-56.8443603515625 ,-40.58008575439453 ,-51.92376708984375 ,-48.8593635559082 ,-31.77848243713379 ,-51.92376708984375 ,-56.35728454589844 ,-64.88554382324219 ,-51.92376708984375 ,-31.77848243713379 ,-38.45083236694336 ,-64.88554382324219 ,-56.35728454589844 ,-74.24273681640625 ,-56.35728454589844 ,-70.5509262084961 ,-74.24273681640625 ,-38.45083236694336 ,-31.77848243713379 ,-25.558605194091797 ,-38.45083236694336 ,-25.558605194091797 ,-49.919212341308594 ,-49.919212341308594 ,-25.558605194091797 ,-44.045379638671875 ,-49.919212341308594 ,-44.045379638671875 ,-64.96870422363281 ,-64.96870422363281 ,-48.88777542114258 ,-64.29334259033203 ,-64.96870422363281 ,-40.22665023803711 ,-48.88777542114258 ,-64.96870422363281 ,-64.29334259033203 ,-71.69428253173828 ,-56.296722412109375 ,-50.09689712524414 ,-46.299007415771484 ,-56.296722412109375 ,-64.29334259033203 ,-50.09689712524414 ,-56.296722412109375 ,-46.299007415771484 ,-40.60354232788086 ,-56.296722412109375 ,-40.60354232788086 ,-35.15899658203125 ,-56.296722412109375 ,-35.15899658203125 ,-46.73856735229492 ,-46.73856735229492 ,-35.15899658203125 ,-29.13590431213379 ,-46.73856735229492 ,-29.13590431213379 ,-23.751272201538086 ,-46.73856735229492 ,-23.751272201538086 ,-46.87852096557617 ,-46.87852096557617 ,-23.751272201538086 ,-19.800701141357422 ,-46.87852096557617 ,-19.800701141357422 ,-48.328758239746094 ,-48.328758239746094 ,-19.800701141357422 ,-15.813745498657227 ,-52.7409782409668 ,-48.328758239746094 ,-32.43184280395508 ,-52.7409782409668 ,-32.43184280395508 ,-51.37636184692383 ,-51.37636184692383 ,-13.02388858795166 ,-33.783992767333984 ,-51.37636184692383 ,-32.43184280395508 ,-13.02388858795166 ,-51.37636184692383 ,-33.783992767333984 ,-57.73455810546875 ,-57.73455810546875 ,-33.783992767333984 ,-50.42792510986328 ,-57.73455810546875 ,-50.42792510986328 ,-57.43354034423828 ,-57.43354034423828 ,-50.42792510986328 ,-59.846065521240234 ,-57.43354034423828 ,-59.846065521240234 ,-60.348907470703125 ,-57.43354034423828 ,-60.348907470703125 ,-60.55412292480469 ,-60.55412292480469 ,-60.348907470703125 ,-59.337890625 ,-60.55412292480469 ,-59.337890625 ,-66.08497619628906 ,-66.08497619628906 ,-59.337890625 ,-50.48353576660156 ,-66.08497619628906 ,-50.48353576660156 ,-59.98164367675781 ,-59.98164367675781 ,-50.48353576660156 ,-33.086769104003906 ,-59.98164367675781 ,-33.086769104003906 ,-41.20072937011719 ,-30.437400817871094 ,-26.16839599609375 ,-26.78887176513672 ,-30.437400817871094 ,-41.20072937011719 ,-26.16839599609375 ,-30.437400817871094 ,-26.78887176513672 ,-28.229341506958008 ,-30.437400817871094 ,-28.229341506958008 ,-31.25475311279297 ,-31.25475311279297 ,-28.229341506958008 ,-30.56441307067871 ,-31.25475311279297 ,-30.56441307067871 ,-34.880271911621094 ,-34.880271911621094 ,-30.56441307067871 ,-32.77574157714844 ,-34.880271911621094 ,-32.77574157714844 ,-38.70508575439453 ,-31.77848243713379 ,-48.8593635559082 ,-31.51075553894043 ,-31.77848243713379 ,-31.51075553894043 ,-25.558605194091797 ,-25.558605194091797 ,-1.28290855884552 ,-44.045379638671875 ,-44.045379638671875 ,-1.28290855884552 ,-8.705370903015137 ,-44.045379638671875 ,-8.705370903015137 ,-25.795822143554688 ,-44.045379638671875 ,-25.795822143554688 ,-40.22665023803711 ,-44.045379638671875 ,-40.22665023803711 ,-64.96870422363281 ,-48.88777542114258 ,-50.09689712524414 ,-64.29334259033203 ,-15.813745498657227 ,-12.762040138244629 ,-32.43184280395508 ,-15.813745498657227 ,-32.43184280395508 ,-48.328758239746094 ,-33.783992767333984 ,-13.471426010131836 ,-16.721044540405273 ,-33.783992767333984 ,-13.02388858795166 ,-13.471426010131836 ,-33.783992767333984 ,-16.721044540405273 ,-32.605865478515625 ,-33.783992767333984 ,-32.605865478515625 ,-50.42792510986328 ,-50.42792510986328 ,-32.605865478515625 ,-49.1010627746582 ,-50.42792510986328 ,-49.1010627746582 ,-59.846065521240234 ,-59.846065521240234 ,-49.1010627746582 ,-55.91640853881836 ,-59.846065521240234 ,-55.91640853881836 ,-60.348907470703125 ,-60.348907470703125 ,-55.91640853881836 ,-53.692840576171875 ,-59.337890625 ,-60.348907470703125 ,-53.692840576171875 ,-59.337890625 ,-53.692840576171875 ,-47.05308532714844 ,-59.337890625 ,-47.05308532714844 ,-50.48353576660156 ,-50.48353576660156 ,-47.05308532714844 ,-35.20200729370117 ,-50.48353576660156 ,-35.20200729370117 ,-33.086769104003906 ,-33.086769104003906 ,-35.20200729370117 ,-24.778844833374023 ,-33.086769104003906 ,-24.778844833374023 ,-26.16839599609375 ,-33.086769104003906 ,-26.16839599609375 ,-41.20072937011719 ,-26.78887176513672 ,-26.16839599609375 ,-23.776256561279297 ,-26.78887176513672 ,-23.776256561279297 ,-26.977195739746094 ,-26.78887176513672 ,-26.977195739746094 ,-28.229341506958008 ,-28.229341506958008 ,-26.977195739746094 ,-30.56441307067871 ,-30.56441307067871 ,-26.977195739746094 ,-28.923904418945312 ,-30.56441307067871 ,-28.923904418945312 ,-32.77574157714844 ,-32.77574157714844 ,-28.923904418945312 ,-31.595598220825195 ,-32.77574157714844 ,-31.595598220825195 ,-36.65013122558594 ,-32.77574157714844 ,-36.65013122558594 ,-38.70508575439453 ,-49.310325622558594 ,-43.43236541748047 ,-37.725059509277344 ,-49.310325622558594 ,-58.127685546875 ,-43.43236541748047 ,-49.310325622558594 ,-37.725059509277344 ,-43.9151496887207 ,-43.9151496887207 ,-37.725059509277344 ,-35.37093734741211 ,-43.9151496887207 ,-48.8593635559082 ,-49.310325622558594 ,-43.9151496887207 ,-35.37093734741211 ,-31.51075553894043 ,-43.9151496887207 ,-31.51075553894043 ,-48.8593635559082 ,-49.310325622558594 ,-51.92376708984375 ,-58.127685546875 ,-49.310325622558594 ,-48.8593635559082 ,-51.92376708984375 ,-31.51075553894043 ,-23.18753433227539 ,-25.558605194091797 ,-25.558605194091797 ,-23.18753433227539 ,-9.217521667480469 ,-25.558605194091797 ,-9.217521667480469 ,-1.28290855884552 ,-13.02388858795166 ,-32.43184280395508 ,-12.762040138244629 ,-32.605865478515625 ,-17.79994010925293 ,-49.1010627746582 ,-32.605865478515625 ,-16.721044540405273 ,-17.79994010925293 ,-49.1010627746582 ,-17.79994010925293 ,-41.41432571411133 ,-49.1010627746582 ,-41.41432571411133 ,-55.91640853881836 ,-55.91640853881836 ,-41.41432571411133 ,-42.59168243408203 ,-55.91640853881836 ,-42.59168243408203 ,-53.692840576171875 ,-53.692840576171875 ,-33.67406463623047 ,-47.05308532714844 ,-53.692840576171875 ,-42.59168243408203 ,-33.67406463623047 ,-47.05308532714844 ,-33.67406463623047 ,-35.20200729370117 ,-35.20200729370117 ,-33.67406463623047 ,-25.204599380493164 ,-35.20200729370117 ,-25.204599380493164 ,-24.778844833374023 ,-24.778844833374023 ,-25.204599380493164 ,-22.0301570892334 ,-24.778844833374023 ,-22.0301570892334 ,-23.776256561279297 ,-24.778844833374023 ,-23.776256561279297 ,-26.16839599609375 ,-23.776256561279297 ,-24.630672454833984 ,-26.977195739746094 ,-23.776256561279297 ,-22.64946174621582 ,-24.630672454833984 ,-26.977195739746094 ,-24.630672454833984 ,-25.30805206298828 ,-26.977195739746094 ,-25.30805206298828 ,-28.923904418945312 ,-28.923904418945312 ,-25.30805206298828 ,-27.195173263549805 ,-28.923904418945312 ,-27.195173263549805 ,-31.595598220825195 ,-31.595598220825195 ,-27.195173263549805 ,-28.108015060424805 ,-38.37532424926758 ,-37.725059509277344 ,-43.43236541748047 ,-38.37532424926758 ,-28.37761688232422 ,-29.571529388427734 ,-38.37532424926758 ,-29.571529388427734 ,-37.725059509277344 ,-38.37532424926758 ,-43.43236541748047 ,-41.27777099609375 ,-37.725059509277344 ,-29.571529388427734 ,-35.37093734741211 ,-35.37093734741211 ,-23.04074478149414 ,-23.18753433227539 ,-35.37093734741211 ,-23.18753433227539 ,-31.51075553894043 ,-23.18753433227539 ,-21.08757781982422 ,-9.217521667480469 ,-17.79994010925293 ,-16.53158187866211 ,-41.41432571411133 ,-41.41432571411133 ,-16.53158187866211 ,-26.097490310668945 ,-41.41432571411133 ,-26.097490310668945 ,-42.59168243408203 ,-42.59168243408203 ,-26.097490310668945 ,-26.048677444458008 ,-33.67406463623047 ,-42.59168243408203 ,-26.048677444458008 ,-33.67406463623047 ,-26.048677444458008 ,-23.457304000854492 ,-33.67406463623047 ,-23.457304000854492 ,-25.204599380493164 ,-25.204599380493164 ,-23.457304000854492 ,-20.699670791625977 ,-25.204599380493164 ,-20.699670791625977 ,-22.0301570892334 ,-22.0301570892334 ,-20.699670791625977 ,-19.781009674072266 ,-22.0301570892334 ,-19.781009674072266 ,-22.64946174621582 ,-22.0301570892334 ,-22.64946174621582 ,-23.776256561279297 ,-24.630672454833984 ,-19.781009674072266 ,-22.186098098754883 ,-24.630672454833984 ,-22.64946174621582 ,-19.781009674072266 ,-24.630672454833984 ,-22.186098098754883 ,-25.30805206298828 ,-25.30805206298828 ,-22.186098098754883 ,-23.76213264465332 ,-25.30805206298828 ,-23.76213264465332 ,-27.195173263549805 ,-27.195173263549805 ,-23.76213264465332 ,-24.04348373413086 ,-27.195173263549805 ,-24.04348373413086 ,-24.0373592376709 ,-27.195173263549805 ,-24.0373592376709 ,-28.108015060424805 ,-28.108015060424805 ,-28.37761688232422 ,-31.595598220825195 ,-28.108015060424805 ,-24.0373592376709 ,-23.635549545288086 ,-28.108015060424805 ,-23.635549545288086 ,-28.37761688232422 ,-28.37761688232422 ,-38.37532424926758 ,-31.595598220825195 ,-31.595598220825195 ,-38.37532424926758 ,-36.65013122558594 ,-28.37761688232422 ,-23.635549545288086 ,-29.571529388427734 ,-29.571529388427734 ,-23.635549545288086 ,-24.556640625 ,-29.571529388427734 ,-24.556640625 ,-25.42995834350586 ,-29.571529388427734 ,-25.42995834350586 ,-35.37093734741211 ,-35.37093734741211 ,-25.42995834350586 ,-23.04074478149414 ,-23.04074478149414 ,-21.08757781982422 ,-23.18753433227539 ,-16.53158187866211 ,-12.453563690185547 ,-26.097490310668945 ,-26.097490310668945 ,-12.453563690185547 ,-10.673930168151855 ,-26.097490310668945 ,-10.673930168151855 ,-14.694073677062988 ,-26.097490310668945 ,-14.694073677062988 ,-26.048677444458008 ,-26.048677444458008 ,-14.694073677062988 ,-16.5230712890625 ,-26.048677444458008 ,-16.5230712890625 ,-23.457304000854492 ,-23.457304000854492 ,-16.5230712890625 ,-18.043184280395508 ,-23.457304000854492 ,-18.043184280395508 ,-20.699670791625977 ,-20.699670791625977 ,-18.043184280395508 ,-19.856922149658203 ,-20.699670791625977 ,-19.856922149658203 ,-19.781009674072266 ,-19.781009674072266 ,-19.856922149658203 ,-18.19673728942871 ,-22.186098098754883 ,-18.19673728942871 ,-20.269926071166992 ,-22.186098098754883 ,-19.781009674072266 ,-18.19673728942871 ,-22.186098098754883 ,-20.269926071166992 ,-23.76213264465332 ,-23.76213264465332 ,-20.269926071166992 ,-20.490047454833984 ,-23.76213264465332 ,-20.490047454833984 ,-24.04348373413086 ,-24.04348373413086 ,-20.490047454833984 ,-19.499570846557617 ,-24.04348373413086 ,-19.499570846557617 ,-24.0373592376709 ,-24.0373592376709 ,-19.499570846557617 ,-23.635549545288086 ,-23.635549545288086 ,-19.499570846557617 ,-18.72336769104004 ,-23.635549545288086 ,-18.72336769104004 ,-24.556640625 ,-24.556640625 ,-18.72336769104004 ,-20.40215301513672 ,-24.556640625 ,-20.40215301513672 ,-25.42995834350586 ,-20.40215301513672 ,-23.04074478149414 ,-25.42995834350586 ,-14.694073677062988 ,-8.995442390441895 ,-16.5230712890625 ,-14.694073677062988 ,-10.673930168151855 ,-8.995442390441895 ,-16.5230712890625 ,-8.995442390441895 ,-11.213990211486816 ,-16.5230712890625 ,-13.654541969299316 ,-18.043184280395508 ,-18.043184280395508 ,-13.654541969299316 ,-18.417266845703125 ,-18.043184280395508 ,-18.417266845703125 ,-19.856922149658203 ,-19.856922149658203 ,-18.417266845703125 ,-20.8195858001709 ,-19.856922149658203 ,-20.8195858001709 ,-17.882061004638672 ,-19.856922149658203 ,-17.882061004638672 ,-18.19673728942871 ,-20.269926071166992 ,-18.19673728942871 ,-17.47191047668457 ,-20.269926071166992 ,-17.47191047668457 ,-17.478492736816406 ,-20.269926071166992 ,-17.478492736816406 ,-20.490047454833984 ,-20.490047454833984 ,-17.478492736816406 ,-16.076217651367188 ,-20.490047454833984 ,-16.076217651367188 ,-19.499570846557617 ,-19.499570846557617 ,-16.076217651367188 ,-14.376813888549805 ,-19.499570846557617 ,-14.376813888549805 ,-11.556077003479004 ,-19.499570846557617 ,-11.556077003479004 ,-18.72336769104004 ,-18.72336769104004 ,-11.556077003479004 ,-14.807839393615723 ,-18.72336769104004 ,-14.807839393615723 ,-20.40215301513672 ,-11.213990211486816 ,-18.62034797668457 ,-13.654541969299316 ,-11.213990211486816 ,-13.654541969299316 ,-16.5230712890625 ,-13.654541969299316 ,-19.87643051147461 ,-18.417266845703125 ,-13.654541969299316 ,-18.62034797668457 ,-19.87643051147461 ,-18.417266845703125 ,-19.87643051147461 ,-22.34345817565918 ,-18.417266845703125 ,-22.34345817565918 ,-20.8195858001709 ,-20.8195858001709 ,-22.34345817565918 ,-17.882061004638672 ,-17.882061004638672 ,-22.34345817565918 ,-16.697416305541992 ,-17.882061004638672 ,-16.697416305541992 ,-17.47191047668457 ,-17.882061004638672 ,-17.47191047668457 ,-18.19673728942871 ,-17.47191047668457 ,-15.349625587463379 ,-17.478492736816406 ,-17.478492736816406 ,-15.349625587463379 ,-12.568105697631836 ,-17.478492736816406 ,-12.568105697631836 ,-16.076217651367188 ,-16.076217651367188 ,-12.568105697631836 ,-7.209066390991211 ,-16.076217651367188 ,-7.209066390991211 ,-14.376813888549805 ,-14.376813888549805 ,-7.209066390991211 ,-9.068727493286133 ,-14.376813888549805 ,-9.068727493286133 ,-11.556077003479004 ,-19.87643051147461 ,-21.758371353149414 ,-23.18262481689453 ,-19.87643051147461 ,-18.62034797668457 ,-21.758371353149414 ,-19.87643051147461 ,-23.18262481689453 ,-23.89716148376465 ,-19.87643051147461 ,-23.89716148376465 ,-22.34345817565918 ,-22.34345817565918 ,-23.89716148376465 ,-23.613245010375977 ,-16.697416305541992 ,-18.67672348022461 ,-14.250904083251953 ,-16.697416305541992 ,-14.250904083251953 ,-15.349625587463379 ,-16.697416305541992 ,-15.349625587463379 ,-17.47191047668457 ,-12.568105697631836 ,-3.8040237426757812 ,-5.106509685516357 ,-12.568105697631836 ,-5.106509685516357 ,-7.209066390991211 ,-7.209066390991211 ,-5.106509685516357 ,-6.139158248901367 ,-18.67672348022461 ,-10.522645950317383 ,-14.250904083251953 ,2391.385498046875 ,2346.43994140625 ,2293.187255859375 ,2391.385498046875 ,2293.187255859375 ,2235.03515625 ,-126.32351684570312 ,-132.94859313964844 ,-115.61714172363281 ,1672.9542236328125 ,1669.6793212890625 ,1673.916259765625 ,1673.916259765625 ,1674.682861328125 ,1672.9542236328125 ,1673.916259765625 ,1676.0706787109375 ,1674.682861328125 ,1662.6553955078125 ,1664.9896240234375 ,1662.9305419921875 ,1647.8907470703125 ,1653.60546875 ,1651.218505859375 ,1647.8907470703125 ,1646.0224609375 ,1653.60546875 ,1647.8907470703125 ,1645.3182373046875 ,1646.0224609375 ,1628.5848388671875 ,1633.216552734375 ,1609.6234130859375 ,1566.445068359375 ,1558.3780517578125 ,1571.6690673828125 ,1566.445068359375 ,1573.506591796875 ,1564.0841064453125 ,1566.445068359375 ,1564.0841064453125 ,1558.3780517578125 ,1566.445068359375 ,1577.423583984375 ,1573.506591796875 ,1566.445068359375 ,1571.6690673828125 ,1577.423583984375 ,1558.3780517578125 ,1564.0841064453125 ,1550.7193603515625 ,1573.506591796875 ,1579.9024658203125 ,1575.1865234375 ,1573.506591796875 ,1575.1865234375 ,1564.0841064453125 ,1573.506591796875 ,1577.423583984375 ,1579.9024658203125 ,1577.423583984375 ,1587.8934326171875 ,1579.9024658203125 ,1584.2979736328125 ,1575.6142578125 ,1575.1865234375 ,1584.2979736328125 ,1575.1865234375 ,1579.9024658203125 ,1589.8682861328125 ,1599.9283447265625 ,1593.3438720703125 ,1593.3438720703125 ,1599.9283447265625 ,1603.496337890625 ,1639.3721923828125 ,1632.9971923828125 ,1626.034912109375 ,1639.3721923828125 ,1626.034912109375 ,1644.2154541015625 ,1644.2154541015625 ,1626.034912109375 ,1618.046630859375 ,1660.006591796875 ,1668.263916015625 ,1664.9896240234375 ,1652.9853515625 ,1644.7115478515625 ,1645.9932861328125 ,1652.9853515625 ,1658.31884765625 ,1656.087158203125 ,1652.9853515625 ,1651.05126953125 ,1644.7115478515625 ,1652.9853515625 ,1656.087158203125 ,1651.05126953125 ,1657.4315185546875 ,1653.57763671875 ,1660.5411376953125 ,1657.4315185546875 ,1660.5411376953125 ,1659.8006591796875 ,1643.9544677734375 ,1646.0224609375 ,1634.888916015625 ,1659.8006591796875 ,1667.7757568359375 ,1660.6507568359375 ,1659.8006591796875 ,1660.5411376953125 ,1667.7757568359375 ,1634.888916015625 ,1645.3182373046875 ,1641.365966796875 ,1634.888916015625 ,1646.0224609375 ,1645.3182373046875 ,1645.3182373046875 ,1643.419677734375 ,1641.365966796875 ,1650.7645263671875 ,1653.4361572265625 ,1643.419677734375 ,1643.419677734375 ,1653.6058349609375 ,1639.4248046875 ,1643.419677734375 ,1653.4361572265625 ,1651.813232421875 ,1643.419677734375 ,1651.813232421875 ,1653.6058349609375 ,1652.6387939453125 ,1659.970947265625 ,1655.2957763671875 ,1684.72509765625 ,1685.5919189453125 ,1683.3270263671875 ,1680.6246337890625 ,1682.7386474609375 ,1684.0565185546875 ,1680.6246337890625 ,1682.3333740234375 ,1682.7386474609375 ,1684.0565185546875 ,1682.7386474609375 ,1684.94921875 ,1675.08056640625 ,1673.7159423828125 ,1666.320068359375 ,1675.08056640625 ,1666.7978515625 ,1670.451416015625 ,1675.08056640625 ,1666.320068359375 ,1666.7978515625 ,1666.320068359375 ,1673.7159423828125 ,1671.9622802734375 ,1636.14453125 ,1664.204345703125 ,1665.359130859375 ,1552.570556640625 ,1547.3134765625 ,1555.5306396484375 ,1555.5306396484375 ,1547.3134765625 ,1552.678466796875 ,1555.5306396484375 ,1552.678466796875 ,1556.0623779296875 ,1556.0623779296875 ,1558.35107421875 ,1565.1370849609375 ,1556.0623779296875 ,1552.678466796875 ,1558.35107421875 ,1634.888916015625 ,1638.5103759765625 ,1644.7115478515625 ,1634.888916015625 ,1644.7115478515625 ,1643.9544677734375 ,1649.9718017578125 ,1639.4248046875 ,1653.6058349609375 ,1653.9100341796875 ,1651.9105224609375 ,1657.7440185546875 ,1651.9105224609375 ,1641.9266357421875 ,1638.3662109375 ,-106.64468383789062 ,-92.26326751708984 ,-97.81755828857422 ,-33.199073791503906 ,-106.60688781738281 ,18.952594757080078 ,1651.9105224609375 ,1638.3662109375 ,1651.02587890625 ,1638.3662109375 ,1645.4649658203125 ,1651.02587890625 ,1626.9364013671875 ,1640.7991943359375 ,1639.356201171875 ,1626.9364013671875 ,1639.356201171875 ,1627.7117919921875 ,1605.6170654296875 ,1608.6029052734375 ,1604.4390869140625 ,1605.6170654296875 ,1613.7576904296875 ,1608.6029052734375 ,927.310791015625 ,887.3312377929688 ,933.4078369140625 ,933.4078369140625 ,943.5916137695312 ,927.310791015625 ,933.4078369140625 ,962.6599731445312 ,943.5916137695312 ,1480.235107421875 ,1406.46630859375 ,1457.6270751953125 ,1480.235107421875 ,1464.3046875 ,1406.46630859375 ,1480.235107421875 ,1475.08251953125 ,1464.3046875 ,1480.235107421875 ,1481.825927734375 ,1475.08251953125 ,128.33255004882812 ,174.18772888183594 ,149.82284545898438 ,1661.6611328125 ,1665.322509765625 ,1667.3758544921875 ,1661.6611328125 ,1667.3758544921875 ,1660.7755126953125 ,1600.1199951171875 ,1601.854736328125 ,1601.0672607421875 ,1600.1199951171875 ,1601.0672607421875 ,1600.988525390625 ,1600.1199951171875 ,1599.591064453125 ,1601.854736328125 ,1600.1199951171875 ,1600.988525390625 ,1600.48583984375 ,1600.1199951171875 ,1598.7205810546875 ,1599.591064453125 ,1600.1199951171875 ,1600.48583984375 ,1598.7205810546875 ,1599.591064453125 ,1598.7205810546875 ,1599.11962890625 ,1594.9661865234375 ,1598.990234375 ,1594.349609375 ,1575.8009033203125 ,1596.012939453125 ,1590.8773193359375 ,1426.2479248046875 ,1596.181396484375 ,1504.6903076171875 ,1426.2479248046875 ,1504.6903076171875 ,1387.4476318359375 ,1426.2479248046875 ,1384.2012939453125 ,1596.181396484375 ,1596.181396484375 ,1575.8009033203125 ,1504.6903076171875 ,1596.181396484375 ,1649.01171875 ,1565.6654052734375 ,1596.181396484375 ,1384.2012939453125 ,1515.2393798828125 ,1223.4453125 ,1369.2298583984375 ,1348.49267578125 ,1223.4453125 ,1348.49267578125 ,1173.2772216796875 ,852.0170288085938 ,845.0215454101562 ,814.9298095703125 ,852.0170288085938 ,814.9298095703125 ,839.070556640625 ,852.0170288085938 ,839.070556640625 ,843.0507202148438 ,1120.439208984375 ,1123.282470703125 ,1087.777587890625 ,1120.439208984375 ,1087.777587890625 ,1080.477294921875 ,1120.439208984375 ,1080.477294921875 ,1092.355224609375 ,174.18772888183594 ,191.36724853515625 ,171.8939208984375 ,174.18772888183594 ,171.8939208984375 ,149.82284545898438 ,28.987707138061523 ,0.48955801129341125 ,14.08456802368164 ,-13.140868186950684 ,-15.03766918182373 ,-8.421085357666016 ,-13.140868186950684 ,-29.316699981689453 ,-15.03766918182373 ,-13.140868186950684 ,-8.421085357666016 ,-19.138835906982422 ,1660.8126220703125 ,1653.598388671875 ,1662.9295654296875 ,1647.4891357421875 ,1637.8194580078125 ,1652.8292236328125 ,1679.4403076171875 ,1678.669921875 ,1684.5247802734375 ,1620.0291748046875 ,1615.1318359375 ,1618.6702880859375 ,1615.1318359375 ,1613.200927734375 ,1618.6702880859375 ,1615.1318359375 ,1611.5498046875 ,1609.84326171875 ,1615.1318359375 ,1609.84326171875 ,1613.200927734375 ,1608.4158935546875 ,1606.5872802734375 ,1603.4041748046875 ,1606.5872802734375 ,1602.937255859375 ,1603.4041748046875 ,1603.4041748046875 ,1602.4737548828125 ,1604.43994140625 ,1603.4041748046875 ,1604.43994140625 ,1608.4158935546875 ,1574.4058837890625 ,1535.486572265625 ,1655.201416015625 ,1574.4058837890625 ,1655.201416015625 ,1635.144775390625 ,822.20458984375 ,722.618408203125 ,829.4507446289062 ,822.20458984375 ,829.4507446289062 ,1006.2012939453125 ,822.20458984375 ,772.8612060546875 ,722.618408203125 ,822.20458984375 ,1006.2012939453125 ,952.9100341796875 ,734.7967529296875 ,822.512939453125 ,847.0896606445312 ,734.7967529296875 ,847.0896606445312 ,829.4507446289062 ,734.7967529296875 ,709.255126953125 ,822.512939453125 ,734.7967529296875 ,829.4507446289062 ,722.618408203125 ,734.7967529296875 ,722.618408203125 ,709.255126953125 ,822.512939453125 ,709.255126953125 ,709.1033325195312 ,800.8710327148438 ,806.5791015625 ,806.5247192382812 ,806.5791015625 ,823.83154296875 ,806.5247192382812 ,805.5436401367188 ,823.83154296875 ,806.5791015625 ,805.5436401367188 ,831.0919189453125 ,823.83154296875 ,787.6688232421875 ,798.9462280273438 ,807.5975952148438 ,798.9462280273438 ,800.7420043945312 ,807.5975952148438 ,396.64276123046875 ,431.29559326171875 ,466.0267333984375 ,130.03395080566406 ,35.302860260009766 ,20.28254508972168 ,1565.9283447265625 ,1566.0189208984375 ,1561.3687744140625 ,1561.3687744140625 ,1562.6962890625 ,1565.9283447265625 ,1613.71533203125 ,1617.68212890625 ,1611.6375732421875 ,1611.6375732421875 ,1617.68212890625 ,1608.282958984375 ,1611.6375732421875 ,1608.282958984375 ,1613.71533203125 ,1588.1116943359375 ,1577.3192138671875 ,1575.1566162109375 ,1588.1116943359375 ,1575.1566162109375 ,1584.7598876953125 ,1577.3192138671875 ,1563.51953125 ,1571.10107421875 ,1577.3192138671875 ,1571.10107421875 ,1575.1566162109375 ,1613.0711669921875 ,1623.382568359375 ,1627.1104736328125 ,1613.0711669921875 ,1624.34375 ,1608.5009765625 ,1666.97705078125 ,1668.600830078125 ,1657.2647705078125 ,1662.9033203125 ,1669.9600830078125 ,1665.784912109375 ,1665.1942138671875 ,1675.47314453125 ,1672.67822265625 ,1675.1297607421875 ,1678.8447265625 ,1679.259033203125 ,1675.1297607421875 ,1679.259033203125 ,1676.636474609375 ,1678.8447265625 ,1682.7294921875 ,1679.259033203125 ,1675.1297607421875 ,1676.636474609375 ,1673.2105712890625 ,1675.1297607421875 ,1673.2105712890625 ,1672.0784912109375 ,1675.1297607421875 ,1672.0784912109375 ,1674.2576904296875 ,744.7554931640625 ,739.1107788085938 ,740.8212280273438 ,744.7554931640625 ,715.9713134765625 ,739.1107788085938 ,744.7554931640625 ,746.0133056640625 ,715.9713134765625 ,744.7554931640625 ,742.4617309570312 ,746.0133056640625 ,739.1107788085938 ,710.6922607421875 ,740.8212280273438 ,739.1107788085938 ,700.0632934570312 ,710.6922607421875 ,739.1107788085938 ,715.9713134765625 ,700.0632934570312 ,740.8212280273438 ,739.1737060546875 ,745.8952026367188 ,740.8212280273438 ,710.6922607421875 ,739.1737060546875 ,740.8212280273438 ,745.8952026367188 ,747.1206665039062 ,740.8212280273438 ,747.1206665039062 ,744.7554931640625 ,805.4881591796875 ,798.9462280273438 ,799.7229614257812 ,805.4881591796875 ,803.9970092773438 ,798.9462280273438 ,805.4881591796875 ,799.7229614257812 ,801.35595703125 ,372.7715759277344 ,255.31051635742188 ,384.8097229003906 ,372.7715759277344 ,297.4990234375 ,255.31051635742188 ,372.7715759277344 ,346.9749755859375 ,297.4990234375 ,372.7715759277344 ,384.8097229003906 ,346.9749755859375 ,384.8097229003906 ,255.31051635742188 ,461.52252197265625 ,1547.94482421875 ,1540.0787353515625 ,1588.2427978515625 ,1540.0787353515625 ,1550.125 ,1574.69580078125 ,1540.0787353515625 ,1574.69580078125 ,1587.00634765625 ,1540.0787353515625 ,1587.00634765625 ,1588.2427978515625 ,-271.23895263671875 ,-176.4127197265625 ,-243.66262817382812 ,-271.23895263671875 ,-160.0223388671875 ,-176.4127197265625 ,-176.4127197265625 ,-183.16323852539062 ,-243.66262817382812 ,-176.4127197265625 ,-160.0223388671875 ,-156.220947265625 ,-176.4127197265625 ,-151.3717803955078 ,-183.16323852539062 ,-176.4127197265625 ,-156.220947265625 ,-151.3717803955078 ,1601.7579345703125 ,1595.2255859375 ,1613.6981201171875 ,1601.7579345703125 ,1613.6981201171875 ,1619.9852294921875 ,1613.6981201171875 ,1637.7955322265625 ,1619.9852294921875 ,1558.0872802734375 ,1548.9468994140625 ,1561.04443359375 ,1558.0872802734375 ,1566.4603271484375 ,1558.8492431640625 ,1558.0872802734375 ,1561.04443359375 ,1566.4603271484375 ,1561.04443359375 ,1568.1436767578125 ,1566.4603271484375 ,1573.8773193359375 ,1574.3280029296875 ,1565.9283447265625 ,1558.8492431640625 ,1553.962646484375 ,1548.560302734375 ,1558.8492431640625 ,1555.5660400390625 ,1553.962646484375 ,1558.8492431640625 ,1566.4603271484375 ,1555.5660400390625 ,1555.5660400390625 ,1566.4603271484375 ,1570.5435791015625 ,1568.1436767578125 ,1572.86376953125 ,1566.4603271484375 ,1568.1436767578125 ,1569.2528076171875 ,1572.86376953125 ,1568.1436767578125 ,1561.04443359375 ,1569.2528076171875 ,1587.5968017578125 ,1577.078125 ,1574.3280029296875 ,1555.5660400390625 ,1570.5435791015625 ,1574.4034423828125 ,-3.633512020111084 ,-10.222365379333496 ,-8.213500022888184 ,1589.7457275390625 ,1588.25830078125 ,1583.048095703125 ,1583.048095703125 ,1578.07763671875 ,1576.6949462890625 ,1583.048095703125 ,1580.8135986328125 ,1578.07763671875 ,1583.0238037109375 ,1595.2420654296875 ,1584.7598876953125 ,1583.0238037109375 ,1584.7598876953125 ,1574.396240234375 ,1583.0238037109375 ,1612.751220703125 ,1595.2420654296875 ,1583.0238037109375 ,1593.195068359375 ,1612.751220703125 ,1595.2420654296875 ,1612.751220703125 ,1599.9251708984375 ,1595.2420654296875 ,1608.689697265625 ,1601.7042236328125 ,1595.2420654296875 ,1608.5009765625 ,1608.689697265625 ,1647.9674072265625 ,1623.9122314453125 ,1621.678955078125 ,1647.9674072265625 ,1621.678955078125 ,1640.5447998046875 ,1669.38330078125 ,1652.837646484375 ,1668.600830078125 ,1669.38330078125 ,1668.600830078125 ,1673.774169921875 ,1672.989013671875 ,1671.78515625 ,1671.922119140625 ,1672.989013671875 ,1671.922119140625 ,1670.8912353515625 ,1672.989013671875 ,1679.5113525390625 ,1671.78515625 ,1677.0831298828125 ,1680.2239990234375 ,1676.400634765625 ,1676.400634765625 ,1675.341064453125 ,1677.0831298828125 ,1664.8974609375 ,1664.044677734375 ,1665.5711669921875 ,1664.8974609375 ,1665.5711669921875 ,1666.755126953125 ,1664.8974609375 ,1663.3662109375 ,1664.044677734375 ,1664.044677734375 ,1664.9874267578125 ,1665.5711669921875 ,1664.044677734375 ,1659.814208984375 ,1664.9874267578125 ,1665.5711669921875 ,1664.9874267578125 ,1666.7664794921875 ,1641.6319580078125 ,1646.7701416015625 ,1637.9412841796875 ,1641.6319580078125 ,1637.9412841796875 ,1638.23876953125 ,1641.6319580078125 ,1638.23876953125 ,1637.6385498046875 ,1642.7744140625 ,1632.2459716796875 ,1641.77685546875 ,1641.77685546875 ,1629.5826416015625 ,1639.492919921875 ,1409.114990234375 ,1249.8555908203125 ,1324.3756103515625 ,1455.574462890625 ,1489.771728515625 ,1494.8699951171875 ,1455.574462890625 ,1447.7816162109375 ,1489.771728515625 ,1455.574462890625 ,1406.17626953125 ,1447.7816162109375 ,1489.771728515625 ,1447.7816162109375 ,1484.3262939453125 ,1489.771728515625 ,1484.3262939453125 ,1492.576904296875 ,1447.7816162109375 ,1406.17626953125 ,1484.3262939453125 ,1589.718017578125 ,1567.586669921875 ,1589.9259033203125 ,1589.9259033203125 ,1567.586669921875 ,1591.67333984375 ,1589.9259033203125 ,1591.67333984375 ,1615.714599609375 ,1592.60205078125 ,1598.22265625 ,1592.45556640625 ,1556.9638671875 ,1555.383056640625 ,1564.7724609375 ,-149.0703582763672 ,-154.72377014160156 ,-142.1386260986328 ,1674.372314453125 ,1664.719482421875 ,1671.5623779296875 ,1664.719482421875 ,1674.372314453125 ,1668.6605224609375 ,1568.8011474609375 ,1585.3182373046875 ,1630.985595703125 ,1568.8011474609375 ,1569.4425048828125 ,1585.3182373046875 ,1994.48974609375 ,2273.0771484375 ,1934.1468505859375 ,1994.48974609375 ,1934.1468505859375 ,1562.002685546875 ,1994.48974609375 ,1562.002685546875 ,2273.0771484375 ,2273.0771484375 ,2009.0777587890625 ,2346.43994140625 ,2273.0771484375 ,2346.43994140625 ,1934.1468505859375 ,2273.0771484375 ,2316.001708984375 ,2009.0777587890625 ,2273.0771484375 ,1562.002685546875 ,2316.001708984375 ,804.3577270507812 ,890.6671752929688 ,812.12744140625 ,890.6671752929688 ,945.8577880859375 ,987.7450561523438 ,890.6671752929688 ,987.7450561523438 ,812.12744140625 ,-161.3847198486328 ,-169.35028076171875 ,-161.09625244140625 ,-161.3847198486328 ,-161.09625244140625 ,-156.71910095214844 ,-161.3847198486328 ,-168.5785675048828 ,-169.35028076171875 ,-169.35028076171875 ,-190.1183624267578 ,-161.09625244140625 ,-169.35028076171875 ,-215.37332153320312 ,-190.1183624267578 ,-169.35028076171875 ,-223.46041870117188 ,-215.37332153320312 ,-169.35028076171875 ,-168.5785675048828 ,-223.46041870117188 ,-161.09625244140625 ,-154.3759307861328 ,-156.71910095214844 ,-161.09625244140625 ,-190.1183624267578 ,-154.3759307861328 ,-48.14024353027344 ,-121.85279083251953 ,-109.26838684082031 ,-48.14024353027344 ,-109.26838684082031 ,-7.0689778327941895 ,-158.5688018798828 ,-161.47756958007812 ,-163.4934844970703 ,-158.5688018798828 ,-163.4934844970703 ,-159.6973876953125 ,-158.5688018798828 ,-159.6973876953125 ,-155.86891174316406 ,-161.47756958007812 ,-162.4461212158203 ,-163.4934844970703 ,-163.4934844970703 ,-164.23593139648438 ,-159.6973876953125 ,-163.4934844970703 ,-168.3688507080078 ,-164.23593139648438 ,-163.4934844970703 ,-162.4461212158203 ,-168.3688507080078 ,1671.5623779296875 ,1664.719482421875 ,1632.3934326171875 ,843.8851318359375 ,853.9212036132812 ,853.804443359375 ,842.852294921875 ,793.662109375 ,772.7360229492188 ,843.8851318359375 ,842.852294921875 ,815.931396484375 ,1801.1998291015625 ,1814.4393310546875 ,1622.8790283203125 ,1426.50927734375 ,1491.1573486328125 ,1408.5682373046875 ,1846.568603515625 ,1606.1458740234375 ,1152.3909912109375 ,1846.568603515625 ,1872.0791015625 ,2001.811767578125 ,1846.568603515625 ,2001.811767578125 ,1606.1458740234375 ,1846.568603515625 ,1726.457275390625 ,1872.0791015625 ,1152.3909912109375 ,793.8865356445312 ,886.9500732421875 ,1152.3909912109375 ,886.9500732421875 ,1846.568603515625 ,793.662109375 ,842.852294921875 ,816.4202880859375 ,842.852294921875 ,803.7413940429688 ,816.4202880859375 ,816.4202880859375 ,803.7413940429688 ,604.1659545898438 ,874.3663940429688 ,846.4479370117188 ,862.8421630859375 ,874.3663940429688 ,841.958740234375 ,846.4479370117188 ,-147.094482421875 ,-150.1798553466797 ,-141.97189331054688 ,-150.1798553466797 ,-147.094482421875 ,-148.68128967285156 ,-150.1798553466797 ,-150.5584259033203 ,-141.97189331054688 ,-150.1798553466797 ,-153.44395446777344 ,-150.5584259033203 ,866.286376953125 ,874.3985595703125 ,838.6942749023438 ,866.286376953125 ,838.6942749023438 ,815.0030517578125 ,866.286376953125 ,815.0030517578125 ,827.5255126953125 ,874.3985595703125 ,873.3203735351562 ,849.3843994140625 ,874.3985595703125 ,849.3843994140625 ,838.6942749023438 ,838.6942749023438 ,831.8568725585938 ,815.0030517578125 ,838.6942749023438 ,849.3843994140625 ,831.8568725585938 ,779.9949951171875 ,810.6036987304688 ,789.5177612304688 ,-138.8554229736328 ,-136.73898315429688 ,-137.98291015625 ,-138.8554229736328 ,-137.98291015625 ,-138.47950744628906 ,-138.8554229736328 ,-138.47950744628906 ,-139.9047393798828 ,-138.8554229736328 ,-139.9047393798828 ,-141.23570251464844 ,-136.73898315429688 ,-135.33396911621094 ,-137.98291015625 ,-136.73898315429688 ,-134.471923828125 ,-135.33396911621094 ,1130.995361328125 ,895.8970947265625 ,1127.7244873046875 ,1130.995361328125 ,897.042724609375 ,895.8970947265625 ,1130.995361328125 ,1000.3450317382812 ,897.042724609375 ,1130.995361328125 ,1127.7244873046875 ,1017.6915893554688 ,839.9677124023438 ,785.249267578125 ,781.9956665039062 ,881.3502807617188 ,881.7457885742188 ,881.2029418945312 ,881.3502807617188 ,873.4906616210938 ,881.7457885742188 ,881.3502807617188 ,816.025146484375 ,873.4906616210938 ,816.025146484375 ,771.46240234375 ,873.4906616210938 ,858.2318115234375 ,845.7063598632812 ,842.575927734375 ,858.2318115234375 ,842.575927734375 ,869.6773071289062 ,858.2318115234375 ,869.6773071289062 ,887.5587158203125 ,867.7277221679688 ,881.2029418945312 ,815.16357421875 ,815.16357421875 ,881.2029418945312 ,848.1057739257812 ,867.7277221679688 ,815.16357421875 ,801.8882446289062 ,867.7277221679688 ,799.5333251953125 ,821.3425903320312 ,867.7277221679688 ,801.8882446289062 ,799.5333251953125 ,-87.01240539550781 ,-84.9164047241211 ,-83.4723129272461 ,-87.01240539550781 ,-95.26194763183594 ,-84.9164047241211 ,-92.81271362304688 ,-56.8443603515625 ,-63.73884963989258 ,1592.6134033203125 ,1588.199462890625 ,1615.5040283203125 ,1592.6134033203125 ,1579.7747802734375 ,1588.199462890625 ,1579.7747802734375 ,1536.4788818359375 ,1542.45068359375 ,1579.7747802734375 ,1542.45068359375 ,1588.199462890625 ,1579.7747802734375 ,1592.6134033203125 ,1536.4788818359375 ,-110.80560302734375 ,-115.13775634765625 ,-109.54987335205078 ,792.6576538085938 ,773.19140625 ,791.2133178710938 ,825.109130859375 ,845.7063598632812 ,858.2318115234375 ,825.109130859375 ,778.8511962890625 ,766.9347534179688 ,825.109130859375 ,858.2318115234375 ,778.8511962890625 ,848.1057739257812 ,881.7457885742188 ,803.7923583984375 ,848.1057739257812 ,881.2029418945312 ,881.7457885742188 ,848.1057739257812 ,792.5941162109375 ,815.16357421875 ,848.1057739257812 ,803.7923583984375 ,792.5941162109375 ,881.7457885742188 ,868.508056640625 ,803.7923583984375 ,881.7457885742188 ,873.4906616210938 ,868.508056640625 ,868.508056640625 ,873.4906616210938 ,884.280517578125 ,868.508056640625 ,884.280517578125 ,825.8290405273438 ,1660.5411376953125 ,1658.153564453125 ,1658.5709228515625 ,1660.5411376953125 ,1653.57763671875 ,1654.66064453125 ,1660.5411376953125 ,1654.66064453125 ,1658.153564453125 ,1658.5709228515625 ,1661.9881591796875 ,1660.5411376953125 ,1658.5709228515625 ,1658.153564453125 ,1661.9881591796875 ,1668.263916015625 ,1676.0706787109375 ,1673.916259765625 ,1578.15625 ,1569.775390625 ,1603.6051025390625 ,-172.1576690673828 ,-169.60626220703125 ,-162.84446716308594 ,-172.1576690673828 ,-172.62753295898438 ,-169.60626220703125 ,-172.62753295898438 ,-173.61891174316406 ,-174.07568359375 ,1621.914794921875 ,1653.1845703125 ,1642.1343994140625 ,1642.1343994140625 ,1645.7117919921875 ,1621.914794921875 ,1541.7872314453125 ,1537.8978271484375 ,1552.5557861328125 ,1643.993896484375 ,1640.2740478515625 ,1643.3203125 ,1643.993896484375 ,1642.681396484375 ,1640.2740478515625 ,1369.2298583984375 ,1223.4453125 ,1363.8858642578125 ,822.20458984375 ,952.9100341796875 ,963.9760131835938 ,822.20458984375 ,963.9760131835938 ,772.8612060546875 ,952.9100341796875 ,1173.2772216796875 ,963.9760131835938 ,952.9100341796875 ,1009.453369140625 ,1173.2772216796875 ,845.0215454101562 ,852.0170288085938 ,827.7611083984375 ,845.0215454101562 ,814.5217895507812 ,814.9298095703125 ,845.0215454101562 ,827.7611083984375 ,814.5217895507812 ,823.1783447265625 ,818.9583740234375 ,799.7362060546875 ,823.1783447265625 ,834.166015625 ,818.9583740234375 ,823.1783447265625 ,799.7362060546875 ,811.1006469726562 ,823.1783447265625 ,811.1006469726562 ,835.4942016601562 ,1662.6783447265625 ,1679.518310546875 ,1694.8782958984375 ,1662.6783447265625 ,1694.8782958984375 ,1667.8065185546875 ,1662.6783447265625 ,1667.8065185546875 ,1657.7835693359375 ,1694.8782958984375 ,1684.8160400390625 ,1667.8065185546875 ,-8.421085357666016 ,0.48955801129341125 ,5.952480792999268 ,-8.421085357666016 ,5.952480792999268 ,11.090381622314453 ,1662.3084716796875 ,1659.79052734375 ,1660.623779296875 ,1662.3084716796875 ,1660.623779296875 ,1664.03955078125 ,1662.3084716796875 ,1664.03955078125 ,1663.9632568359375 ,1659.79052734375 ,1662.3084716796875 ,1657.7269287109375 ,1659.79052734375 ,1657.7269287109375 ,1660.623779296875 ,1601.3475341796875 ,1604.507568359375 ,1603.0877685546875 ,1601.3475341796875 ,1604.4119873046875 ,1604.507568359375 ,1604.507568359375 ,1604.4119873046875 ,1604.0233154296875 ,1604.507568359375 ,1604.0233154296875 ,1603.0877685546875 ,952.9100341796875 ,1006.2012939453125 ,1009.453369140625 ,772.8612060546875 ,706.0634765625 ,722.618408203125 ,824.8201904296875 ,787.8994750976562 ,787.9410400390625 ,824.8201904296875 ,805.5436401367188 ,787.8994750976562 ,1667.9810791015625 ,1664.859130859375 ,1673.2763671875 ,1602.7296142578125 ,1601.361328125 ,1601.2574462890625 ,1601.361328125 ,1602.168701171875 ,1601.2574462890625 ,1601.361328125 ,1600.859375 ,1602.168701171875 ,747.9286499023438 ,759.8478393554688 ,751.3086547851562 ,747.9286499023438 ,745.458740234375 ,759.8478393554688 ,747.9286499023438 ,744.73828125 ,753.7611083984375 ,747.9286499023438 ,751.3086547851562 ,744.73828125 ,747.9286499023438 ,753.7611083984375 ,745.458740234375 ,759.8478393554688 ,747.1206665039062 ,767.7692260742188 ,759.8478393554688 ,745.458740234375 ,747.1206665039062 ,759.8478393554688 ,767.7692260742188 ,751.3086547851562 ,751.3086547851562 ,751.7406616210938 ,744.73828125 ,590.23095703125 ,458.4006042480469 ,561.6047973632812 ,20.28254508972168 ,22.273630142211914 ,130.03395080566406 ,20.28254508972168 ,35.302860260009766 ,22.273630142211914 ,130.03395080566406 ,22.273630142211914 ,2.2539000511169434 ,130.03395080566406 ,2.2539000511169434 ,39.34755325317383 ,1548.8284912109375 ,1548.9468994140625 ,1550.103271484375 ,-146.88943481445312 ,-149.2166748046875 ,-162.18087768554688 ,-146.88943481445312 ,-162.18087768554688 ,-170.53453063964844 ,1669.373046875 ,1668.416259765625 ,1671.40869140625 ,1669.373046875 ,1666.7664794921875 ,1668.416259765625 ,1513.2626953125 ,2080.4912109375 ,1489.4591064453125 ,1513.2626953125 ,1454.7735595703125 ,2080.4912109375 ,1591.67333984375 ,1567.586669921875 ,1563.31787109375 ,1563.31787109375 ,1615.714599609375 ,1591.67333984375 ,1563.31787109375 ,1571.35205078125 ,1615.714599609375 ,1623.39892578125 ,1643.8046875 ,1624.4599609375 ,1598.22265625 ,1592.60205078125 ,1601.060791015625 ,1601.060791015625 ,1598.5628662109375 ,1608.6427001953125 ,1601.060791015625 ,1608.6427001953125 ,1598.22265625 ,1601.060791015625 ,1592.60205078125 ,1598.5628662109375 ,1598.22265625 ,1608.6427001953125 ,1601.3533935546875 ,-138.46212768554688 ,-133.1144561767578 ,-146.88943481445312 ,-146.88943481445312 ,-149.0703582763672 ,-138.46212768554688 ,-138.46212768554688 ,-149.0703582763672 ,-139.89889526367188 ,1638.38623046875 ,1636.0416259765625 ,1637.9412841796875 ,1636.0416259765625 ,1636.2884521484375 ,1633.53369140625 ,1674.372314453125 ,1666.1053466796875 ,1668.6605224609375 ,795.3846435546875 ,800.04736328125 ,792.85107421875 ,795.3846435546875 ,796.2474975585938 ,800.04736328125 ,785.5821533203125 ,784.9931640625 ,798.1160888671875 ,784.9931640625 ,792.5782470703125 ,798.1160888671875 ,783.5720825195312 ,793.9613037109375 ,791.5802001953125 ,783.5720825195312 ,781.643310546875 ,793.9613037109375 ,793.9613037109375 ,781.643310546875 ,779.3375244140625 ,-80.9568099975586 ,-128.61953735351562 ,-84.93722534179688 ,-128.61953735351562 ,-114.91108703613281 ,-84.93722534179688 ,-137.555419921875 ,-136.15399169921875 ,-134.15402221679688 ,-137.555419921875 ,-134.7921905517578 ,-136.15399169921875 ,-137.555419921875 ,-137.98291015625 ,-134.7921905517578 ,-137.555419921875 ,-138.60194396972656 ,-137.98291015625 ,-137.555419921875 ,-134.15402221679688 ,-138.12728881835938 ,-137.555419921875 ,-138.12728881835938 ,-138.60194396972656 ,-136.15399169921875 ,-132.725341796875 ,-134.15402221679688 ,-136.15399169921875 ,-134.7921905517578 ,-132.725341796875 ,-134.15402221679688 ,-138.8220977783203 ,-138.12728881835938 ,-96.9683609008789 ,-116.95503997802734 ,-144.3998565673828 ,-96.9683609008789 ,-144.3998565673828 ,-147.50628662109375 ,-116.95503997802734 ,-96.9683609008789 ,-123.2982406616211 ,-144.3998565673828 ,-116.95503997802734 ,-128.61953735351562 ,-144.3998565673828 ,-128.61953735351562 ,-80.9568099975586 ,-144.3998565673828 ,-80.9568099975586 ,-147.50628662109375 ,-75.91277313232422 ,38.04579162597656 ,-0.3093560039997101 ,-75.91277313232422 ,-0.3093560039997101 ,-96.9683609008789 ,-75.91277313232422 ,-147.50628662109375 ,-80.9568099975586 ,-75.91277313232422 ,-96.9683609008789 ,-147.50628662109375 ,-75.91277313232422 ,-80.9568099975586 ,-43.334495544433594 ,-75.91277313232422 ,-43.334495544433594 ,38.04579162597656 ,38.04579162597656 ,25.46628189086914 ,5.809103965759277 ,38.04579162597656 ,5.809103965759277 ,-0.3093560039997101 ,-0.3093560039997101 ,-62.83191680908203 ,-96.9683609008789 ,-0.3093560039997101 ,5.809103965759277 ,-56.81816482543945 ,-0.3093560039997101 ,-56.81816482543945 ,-62.83191680908203 ,1793.443359375 ,1728.110595703125 ,1759.4949951171875 ,1793.443359375 ,1798.2933349609375 ,1728.110595703125 ,1793.443359375 ,1835.1531982421875 ,1798.2933349609375 ,1793.443359375 ,1759.4949951171875 ,1843.4600830078125 ,1793.443359375 ,1843.4600830078125 ,1841.949462890625 ,1793.443359375 ,1841.949462890625 ,1835.1531982421875 ,1798.2933349609375 ,1835.1531982421875 ,1907.8543701171875 ,796.4855346679688 ,798.5071411132812 ,744.9285278320312 ,862.8421630859375 ,846.4479370117188 ,843.5925903320312 ,886.9500732421875 ,793.8865356445312 ,1000.3450317382812 ,1000.3450317382812 ,793.8865356445312 ,795.3567504882812 ,1000.3450317382812 ,795.3567504882812 ,897.042724609375 ,810.6036987304688 ,805.8684692382812 ,789.5177612304688 ,-160.6448974609375 ,-163.46197509765625 ,-166.4710693359375 ,-160.6448974609375 ,-157.5364990234375 ,-163.46197509765625 ,-160.6448974609375 ,-156.4678955078125 ,-157.5364990234375 ,839.9677124023438 ,867.7277221679688 ,903.6100463867188 ,839.9677124023438 ,903.6100463867188 ,785.249267578125 ,874.5257568359375 ,872.126220703125 ,872.2061157226562 ,874.5257568359375 ,868.7754516601562 ,872.126220703125 ,-159.72174072265625 ,-174.0264892578125 ,-106.60688781738281 ,-142.57838439941406 ,-145.12283325195312 ,-131.700927734375 ,-145.12283325195312 ,-142.14691162109375 ,-139.00653076171875 ,-145.12283325195312 ,-139.00653076171875 ,-131.700927734375 ,-131.700927734375 ,-139.00653076171875 ,-129.4573974609375 ,-90.65093231201172 ,-90.04814910888672 ,-86.91287994384766 ,-90.65093231201172 ,-94.73629760742188 ,-90.04814910888672 ,-110.61604309082031 ,-87.17730712890625 ,-93.25747680664062 ,-110.61604309082031 ,-92.81271362304688 ,-87.17730712890625 ,-93.25747680664062 ,-102.13951873779297 ,-110.61604309082031 ,-51.92376708984375 ,-64.88554382324219 ,-58.127685546875 ,1594.73974609375 ,1596.21337890625 ,1589.362060546875 ,1589.362060546875 ,1597.156982421875 ,1597.928955078125 ,1589.362060546875 ,1596.21337890625 ,1597.156982421875 ,787.9410400390625 ,787.8994750976562 ,767.7692260742188 ,807.5975952148438 ,800.7420043945312 ,814.1434326171875 ,847.1500244140625 ,864.621826171875 ,852.0170288085938 ,847.1500244140625 ,859.4566650390625 ,864.621826171875 ,847.1500244140625 ,848.6284790039062 ,859.4566650390625 ,864.621826171875 ,859.4566650390625 ,863.3182373046875 ,844.1985473632812 ,848.0054931640625 ,834.166015625 ,844.1985473632812 ,843.5563354492188 ,848.0054931640625 ,844.1985473632812 ,847.5123291015625 ,843.5563354492188 ,-170.3991241455078 ,-164.23593139648438 ,-168.3688507080078 ,2391.385498046875 ,2119.65625 ,2346.43994140625 ,793.8865356445312 ,797.3441772460938 ,795.3567504882812 ,-140.2585906982422 ,-152.16177368164062 ,-118.78472900390625 ,-120.89374542236328 ,-114.11538696289062 ,-115.13775634765625 ,-120.89374542236328 ,-118.78472900390625 ,-114.11538696289062 ,773.19140625 ,776.2487182617188 ,791.2133178710938 ,1547.5792236328125 ,1551.5625 ,1548.026611328125 ,1547.5792236328125 ,1548.026611328125 ,1544.6461181640625 ,1660.006591796875 ,1661.6192626953125 ,1669.516845703125 ,1660.006591796875 ,1664.8953857421875 ,1661.6192626953125 ,1664.9896240234375 ,1656.087158203125 ,1658.31884765625 ,1664.9896240234375 ,1659.756103515625 ,1656.087158203125 ,1675.08056640625 ,1670.451416015625 ,1675.3055419921875 ,1617.6669921875 ,1626.154296875 ,1630.8304443359375 ,1617.6669921875 ,1604.699951171875 ,1610.2916259765625 ,1617.6669921875 ,1609.5733642578125 ,1604.699951171875 ,1617.6669921875 ,1610.2916259765625 ,1626.154296875 ,1570.8770751953125 ,1577.8319091796875 ,1576.539306640625 ,1645.3931884765625 ,1649.5989990234375 ,1647.38427734375 ,1651.9105224609375 ,1662.08154296875 ,1657.7440185546875 ,1651.9105224609375 ,1651.02587890625 ,1662.08154296875 ,1689.44873046875 ,1688.627197265625 ,1690.560302734375 ,1690.560302734375 ,1688.627197265625 ,1691.265380859375 ,74.95420837402344 ,57.109249114990234 ,8.591601371765137 ,74.95420837402344 ,8.591601371765137 ,2.1524689197540283 ,74.95420837402344 ,70.07876586914062 ,57.109249114990234 ,74.95420837402344 ,74.84351348876953 ,70.07876586914062 ,74.95420837402344 ,49.47584915161133 ,74.84351348876953 ,57.109249114990234 ,70.07876586914062 ,51.06891632080078 ,57.109249114990234 ,51.06891632080078 ,8.591601371765137 ,1645.4649658203125 ,1659.3050537109375 ,1651.02587890625 ,907.8963012695312 ,934.7592163085938 ,943.1953125 ,907.8963012695312 ,925.2911987304688 ,934.7592163085938 ,1475.4910888671875 ,1467.4976806640625 ,1463.5909423828125 ,1475.4910888671875 ,1463.5909423828125 ,1501.1376953125 ,1475.4910888671875 ,1501.1376953125 ,1506.52294921875 ,1467.4976806640625 ,1431.1864013671875 ,1463.5909423828125 ,1467.4976806640625 ,1475.4910888671875 ,1431.1864013671875 ,1463.5909423828125 ,1431.1864013671875 ,1477.014404296875 ,1463.5909423828125 ,1477.014404296875 ,1501.1376953125 ,1630.4327392578125 ,1637.527587890625 ,1640.646728515625 ,1685.5765380859375 ,1684.5247802734375 ,1685.6358642578125 ,1685.5765380859375 ,1685.6358642578125 ,1686.009765625 ,1685.6358642578125 ,1684.5247802734375 ,1678.669921875 ,1597.7860107421875 ,1597.156982421875 ,1596.21337890625 ,757.044189453125 ,742.2379760742188 ,738.90380859375 ,757.044189453125 ,738.90380859375 ,744.73828125 ,-182.18698120117188 ,-194.07723999023438 ,-166.4972381591797 ,-182.18698120117188 ,-166.4972381591797 ,-148.29736328125 ,-182.18698120117188 ,-148.29736328125 ,-133.5084228515625 ,-182.18698120117188 ,-133.5084228515625 ,-182.0306396484375 ,-194.07723999023438 ,-208.4066162109375 ,-171.53567504882812 ,-194.07723999023438 ,-171.53567504882812 ,-166.4972381591797 ,-166.4972381591797 ,-171.53567504882812 ,-148.29736328125 ,175.15267944335938 ,65.91230010986328 ,130.03395080566406 ,1613.9197998046875 ,1627.6866455078125 ,1620.38330078125 ,1613.9197998046875 ,1645.7232666015625 ,1627.6866455078125 ,1567.37890625 ,1554.4915771484375 ,1555.0257568359375 ,1567.37890625 ,1555.0257568359375 ,1559.1688232421875 ,1559.1688232421875 ,1572.697509765625 ,1567.37890625 ,1567.37890625 ,1565.482666015625 ,1554.4915771484375 ,1606.5872802734375 ,1608.4158935546875 ,1608.2562255859375 ,829.4507446289062 ,847.0896606445312 ,1006.2012939453125 ,787.8994750976562 ,775.8414916992188 ,767.7692260742188 ,798.9462280273438 ,787.6688232421875 ,799.7229614257812 ,1028.039306640625 ,1068.9901123046875 ,1072.1270751953125 ,1655.4056396484375 ,1643.8046875 ,1657.7835693359375 ,1655.4056396484375 ,1657.7835693359375 ,1667.8065185546875 ,35.302860260009766 ,65.91230010986328 ,55.59247970581055 ,35.302860260009766 ,130.03395080566406 ,65.91230010986328 ,1548.560302734375 ,1553.962646484375 ,1543.2904052734375 ,-29.316699981689453 ,-44.69572830200195 ,-3.633512020111084 ,1575.04296875 ,1555.5660400390625 ,1578.07763671875 ,1613.0711669921875 ,1608.5009765625 ,1599.9251708984375 ,1613.0711669921875 ,1612.751220703125 ,1623.382568359375 ,1668.779541015625 ,1666.97705078125 ,1666.6029052734375 ,1687.320068359375 ,1683.0172119140625 ,1687.1873779296875 ,1682.7294921875 ,1681.5421142578125 ,1682.6153564453125 ,1681.5421142578125 ,1680.8697509765625 ,1682.6153564453125 ,1681.5421142578125 ,1682.7294921875 ,1680.8697509765625 ,1682.6153564453125 ,1680.8697509765625 ,1679.267333984375 ,1650.67578125 ,1646.9783935546875 ,1653.3548583984375 ,1270.929931640625 ,1230.4781494140625 ,847.0896606445312 ,1270.929931640625 ,847.0896606445312 ,979.4857177734375 ,1595.8814697265625 ,1692.1318359375 ,1598.534423828125 ,893.1461791992188 ,822.512939453125 ,748.1673583984375 ,893.1461791992188 ,979.4857177734375 ,822.512939453125 ,893.1461791992188 ,961.9600830078125 ,979.4857177734375 ,822.512939453125 ,754.551025390625 ,748.1673583984375 ,822.512939453125 ,709.1033325195312 ,754.551025390625 ,752.9854125976562 ,761.7636108398438 ,754.792236328125 ,752.9854125976562 ,750.8538208007812 ,757.1332397460938 ,752.9854125976562 ,757.1332397460938 ,761.7636108398438 ,754.792236328125 ,761.7636108398438 ,787.9410400390625 ,826.7001342773438 ,836.3881225585938 ,839.0542602539062 ,1548.8284912109375 ,1561.04443359375 ,1548.9468994140625 ,1574.3280029296875 ,1566.0189208984375 ,1565.9283447265625 ,1574.3280029296875 ,1564.7724609375 ,1566.0189208984375 ,1574.3280029296875 ,1577.078125 ,1564.7724609375 ,1646.806640625 ,1651.7899169921875 ,1640.5447998046875 ,1646.806640625 ,1645.72412109375 ,1654.5584716796875 ,1646.806640625 ,1654.5584716796875 ,1651.7899169921875 ,1666.7664794921875 ,1664.8988037109375 ,1668.416259765625 ,1666.7664794921875 ,1664.9874267578125 ,1664.8988037109375 ,1641.6319580078125 ,1637.6385498046875 ,1650.67578125 ,1641.6319580078125 ,1650.67578125 ,1646.7701416015625 ,1637.6385498046875 ,1646.9783935546875 ,1650.67578125 ,1637.6385498046875 ,1637.099853515625 ,1646.9783935546875 ,1628.7613525390625 ,1622.7889404296875 ,1616.6317138671875 ,1628.7613525390625 ,1616.6317138671875 ,1623.7159423828125 ,673.9083251953125 ,723.9375610351562 ,625.8710327148438 ,673.9083251953125 ,725.7775268554688 ,723.9375610351562 ,725.7775268554688 ,687.5601806640625 ,717.6525268554688 ,725.7775268554688 ,673.9083251953125 ,687.5601806640625 ,725.7775268554688 ,733.4481811523438 ,723.9375610351562 ,-145.7958221435547 ,-151.15257263183594 ,-150.48141479492188 ,1583.3828125 ,1583.74853515625 ,1586.105712890625 ,1583.3828125 ,1578.2080078125 ,1583.74853515625 ,-84.93722534179688 ,-84.05589294433594 ,-24.251636505126953 ,-84.93722534179688 ,-24.251636505126953 ,70.94438171386719 ,-24.251636505126953 ,-84.05589294433594 ,-51.09827423095703 ,1690.1962890625 ,1517.98193359375 ,1578.2552490234375 ,1517.98193359375 ,1690.1962890625 ,1718.588134765625 ,1517.98193359375 ,1718.588134765625 ,1616.56201171875 ,726.071044921875 ,723.6242065429688 ,725.346923828125 ,726.071044921875 ,725.346923828125 ,716.6488647460938 ,726.071044921875 ,721.634765625 ,723.6242065429688 ,726.071044921875 ,716.6488647460938 ,721.634765625 ,723.6242065429688 ,721.634765625 ,728.3058471679688 ,725.346923828125 ,729.0462646484375 ,727.1863403320312 ,725.346923828125 ,723.6242065429688 ,729.0462646484375 ,729.0462646484375 ,723.6242065429688 ,746.5005493164062 ,-101.66226959228516 ,-93.75887298583984 ,-101.7322006225586 ,1676.946533203125 ,1631.4007568359375 ,1663.065185546875 ,1676.946533203125 ,1600.6480712890625 ,1631.4007568359375 ,1631.4007568359375 ,1579.073974609375 ,1663.065185546875 ,1631.4007568359375 ,1600.6480712890625 ,1579.073974609375 ,1663.065185546875 ,1579.073974609375 ,1526.1451416015625 ,1663.065185546875 ,1526.1451416015625 ,1652.356201171875 ,1488.171630859375 ,1581.4505615234375 ,1555.284912109375 ,779.3375244140625 ,786.6719970703125 ,790.4133911132812 ,779.3375244140625 ,790.4133911132812 ,793.9613037109375 ,1556.9329833984375 ,1581.4505615234375 ,1494.3138427734375 ,842.852294921875 ,854.6092529296875 ,862.65185546875 ,842.852294921875 ,862.65185546875 ,836.5758666992188 ,842.852294921875 ,816.103271484375 ,803.7413940429688 ,842.852294921875 ,836.5758666992188 ,816.103271484375 ,1696.6854248046875 ,1649.6490478515625 ,1614.8197021484375 ,1696.6854248046875 ,1614.8197021484375 ,1539.79345703125 ,1523.0828857421875 ,1494.3138427734375 ,1555.0970458984375 ,1312.385986328125 ,1043.316162109375 ,1428.7633056640625 ,807.87060546875 ,782.33935546875 ,773.22314453125 ,807.87060546875 ,790.466796875 ,782.33935546875 ,807.87060546875 ,773.22314453125 ,777.0872802734375 ,297.4990234375 ,229.74269104003906 ,249.11463928222656 ,297.4990234375 ,225.9130401611328 ,229.74269104003906 ,297.4990234375 ,346.9749755859375 ,225.9130401611328 ,2346.43994140625 ,2009.0777587890625 ,2293.187255859375 ,865.3997802734375 ,883.9874877929688 ,804.3577270507812 ,865.3997802734375 ,885.4091796875 ,883.9874877929688 ,865.3997802734375 ,832.0707397460938 ,885.4091796875 ,883.9874877929688 ,890.6671752929688 ,804.3577270507812 ,791.40380859375 ,789.9561767578125 ,773.22314453125 ,1565.3388671875 ,1575.6142578125 ,1557.9974365234375 ,1565.3388671875 ,1557.9974365234375 ,1560.262451171875 ,1557.9974365234375 ,1575.6142578125 ,1567.23486328125 ,14.917814254760742 ,-24.25218963623047 ,8.798081398010254 ,8.798081398010254 ,79.7586669921875 ,14.917814254760742 ,53.96044158935547 ,212.82652282714844 ,466.0267333984375 ,53.96044158935547 ,466.0267333984375 ,192.3759765625 ,53.96044158935547 ,192.3759765625 ,7.397647857666016 ,1636.0416259765625 ,1638.23876953125 ,1637.9412841796875 ,1636.0416259765625 ,1633.53369140625 ,1638.23876953125 ,1630.1005859375 ,1625.792724609375 ,1627.7117919921875 ,1630.1005859375 ,1627.7117919921875 ,1637.7620849609375 ,1548.026611328125 ,1555.912109375 ,1550.6932373046875 ,1548.026611328125 ,1564.7476806640625 ,1555.912109375 ,1548.026611328125 ,1551.5625 ,1556.6446533203125 ,1548.026611328125 ,1556.6446533203125 ,1564.7476806640625 ,1600.574462890625 ,1608.5126953125 ,1607.9539794921875 ,1600.574462890625 ,1607.9539794921875 ,1599.3277587890625 ,1610.2916259765625 ,1616.628173828125 ,1626.154296875 ,50.2431755065918 ,39.25868225097656 ,-49.12808609008789 ,50.2431755065918 ,60.37742233276367 ,39.25868225097656 ,39.25868225097656 ,84.98744201660156 ,81.85726165771484 ,39.25868225097656 ,60.37742233276367 ,84.98744201660156 ,39.25868225097656 ,81.85726165771484 ,-49.12808609008789 ,1645.790283203125 ,1642.681396484375 ,1643.9893798828125 ,1645.790283203125 ,1647.38427734375 ,1642.681396484375 ,1594.7960205078125 ,1597.1424560546875 ,1592.21435546875 ,1541.7872314453125 ,1552.5557861328125 ,1546.934814453125 ,1537.8978271484375 ,1541.7872314453125 ,1541.107177734375 ,1645.533203125 ,1643.3203125 ,1630.8231201171875 ,1645.533203125 ,1630.8231201171875 ,1631.4022216796875 ,1662.50830078125 ,1660.1500244140625 ,1662.3084716796875 ,1662.50830078125 ,1662.3084716796875 ,1663.9632568359375 ,1662.50830078125 ,1663.9632568359375 ,1666.2528076171875 ,1662.50830078125 ,1666.2528076171875 ,1667.6202392578125 ,1677.809814453125 ,1668.092529296875 ,1674.4515380859375 ,1668.092529296875 ,1668.141357421875 ,1674.4515380859375 ,1668.092529296875 ,1664.110107421875 ,1668.141357421875 ,561.6047973632812 ,577.8530883789062 ,661.638916015625 ,561.6047973632812 ,661.638916015625 ,590.23095703125 ,1593.195068359375 ,1574.923828125 ,1596.00439453125 ,1669.1170654296875 ,1667.6173095703125 ,1668.46630859375 ,1455.574462890625 ,1436.84033203125 ,1406.17626953125 ,1523.1141357421875 ,1474.0537109375 ,1465.8497314453125 ,1523.1141357421875 ,1465.8497314453125 ,1534.2867431640625 ,1465.8497314453125 ,1511.5054931640625 ,1534.2867431640625 ,1847.626220703125 ,1798.1724853515625 ,1833.514404296875 ,1523.0828857421875 ,1487.403564453125 ,1556.9329833984375 ,-115.13775634765625 ,-114.11538696289062 ,-103.92625427246094 ,-115.13775634765625 ,-103.92625427246094 ,-109.54987335205078 ,1653.60546875 ,1656.8359375 ,1660.2691650390625 ,1547.5792236328125 ,1552.570556640625 ,1554.7137451171875 ,1547.5792236328125 ,1554.7137451171875 ,1551.5625 ,1552.570556640625 ,1555.5306396484375 ,1557.3426513671875 ,1552.570556640625 ,1557.3426513671875 ,1554.7137451171875 ,1554.7137451171875 ,1556.6446533203125 ,1551.5625 ,1608.5126953125 ,1609.5733642578125 ,1617.8865966796875 ,1608.5126953125 ,1617.8865966796875 ,1607.9539794921875 ,1608.5126953125 ,1597.1424560546875 ,1609.5733642578125 ,1651.5751953125 ,1658.034912109375 ,1648.0936279296875 ,1651.5751953125 ,1656.557861328125 ,1658.034912109375 ,1656.557861328125 ,1659.63916015625 ,1658.034912109375 ,757.044189453125 ,755.9078369140625 ,742.2379760742188 ,639.5640869140625 ,664.9578857421875 ,648.278564453125 ,1608.282958984375 ,1600.1275634765625 ,1613.71533203125 ,1613.0711669921875 ,1627.1104736328125 ,1624.34375 ,1570.5435791015625 ,1579.202392578125 ,1578.88525390625 ,1570.5435791015625 ,1578.88525390625 ,1574.4034423828125 ,1570.5435791015625 ,1566.4603271484375 ,1577.1654052734375 ,1570.5435791015625 ,1577.1654052734375 ,1579.202392578125 ,1489.771728515625 ,1492.576904296875 ,1494.8699951171875 ,1545.984375 ,1538.773681640625 ,1600.99267578125 ,1545.984375 ,1602.4049072265625 ,1540.01904296875 ,1651.218505859375 ,1653.57763671875 ,1657.4315185546875 ,1527.1690673828125 ,1439.11962890625 ,1441.8394775390625 ,1527.1690673828125 ,1441.8394775390625 ,1520.814453125 ,1527.1690673828125 ,1523.725830078125 ,1439.11962890625 ,1439.11962890625 ,1523.725830078125 ,1455.2423095703125 ,1441.8394775390625 ,1475.1905517578125 ,1520.814453125 ,1426.50927734375 ,1801.1998291015625 ,1491.1573486328125 ,1658.31884765625 ,1652.9853515625 ,1660.006591796875 ,1573.0107421875 ,1572.697509765625 ,1567.9937744140625 ,1572.697509765625 ,1573.0107421875 ,1570.904541015625 ,1601.0672607421875 ,1601.5650634765625 ,1600.988525390625 ,1601.854736328125 ,1599.591064453125 ,1600.544921875 ,1601.0672607421875 ,1601.854736328125 ,1601.5650634765625 ,1639.492919921875 ,1636.418212890625 ,1641.852294921875 ,1608.5009765625 ,1595.2420654296875 ,1599.9251708984375 ,855.8199462890625 ,852.9420166015625 ,850.8707275390625 ,855.8199462890625 ,855.2047119140625 ,852.9420166015625 ,855.8199462890625 ,849.9226684570312 ,855.2047119140625 ,855.8199462890625 ,850.2197875976562 ,849.9226684570312 ,-159.6973876953125 ,-154.16233825683594 ,-155.86891174316406 ,25.46628189086914 ,57.19397735595703 ,-98.51581573486328 ,25.46628189086914 ,38.04579162597656 ,57.19397735595703 ,57.19397735595703 ,-119.19314575195312 ,-98.51581573486328 ,1846.568603515625 ,886.9500732421875 ,1000.3450317382812 ,1846.568603515625 ,1000.3450317382812 ,1726.457275390625 ,-163.46197509765625 ,-157.5364990234375 ,-157.58616638183594 ,-163.46197509765625 ,-157.58616638183594 ,-162.77415466308594 ,-163.46197509765625 ,-162.77415466308594 ,-166.4710693359375 ,856.3151245117188 ,912.0824584960938 ,835.4879760742188 ,856.3151245117188 ,894.9439086914062 ,912.0824584960938 ,-134.7921905517578 ,-137.98291015625 ,-135.33396911621094 ,-134.7921905517578 ,-132.94859313964844 ,-132.725341796875 ,1550.7193603515625 ,1551.9730224609375 ,1558.3780517578125 ,1618.046630859375 ,1634.7216796875 ,1644.2154541015625 ,1634.7216796875 ,1638.5665283203125 ,1644.2154541015625 ,1656.087158203125 ,1656.8359375 ,1651.05126953125 ,1656.087158203125 ,1659.756103515625 ,1656.8359375 ,1604.699951171875 ,1609.5733642578125 ,1600.057861328125 ,1672.9698486328125 ,1662.9295654296875 ,1681.4715576171875 ,1672.9698486328125 ,1660.8126220703125 ,1662.9295654296875 ,1672.9698486328125 ,1681.4715576171875 ,1678.9876708984375 ,1672.9698486328125 ,1678.9876708984375 ,1672.689208984375 ,1623.7742919921875 ,1620.9952392578125 ,1611.4110107421875 ,1575.8009033203125 ,1590.8773193359375 ,1556.5546875 ,706.0634765625 ,933.3903198242188 ,792.0645141601562 ,1679.4403076171875 ,1682.325927734375 ,1675.5518798828125 ,1648.0313720703125 ,1651.9884033203125 ,1650.967041015625 ,1648.0313720703125 ,1650.967041015625 ,1645.1719970703125 ,855.8199462890625 ,848.3840942382812 ,850.2197875976562 ,855.8199462890625 ,843.2396240234375 ,848.3840942382812 ,855.8199462890625 ,843.6236572265625 ,843.2396240234375 ,855.8199462890625 ,853.600830078125 ,843.6236572265625 ,848.3840942382812 ,843.2396240234375 ,848.0054931640625 ,1637.9412841796875 ,1642.2862548828125 ,1642.71826171875 ,1637.9412841796875 ,1642.71826171875 ,1638.38623046875 ,1194.105224609375 ,1375.368896484375 ,1156.853515625 ,1194.105224609375 ,1156.853515625 ,1135.334228515625 ,1194.105224609375 ,1135.334228515625 ,1154.2872314453125 ,1194.105224609375 ,1315.204833984375 ,1375.368896484375 ,1194.105224609375 ,1154.2872314453125 ,1315.204833984375 ,647.0407104492188 ,552.5986328125 ,604.1659545898438 ,647.0407104492188 ,604.1659545898438 ,816.103271484375 ,552.5986328125 ,452.7947692871094 ,604.1659545898438 ,-116.95503997802734 ,-101.84134674072266 ,-128.61953735351562 ,-116.95503997802734 ,-93.7981948852539 ,-101.84134674072266 ,-128.61953735351562 ,-101.84134674072266 ,-114.91108703613281 ,778.7959594726562 ,785.9707641601562 ,783.1329956054688 ,783.1329956054688 ,777.6443481445312 ,778.7959594726562 ,778.7959594726562 ,777.6443481445312 ,773.294677734375 ,22.273630142211914 ,-0.7145509719848633 ,4.284152984619141 ,22.273630142211914 ,21.5523624420166 ,-0.7145509719848633 ,4.284152984619141 ,-0.7145509719848633 ,2.2539000511169434 ,4.284152984619141 ,2.2539000511169434 ,22.273630142211914 ,911.580078125 ,1014.3953247070312 ,941.419921875 ,941.419921875 ,882.2884521484375 ,911.580078125 ,1775.8941650390625 ,1833.514404296875 ,1798.1724853515625 ,1775.8941650390625 ,1727.8466796875 ,1833.514404296875 ,1565.3388671875 ,1575.1865234375 ,1575.6142578125 ,1565.3388671875 ,1564.0841064453125 ,1575.1865234375 ,1565.3388671875 ,1553.8087158203125 ,1564.0841064453125 ,1565.3388671875 ,1560.262451171875 ,1553.8087158203125 ,1660.6507568359375 ,1669.6060791015625 ,1664.745849609375 ,1669.6060791015625 ,1660.6507568359375 ,1671.44140625 ,1567.5185546875 ,1569.1812744140625 ,1590.896484375 ,1567.5185546875 ,1590.896484375 ,1593.3319091796875 ,1567.5185546875 ,1566.099365234375 ,1569.1812744140625 ,1651.0067138671875 ,1661.302978515625 ,1665.4837646484375 ,745.8952026367188 ,739.1737060546875 ,739.649169921875 ,745.8952026367188 ,750.8538208007812 ,747.1206665039062 ,745.8952026367188 ,739.649169921875 ,750.8538208007812 ,739.1737060546875 ,710.6922607421875 ,723.9375610351562 ,739.1737060546875 ,723.9375610351562 ,739.649169921875 ,1558.8492431640625 ,1548.560302734375 ,1558.0872802734375 ,800.3818359375 ,791.2133178710938 ,846.9815063476562 ,1592.45556640625 ,1598.22265625 ,1589.130126953125 ,1589.130126953125 ,1585.578369140625 ,1592.45556640625 ,1577.423583984375 ,1571.6690673828125 ,1589.8682861328125 ,1577.423583984375 ,1589.8682861328125 ,1587.8934326171875 ,1571.6690673828125 ,1599.9283447265625 ,1589.8682861328125 ,1587.8934326171875 ,1607.81689453125 ,1600.77587890625 ,1626.034912109375 ,1627.227294921875 ,1618.046630859375 ,1618.046630859375 ,1603.496337890625 ,1617.992431640625 ,1672.2923583984375 ,1660.6507568359375 ,1667.7757568359375 ,1672.2923583984375 ,1667.7757568359375 ,1674.808837890625 ,1643.9544677734375 ,1644.7115478515625 ,1651.05126953125 ,1634.888916015625 ,1641.365966796875 ,1639.4248046875 ,1641.365966796875 ,1643.419677734375 ,1639.4248046875 ,1599.0076904296875 ,1589.208251953125 ,1590.354248046875 ,1599.0076904296875 ,1590.354248046875 ,1604.0233154296875 ,1599.0076904296875 ,1604.0233154296875 ,1615.1766357421875 ,1599.0076904296875 ,1595.2818603515625 ,1589.208251953125 ,1556.0623779296875 ,1563.65771484375 ,1555.5306396484375 ,1534.9771728515625 ,1532.6363525390625 ,1537.858642578125 ,1534.9771728515625 ,1537.4833984375 ,1532.6363525390625 ,1534.9771728515625 ,1537.7679443359375 ,1532.41796875 ,1621.833984375 ,1615.5350341796875 ,1626.644287109375 ,1660.6507568359375 ,1672.2923583984375 ,1671.44140625 ,1671.44140625 ,1678.28515625 ,1669.6060791015625 ,1663.8935546875 ,1666.7978515625 ,1657.4427490234375 ,1663.8935546875 ,1657.4427490234375 ,1659.263916015625 ,1663.8935546875 ,1670.4793701171875 ,1670.451416015625 ,1663.8935546875 ,1670.451416015625 ,1666.7978515625 ,1663.8935546875 ,1659.263916015625 ,1670.4793701171875 ,1563.18798828125 ,1460.7689208984375 ,1543.3221435546875 ,1563.18798828125 ,1477.02099609375 ,1460.7689208984375 ,1543.3221435546875 ,1460.7689208984375 ,1476.919677734375 ,1061.62109375 ,1018.4519653320312 ,975.66455078125 ,1580.0263671875 ,1569.8341064453125 ,1582.6365966796875 ,1600.988525390625 ,1601.5650634765625 ,1602.3759765625 ,1596.012939453125 ,1594.9661865234375 ,1590.8773193359375 ,1590.8773193359375 ,1594.9661865234375 ,1556.5546875 ,1504.6903076171875 ,1575.8009033203125 ,1556.5546875 ,1504.6903076171875 ,1556.5546875 ,1387.4476318359375 ,756.6593627929688 ,778.0476684570312 ,542.66552734375 ,-72.85733032226562 ,-22.468109130859375 ,-51.09827423095703 ,-72.85733032226562 ,-51.09827423095703 ,-84.05589294433594 ,1679.259033203125 ,1682.7294921875 ,1684.1480712890625 ,1499.37890625 ,1395.549560546875 ,1487.9423828125 ,1608.282958984375 ,1596.677001953125 ,1589.683349609375 ,1608.282958984375 ,1593.351806640625 ,1600.1275634765625 ,1608.282958984375 ,1589.683349609375 ,1593.351806640625 ,1596.677001953125 ,1584.0416259765625 ,1589.683349609375 ,1621.678955078125 ,1623.9122314453125 ,1604.6942138671875 ,1674.4515380859375 ,1668.141357421875 ,1669.38330078125 ,1669.38330078125 ,1668.141357421875 ,1652.837646484375 ,1661.281982421875 ,1664.8988037109375 ,1664.9874267578125 ,1661.281982421875 ,1658.734619140625 ,1664.8988037109375 ,797.864990234375 ,794.5354614257812 ,789.9561767578125 ,797.864990234375 ,791.40380859375 ,804.38037109375 ,25.46628189086914 ,-88.27867126464844 ,5.809103965759277 ,25.46628189086914 ,-98.51581573486328 ,-88.27867126464844 ,810.6036987304688 ,812.1361083984375 ,829.6168212890625 ,810.6036987304688 ,829.6168212890625 ,805.8684692382812 ,1555.912109375 ,1564.7476806640625 ,1566.90966796875 ,1550.6932373046875 ,1537.858642578125 ,1548.026611328125 ,1574.271484375 ,1581.4888916015625 ,1571.6690673828125 ,1581.4888916015625 ,1599.9283447265625 ,1571.6690673828125 ,1616.805419921875 ,1599.0076904296875 ,1615.1766357421875 ,1616.805419921875 ,1595.2818603515625 ,1599.0076904296875 ,1615.1766357421875 ,1636.14453125 ,1616.805419921875 ,1605.6170654296875 ,1604.4390869140625 ,1600.896484375 ,1604.4390869140625 ,1608.6029052734375 ,1601.1868896484375 ,1426.2479248046875 ,1387.4476318359375 ,1384.2012939453125 ,-3.2561590671539307 ,-106.98082733154297 ,-48.15782165527344 ,1664.110107421875 ,1652.837646484375 ,1668.141357421875 ,1664.110107421875 ,1659.33349609375 ,1652.837646484375 ,1676.400634765625 ,1680.744873046875 ,1679.02587890625 ,1676.400634765625 ,1680.2239990234375 ,1680.744873046875 ,1684.2529296875 ,1685.66845703125 ,1685.751220703125 ,1693.1881103515625 ,1689.44873046875 ,1691.7314453125 ,1602.3759765625 ,1602.937255859375 ,1603.8221435546875 ,1602.3759765625 ,1601.5650634765625 ,1602.937255859375 ,1651.218505859375 ,1653.60546875 ,1653.57763671875 ,8.591601371765137 ,50.2431755065918 ,-9.448720932006836 ,-9.448720932006836 ,50.2431755065918 ,-22.31652069091797 ,8.591601371765137 ,-3.5637929439544678 ,-34.57811737060547 ,8.591601371765137 ,-9.448720932006836 ,-3.5637929439544678 ,1572.86376953125 ,1577.1654052734375 ,1566.4603271484375 ,1880.57177734375 ,1819.286376953125 ,1760.213623046875 ,1760.213623046875 ,1819.286376953125 ,1744.6837158203125 ,1600.8250732421875 ,1597.5272216796875 ,1598.179443359375 ,1578.15625 ,1593.12060546875 ,1586.9632568359375 ,1587.8934326171875 ,1601.041015625 ,1579.9024658203125 ,1587.8934326171875 ,1600.77587890625 ,1601.041015625 ,1589.8682861328125 ,1593.3438720703125 ,1607.81689453125 ,1589.8682861328125 ,1607.81689453125 ,1587.8934326171875 ,1581.4888916015625 ,1600.038330078125 ,1599.9283447265625 ,1657.4315185546875 ,1659.8006591796875 ,1652.6387939453125 ,1657.4315185546875 ,1652.6387939453125 ,1651.218505859375 ,1653.9466552734375 ,1645.1536865234375 ,1670.7144775390625 ,1653.9466552734375 ,1670.7144775390625 ,1664.204345703125 ,1653.9466552734375 ,1635.6138916015625 ,1645.1536865234375 ,1653.9466552734375 ,1636.14453125 ,1635.6138916015625 ,1653.9466552734375 ,1664.204345703125 ,1636.14453125 ,43.552696228027344 ,40.656192779541016 ,49.47584915161133 ,-41.43098068237305 ,-2.8962490558624268 ,-25.64232063293457 ,1600.77587890625 ,1607.81689453125 ,1601.041015625 ,1607.81689453125 ,1612.3529052734375 ,1601.041015625 ,1607.81689453125 ,1615.5350341796875 ,1612.3529052734375 ,1645.9932861328125 ,1644.7115478515625 ,1638.5103759765625 ,1666.7978515625 ,1666.320068359375 ,1664.548095703125 ,1666.7978515625 ,1664.548095703125 ,1662.6409912109375 ,1666.7978515625 ,1662.6409912109375 ,1657.4427490234375 ,-129.30104064941406 ,-146.49044799804688 ,-130.52609252929688 ,-129.30104064941406 ,-131.70802307128906 ,-138.11817932128906 ,-129.30104064941406 ,-138.11817932128906 ,-137.9761505126953 ,14.137516021728516 ,-48.63685607910156 ,6.3370041847229 ,943.5916137695312 ,934.7592163085938 ,927.310791015625 ,1580.0263671875 ,1565.7703857421875 ,1569.8341064453125 ,1597.928955078125 ,1609.713134765625 ,1596.8861083984375 ,1597.928955078125 ,1598.9300537109375 ,1609.713134765625 ,1597.928955078125 ,1596.8861083984375 ,1589.362060546875 ,1018.4519653320312 ,986.6577758789062 ,975.66455078125 ,1601.854736328125 ,1601.251953125 ,1601.9359130859375 ,1601.854736328125 ,1601.9359130859375 ,1601.5650634765625 ,1601.854736328125 ,1601.023681640625 ,1601.906982421875 ,1601.854736328125 ,1601.906982421875 ,1601.251953125 ,28.987707138061523 ,-6.674344062805176 ,4.923157215118408 ,28.987707138061523 ,4.923157215118408 ,67.66964721679688 ,28.987707138061523 ,67.66964721679688 ,43.1501350402832 ,28.987707138061523 ,14.08456802368164 ,-6.674344062805176 ,1578.07763671875 ,1580.8135986328125 ,1566.546630859375 ,1683.33642578125 ,1677.809814453125 ,1677.3021240234375 ,1666.97705078125 ,1657.2647705078125 ,1666.6029052734375 ,1678.3294677734375 ,1671.78515625 ,1681.4793701171875 ,1680.2239990234375 ,1677.0831298828125 ,1681.99755859375 ,1680.2239990234375 ,1681.99755859375 ,1680.744873046875 ,723.9375610351562 ,710.6922607421875 ,625.8710327148438 ,625.8710327148438 ,710.6922607421875 ,546.88916015625 ,1583.048095703125 ,1588.25830078125 ,1587.4739990234375 ,1583.048095703125 ,1587.4739990234375 ,1580.8135986328125 ,1575.1566162109375 ,1574.396240234375 ,1584.7598876953125 ,1575.1566162109375 ,1571.10107421875 ,1574.396240234375 ,1604.6942138671875 ,1601.7042236328125 ,1621.678955078125 ,1604.6942138671875 ,1584.7598876953125 ,1601.7042236328125 ,1651.7899169921875 ,1647.4063720703125 ,1640.5447998046875 ,1651.7899169921875 ,1655.194580078125 ,1647.4063720703125 ,1668.600830078125 ,1652.837646484375 ,1657.2647705078125 ,1680.744873046875 ,1683.382080078125 ,1679.02587890625 ,1680.744873046875 ,1681.99755859375 ,1683.382080078125 ,723.9375610351562 ,733.4481811523438 ,739.649169921875 ,798.1160888671875 ,778.3762817382812 ,785.5821533203125 ,1474.0537109375 ,1523.1141357421875 ,1564.2630615234375 ,1474.0537109375 ,1564.2630615234375 ,1487.9423828125 ,1564.2630615234375 ,1516.1270751953125 ,1487.9423828125 ,1632.698974609375 ,1617.8851318359375 ,1626.0413818359375 ,1632.698974609375 ,1657.7835693359375 ,1643.8046875 ,1632.698974609375 ,1626.0413818359375 ,1657.7835693359375 ,1657.05810546875 ,1604.458251953125 ,1680.8619384765625 ,1657.05810546875 ,1680.8619384765625 ,1740.9375 ,1657.05810546875 ,1740.9375 ,1625.0286865234375 ,1657.05810546875 ,1625.0286865234375 ,1593.2496337890625 ,1657.05810546875 ,1593.2496337890625 ,1604.458251953125 ,1568.8011474609375 ,1630.985595703125 ,1827.9642333984375 ,1652.356201171875 ,1526.1451416015625 ,1551.97705078125 ,1999.923828125 ,1950.8538818359375 ,1880.57177734375 ,1622.8790283203125 ,1491.1573486328125 ,1801.1998291015625 ,1555.0970458984375 ,1494.3138427734375 ,1549.762451171875 ,1692.2557373046875 ,1759.4949951171875 ,1640.898193359375 ,1692.2557373046875 ,1766.5675048828125 ,1759.4949951171875 ,1692.2557373046875 ,1640.898193359375 ,1656.7720947265625 ,1692.2557373046875 ,1750.3934326171875 ,1766.5675048828125 ,1692.2557373046875 ,1712.3887939453125 ,1750.3934326171875 ,1692.2557373046875 ,1656.7720947265625 ,1712.3887939453125 ,1759.4949951171875 ,1728.110595703125 ,1640.898193359375 ,1640.898193359375 ,1728.110595703125 ,1537.597900390625 ,1640.898193359375 ,1537.597900390625 ,1656.7720947265625 ,-157.58616638183594 ,-158.0950469970703 ,-162.77415466308594 ,-142.14691162109375 ,-137.97515869140625 ,-139.00653076171875 ,-142.14691162109375 ,-142.8347930908203 ,-137.97515869140625 ,-142.14691162109375 ,-145.12283325195312 ,-142.8347930908203 ,-145.12283325195312 ,-140.21238708496094 ,-142.8347930908203 ,-139.00653076171875 ,-110.61604309082031 ,-129.4573974609375 ,-139.00653076171875 ,-137.97515869140625 ,-110.61604309082031 ,-111.19154357910156 ,-118.4346923828125 ,-110.61604309082031 ,-118.4346923828125 ,-111.19154357910156 ,-119.94938659667969 ,-118.4346923828125 ,-119.94938659667969 ,-129.4573974609375 ,-118.4346923828125 ,-129.4573974609375 ,-110.61604309082031 ,694.2725830078125 ,647.1498413085938 ,688.91357421875 ,694.2725830078125 ,688.91357421875 ,738.90380859375 ,694.2725830078125 ,738.90380859375 ,647.1498413085938 ,688.91357421875 ,647.1498413085938 ,721.9412841796875 ,1548.026611328125 ,1537.858642578125 ,1544.6461181640625 ,1600.038330078125 ,1581.4888916015625 ,1614.396728515625 ,1600.038330078125 ,1607.0042724609375 ,1599.9283447265625 ,1600.038330078125 ,1618.32177734375 ,1613.982666015625 ,1600.038330078125 ,1613.982666015625 ,1607.0042724609375 ,1626.034912109375 ,1632.9971923828125 ,1627.227294921875 ,1652.9178466796875 ,1645.7117919921875 ,1642.1343994140625 ,1645.7117919921875 ,1652.9178466796875 ,1664.5697021484375 ,1663.33984375 ,1664.8310546875 ,1667.665283203125 ,1691.0614013671875 ,1691.605712890625 ,1692.1171875 ,1691.0614013671875 ,1690.4541015625 ,1691.605712890625 ,1595.2818603515625 ,1585.5823974609375 ,1589.208251953125 ,1595.2818603515625 ,1576.927001953125 ,1585.5823974609375 ,1626.644287109375 ,1632.9971923828125 ,1621.833984375 ,1298.5340576171875 ,1337.581787109375 ,1317.367431640625 ,1298.5340576171875 ,1272.394287109375 ,1337.581787109375 ,1317.367431640625 ,1337.581787109375 ,1370.767333984375 ,1317.367431640625 ,1370.767333984375 ,1460.7689208984375 ,1605.6170654296875 ,1605.64599609375 ,1613.7576904296875 ,755.9078369140625 ,891.99853515625 ,881.7615966796875 ,1076.6728515625 ,1012.0601196289062 ,1038.2100830078125 ,1076.6728515625 ,996.065185546875 ,1012.0601196289062 ,1558.611572265625 ,1567.772216796875 ,1563.7801513671875 ,1659.3795166015625 ,1654.3341064453125 ,1654.9130859375 ,1654.3341064453125 ,1653.2147216796875 ,1654.9130859375 ,943.1953125 ,934.7592163085938 ,952.6613159179688 ,1665.4837646484375 ,1664.2130126953125 ,1656.165283203125 ,1647.9464111328125 ,1623.9122314453125 ,1660.8126220703125 ,1647.9464111328125 ,1660.7340087890625 ,1638.8861083984375 ,1647.9464111328125 ,1638.8861083984375 ,1623.9122314453125 ,1654.9130859375 ,1647.1204833984375 ,1648.6241455078125 ,1636.418212890625 ,1639.492919921875 ,1631.2967529296875 ,1600.99267578125 ,1538.773681640625 ,1602.775390625 ,826.8889770507812 ,596.9385375976562 ,616.7412109375 ,596.9385375976562 ,592.302978515625 ,616.7412109375 ,616.7412109375 ,655.33544921875 ,826.8889770507812 ,847.5123291015625 ,865.5841674804688 ,859.4566650390625 ,865.5841674804688 ,863.3182373046875 ,859.4566650390625 ,1589.0775146484375 ,1589.48583984375 ,1588.2427978515625 ,1589.48583984375 ,1589.0775146484375 ,1590.1669921875 ,1570.0733642578125 ,1571.1533203125 ,1561.3687744140625 ,1570.0733642578125 ,1571.789794921875 ,1571.1533203125 ,1573.8773193359375 ,1575.0830078125 ,1583.346435546875 ,1573.8773193359375 ,1565.9283447265625 ,1575.0830078125 ,1612.751220703125 ,1613.0711669921875 ,1599.9251708984375 ,1675.341064453125 ,1672.3841552734375 ,1675.5518798828125 ,1675.341064453125 ,1672.285888671875 ,1672.3841552734375 ,1487.9423828125 ,1516.1270751953125 ,1499.37890625 ,1623.39892578125 ,1624.4599609375 ,1608.6427001953125 ,1601.3533935546875 ,1608.6427001953125 ,1613.6981201171875 ,1613.6981201171875 ,1608.6427001953125 ,1624.4599609375 ,1613.6981201171875 ,1624.4599609375 ,1637.7955322265625 ,1550.103271484375 ,1548.9468994140625 ,1548.867919921875 ,1553.962646484375 ,1555.5660400390625 ,1543.2904052734375 ,1579.202392578125 ,1589.28662109375 ,1578.88525390625 ,1600.1275634765625 ,1593.351806640625 ,1594.8846435546875 ,1584.0416259765625 ,1596.677001953125 ,1596.00439453125 ,1584.0416259765625 ,1579.477783203125 ,1589.683349609375 ,1601.7042236328125 ,1584.7598876953125 ,1595.2420654296875 ,1645.72412109375 ,1659.33349609375 ,1654.5584716796875 ,1645.72412109375 ,1652.837646484375 ,1659.33349609375 ,1654.5584716796875 ,1664.110107421875 ,1651.7899169921875 ,1654.5584716796875 ,1659.33349609375 ,1664.110107421875 ,732.1451416015625 ,706.3660278320312 ,743.750244140625 ,840.1779174804688 ,848.3840942382812 ,839.0542602539062 ,840.1779174804688 ,850.2197875976562 ,848.3840942382812 ,840.1779174804688 ,839.0542602539062 ,836.3881225585938 ,839.0542602539062 ,848.3840942382812 ,843.5563354492188 ,1395.549560546875 ,1286.781494140625 ,1249.8555908203125 ,17.356164932250977 ,-48.14024353027344 ,73.47518157958984 ,1667.91650390625 ,1666.1053466796875 ,1674.372314453125 ,1667.91650390625 ,1658.8876953125 ,1658.670166015625 ,1667.91650390625 ,1658.670166015625 ,1666.1053466796875 ,853.9212036132812 ,852.9420166015625 ,855.2047119140625 ,853.9212036132812 ,851.4752197265625 ,852.9420166015625 ,852.9420166015625 ,851.4752197265625 ,850.8707275390625 ,-156.71910095214844 ,-153.44960021972656 ,-154.56825256347656 ,-156.71910095214844 ,-154.56825256347656 ,-151.15257263183594 ,-150.79893493652344 ,-150.48141479492188 ,-151.15257263183594 ,-150.79893493652344 ,-154.56825256347656 ,-153.44960021972656 ,-150.79893493652344 ,-151.15257263183594 ,-154.56825256347656 ,-150.79893493652344 ,-148.954833984375 ,-150.48141479492188 ,786.3716430664062 ,786.6719970703125 ,784.624755859375 ,-153.9589385986328 ,-153.44395446777344 ,-158.7922821044922 ,-153.9589385986328 ,-158.7922821044922 ,-154.53662109375 ,-153.9589385986328 ,-148.95811462402344 ,-153.44395446777344 ,1312.385986328125 ,1081.4989013671875 ,1065.2171630859375 ,1017.6915893554688 ,945.4508056640625 ,1130.995361328125 ,1130.995361328125 ,1515.3936767578125 ,1000.3450317382812 ,1130.995361328125 ,945.4508056640625 ,1515.3936767578125 ,1056.8111572265625 ,1127.7244873046875 ,895.8970947265625 ,1056.8111572265625 ,895.8970947265625 ,1002.829345703125 ,-158.48971557617188 ,-176.13626098632812 ,-166.1304168701172 ,-166.1304168701172 ,-174.0264892578125 ,-163.55294799804688 ,-166.1304168701172 ,-176.13626098632812 ,-118.19950103759766 ,-166.1304168701172 ,-118.19950103759766 ,-174.0264892578125 ,-110.61604309082031 ,-137.97515869140625 ,-120.02518463134766 ,-81.57925415039062 ,-93.25747680664062 ,-87.17730712890625 ,-81.57925415039062 ,-89.18526458740234 ,-93.25747680664062 ,-93.25747680664062 ,-96.3033676147461 ,-102.13951873779297 ,-93.25747680664062 ,-89.18526458740234 ,-96.3033676147461 ,1460.7689208984375 ,1477.02099609375 ,1317.367431640625 ,949.4277954101562 ,979.1408081054688 ,806.8790893554688 ,949.4277954101562 ,806.8790893554688 ,864.3307495117188 ,806.8790893554688 ,979.1408081054688 ,894.9195556640625 ,1618.32177734375 ,1600.038330078125 ,1614.396728515625 ,949.4277954101562 ,978.0540161132812 ,979.1408081054688 ,949.4277954101562 ,927.310791015625 ,978.0540161132812 ,979.1408081054688 ,978.0540161132812 ,978.31494140625 ,1584.6922607421875 ,1571.6982421875 ,1573.8131103515625 ,-145.84243774414062 ,-138.11817932128906 ,-140.02178955078125 ,-140.02178955078125 ,-141.91162109375 ,-145.84243774414062 ,72.48503112792969 ,84.34304809570312 ,19.352371215820312 ,72.48503112792969 ,55.59247970581055 ,84.34304809570312 ,72.48503112792969 ,21.5523624420166 ,55.59247970581055 ,72.48503112792969 ,19.352371215820312 ,21.5523624420166 ,852.0170288085938 ,832.4279174804688 ,847.1500244140625 ,852.0170288085938 ,843.0507202148438 ,824.2406616210938 ,852.0170288085938 ,824.2406616210938 ,832.4279174804688 ,1555.0257568359375 ,1577.3192138671875 ,1588.1116943359375 ,1555.0257568359375 ,1563.51953125 ,1577.3192138671875 ,1555.0257568359375 ,1588.1116943359375 ,1611.879638671875 ,22.273630142211914 ,35.302860260009766 ,55.59247970581055 ,22.273630142211914 ,55.59247970581055 ,21.5523624420166 ,1589.683349609375 ,1579.477783203125 ,1593.351806640625 ,-0.7145509719848633 ,-13.414265632629395 ,-49.69411087036133 ,-0.7145509719848633 ,-49.69411087036133 ,2.2539000511169434 ,577.8530883789062 ,683.6290893554688 ,661.638916015625 ,1554.7137451171875 ,1569.775390625 ,1556.6446533203125 ,1554.7137451171875 ,1557.3426513671875 ,1569.775390625 ,1644.2154541015625 ,1649.5989990234375 ,1639.3721923828125 ,1683.29248046875 ,1688.038818359375 ,1675.038330078125 ,1683.29248046875 ,1690.700439453125 ,1688.038818359375 ,1683.29248046875 ,1675.038330078125 ,1670.7144775390625 ,1662.08154296875 ,1651.02587890625 ,1659.3050537109375 ,978.5054931640625 ,969.9252319335938 ,983.1600952148438 ,978.5054931640625 ,983.1600952148438 ,988.48779296875 ,978.5054931640625 ,965.5859985351562 ,969.9252319335938 ,969.9252319335938 ,992.80419921875 ,983.1600952148438 ,983.1600952148438 ,992.80419921875 ,1009.9961547851562 ,983.1600952148438 ,1009.9961547851562 ,988.48779296875 ,1501.1376953125 ,1529.5411376953125 ,1541.4324951171875 ,1501.1376953125 ,1541.4324951171875 ,1506.52294921875 ,1630.4327392578125 ,1624.47802734375 ,1637.527587890625 ,1660.7340087890625 ,1672.689208984375 ,1673.563720703125 ,1660.7340087890625 ,1661.914794921875 ,1672.689208984375 ,1660.7340087890625 ,1673.563720703125 ,1659.01953125 ,1693.0804443359375 ,1689.44873046875 ,1693.1881103515625 ,1618.9720458984375 ,1615.4534912109375 ,1614.930419921875 ,1618.9720458984375 ,1614.930419921875 ,1626.0142822265625 ,-182.0306396484375 ,-172.128173828125 ,-182.18698120117188 ,1570.0733642578125 ,1572.6234130859375 ,1571.789794921875 ,1693.7802734375 ,1694.043212890625 ,1693.86083984375 ,1693.7802734375 ,1692.35009765625 ,1693.2091064453125 ,1693.7802734375 ,1693.2091064453125 ,1693.468017578125 ,1693.7802734375 ,1693.468017578125 ,1694.043212890625 ,1693.7802734375 ,1693.86083984375 ,1692.35009765625 ,1682.325927734375 ,1679.4403076171875 ,1686.4300537109375 ,1686.4300537109375 ,1679.4403076171875 ,1684.5247802734375 ,1686.4300537109375 ,1684.5247802734375 ,1685.360595703125 ,791.2047729492188 ,795.9425048828125 ,770.282470703125 ,791.2047729492188 ,770.282470703125 ,761.124755859375 ,791.2047729492188 ,761.124755859375 ,800.8710327148438 ,791.2047729492188 ,800.8710327148438 ,795.9425048828125 ,800.8710327148438 ,761.124755859375 ,765.2786865234375 ,1608.282958984375 ,1607.8541259765625 ,1596.677001953125 ,1593.195068359375 ,1615.1953125 ,1612.751220703125 ,1612.751220703125 ,1615.1953125 ,1630.4327392578125 ,1611.879638671875 ,1623.9122314453125 ,1635.4061279296875 ,1608.5009765625 ,1635.94482421875 ,1623.8583984375 ,1635.94482421875 ,1638.36181640625 ,1623.8583984375 ,1604.43994140625 ,1609.84326171875 ,1608.4158935546875 ,1658.8876953125 ,1643.3670654296875 ,1658.670166015625 ,1658.8876953125 ,1652.3216552734375 ,1643.3670654296875 ,1658.670166015625 ,1643.3670654296875 ,1623.536376953125 ,1578.07763671875 ,1555.5660400390625 ,1576.6949462890625 ,1650.708740234375 ,1649.3350830078125 ,1643.6181640625 ,1650.708740234375 ,1653.2535400390625 ,1649.3350830078125 ,759.187255859375 ,750.8538208007812 ,745.3248291015625 ,750.8538208007812 ,739.649169921875 ,745.3248291015625 ,1556.9638671875 ,1548.8284912109375 ,1553.022705078125 ,1556.9638671875 ,1553.022705078125 ,1554.3277587890625 ,1554.3277587890625 ,1556.35205078125 ,1556.9638671875 ,850.2197875976562 ,840.7582397460938 ,849.9226684570312 ,842.852294921875 ,772.7360229492188 ,804.1401977539062 ,842.852294921875 ,804.1401977539062 ,815.931396484375 ,57.19397735595703 ,-109.40483856201172 ,-119.19314575195312 ,57.19397735595703 ,-1.4779369831085205 ,-109.40483856201172 ,-109.40483856201172 ,-1.4779369831085205 ,32.23271942138672 ,552.5986328125 ,80.88017272949219 ,452.7947692871094 ,552.5986328125 ,147.09942626953125 ,80.88017272949219 ,452.7947692871094 ,80.88017272949219 ,363.066162109375 ,452.7947692871094 ,363.066162109375 ,604.1659545898438 ,-168.038330078125 ,-395.974853515625 ,-301.7873840332031 ,-168.038330078125 ,-402.4700927734375 ,-395.974853515625 ,-395.974853515625 ,-402.4700927734375 ,-431.3062438964844 ,828.5111694335938 ,882.060302734375 ,842.575927734375 ,828.5111694335938 ,825.8290405273438 ,882.060302734375 ,1651.3546142578125 ,1980.4984130859375 ,2016.6395263671875 ,1615.1766357421875 ,1635.6138916015625 ,1636.14453125 ,1635.6138916015625 ,1615.1766357421875 ,1604.0233154296875 ,1679.4403076171875 ,1675.5518798828125 ,1678.669921875 ,1622.59228515625 ,1623.9493408203125 ,1625.290283203125 ,1622.59228515625 ,1625.290283203125 ,1621.124755859375 ,1623.9493408203125 ,1630.1005859375 ,1625.290283203125 ,1623.9493408203125 ,1622.59228515625 ,1613.7576904296875 ,1623.9493408203125 ,1613.7576904296875 ,1625.792724609375 ,1623.9493408203125 ,1625.792724609375 ,1630.1005859375 ,1600.544921875 ,1600.4422607421875 ,1601.023681640625 ,1600.544921875 ,1599.591064453125 ,1600.4422607421875 ,1613.71533203125 ,1617.2596435546875 ,1625.169189453125 ,1625.169189453125 ,1623.6824951171875 ,1613.71533203125 ,840.5704345703125 ,829.766357421875 ,795.2511596679688 ,1653.60546875 ,1658.14501953125 ,1658.153564453125 ,1620.9952392578125 ,1613.4114990234375 ,1611.4110107421875 ,481.72210693359375 ,454.2554016113281 ,225.7664794921875 ,481.72210693359375 ,648.278564453125 ,639.7841796875 ,481.72210693359375 ,639.7841796875 ,454.2554016113281 ,1555.0257568359375 ,1561.6275634765625 ,1563.51953125 ,1586.1710205078125 ,1601.041015625 ,1591.043701171875 ,751.7406616210938 ,751.3086547851562 ,787.8994750976562 ,751.7406616210938 ,787.8994750976562 ,757.044189453125 ,751.7406616210938 ,757.044189453125 ,744.73828125 ,751.3086547851562 ,767.7692260742188 ,775.8414916992188 ,751.3086547851562 ,775.8414916992188 ,787.8994750976562 ,-146.54104614257812 ,-121.85279083251953 ,-116.43762969970703 ,-146.54104614257812 ,-151.19723510742188 ,-121.85279083251953 ,-121.85279083251953 ,-151.19723510742188 ,-109.26838684082031 ,1660.5411376953125 ,1661.9881591796875 ,1667.7757568359375 ,1595.2818603515625 ,1584.786865234375 ,1576.927001953125 ,-146.88943481445312 ,-137.802978515625 ,-149.2166748046875 ,761.7636108398438 ,784.0744018554688 ,787.9410400390625 ,1652.837646484375 ,1645.72412109375 ,1644.7110595703125 ,1652.837646484375 ,1644.7110595703125 ,1651.905029296875 ,1536.8348388671875 ,1492.576904296875 ,1571.35205078125 ,1556.9638671875 ,1556.35205078125 ,1555.383056640625 ,1548.8284912109375 ,1556.9638671875 ,1561.04443359375 ,-132.90476989746094 ,-63.78702163696289 ,-58.478668212890625 ,-132.90476989746094 ,-58.478668212890625 ,-103.25717163085938 ,-132.90476989746094 ,-67.07080841064453 ,-63.78702163696289 ,1870.11962890625 ,1885.6708984375 ,1867.268798828125 ,1885.6708984375 ,1841.949462890625 ,1858.9906005859375 ,1885.6708984375 ,1858.9906005859375 ,1867.268798828125 ,1867.268798828125 ,1858.9906005859375 ,1894.75439453125 ,1867.268798828125 ,1894.75439453125 ,1870.11962890625 ,5.809103965759277 ,-88.27867126464844 ,-56.81816482543945 ,867.7277221679688 ,890.0218505859375 ,903.6100463867188 ,-141.76710510253906 ,-115.81771850585938 ,-55.921024322509766 ,-141.76710510253906 ,-55.921024322509766 ,-115.22801971435547 ,65.16423034667969 ,11.559826850891113 ,81.85726165771484 ,65.16423034667969 ,81.85726165771484 ,117.10556030273438 ,65.16423034667969 ,-37.357818603515625 ,11.559826850891113 ,65.16423034667969 ,117.10556030273438 ,91.43526458740234 ,65.16423034667969 ,29.884546279907227 ,-37.357818603515625 ,65.16423034667969 ,91.43526458740234 ,29.884546279907227 ,11.559826850891113 ,-49.12808609008789 ,81.85726165771484 ,81.85726165771484 ,84.98744201660156 ,117.10556030273438 ,-174.69415283203125 ,-157.6728057861328 ,-171.90296936035156 ,1660.006591796875 ,1652.9853515625 ,1664.8953857421875 ,84.34304809570312 ,55.59247970581055 ,65.91230010986328 ,84.34304809570312 ,65.91230010986328 ,123.47190856933594 ,1651.9884033203125 ,1652.4918212890625 ,1650.967041015625 ,1651.9884033203125 ,1653.5064697265625 ,1656.9443359375 ,1651.9884033203125 ,1656.9443359375 ,1652.4918212890625 ,843.8851318359375 ,815.931396484375 ,851.4752197265625 ,1726.457275390625 ,1610.6427001953125 ,1872.0791015625 ,1581.4505615234375 ,1556.9329833984375 ,1505.9176025390625 ,1505.9176025390625 ,1512.47705078125 ,1581.4505615234375 ,820.02978515625 ,819.2005615234375 ,809.3734130859375 ,820.02978515625 ,848.0089111328125 ,819.2005615234375 ,820.02978515625 ,809.3734130859375 ,801.7922973632812 ,820.02978515625 ,831.8568725585938 ,848.0089111328125 ,820.02978515625 ,801.7922973632812 ,831.8568725585938 ,809.3734130859375 ,804.2978515625 ,801.7922973632812 ,1651.3546142578125 ,2016.6395263671875 ,1540.01904296875 ,911.580078125 ,1083.5889892578125 ,1014.3953247070312 ,911.580078125 ,987.7450561523438 ,1083.5889892578125 ,963.122314453125 ,1207.198486328125 ,1234.9974365234375 ,963.122314453125 ,1234.9974365234375 ,1125.4884033203125 ,1207.198486328125 ,963.122314453125 ,1081.4989013671875 ,803.837158203125 ,786.45361328125 ,827.5490112304688 ,786.45361328125 ,772.87109375 ,778.3737182617188 ,786.45361328125 ,803.837158203125 ,772.87109375 ,786.45361328125 ,814.464111328125 ,827.5490112304688 ,799.7362060546875 ,801.1747436523438 ,811.1006469726562 ,800.7420043945312 ,814.5217895507812 ,814.1434326171875 ,249.11463928222656 ,229.74269104003906 ,167.67335510253906 ,814.9298095703125 ,823.284912109375 ,840.1627807617188 ,814.9298095703125 ,840.1627807617188 ,839.070556640625 ,839.070556640625 ,840.1627807617188 ,843.0507202148438 ,1660.7340087890625 ,1648.0037841796875 ,1638.8861083984375 ,1619.9852294921875 ,1592.7005615234375 ,1601.7579345703125 ,797.4121704101562 ,815.0030517578125 ,831.8568725585938 ,797.4121704101562 ,831.8568725585938 ,801.7922973632812 ,1870.11962890625 ,1892.9903564453125 ,1882.818359375 ,1870.11962890625 ,1894.75439453125 ,1892.9903564453125 ,1652.6387939453125 ,1657.06494140625 ,1660.91064453125 ,1652.6387939453125 ,1660.91064453125 ,1659.970947265625 ,1555.5306396484375 ,1563.65771484375 ,1557.3426513671875 ,1617.012939453125 ,1612.3529052734375 ,1621.833984375 ,1617.012939453125 ,1601.041015625 ,1612.3529052734375 ,1621.833984375 ,1612.3529052734375 ,1615.5350341796875 ,1607.0042724609375 ,1613.982666015625 ,1617.992431640625 ,1607.0042724609375 ,1617.992431640625 ,1603.496337890625 ,1607.0042724609375 ,1603.496337890625 ,1599.9283447265625 ,1646.0224609375 ,1651.05126953125 ,1656.8359375 ,1678.726318359375 ,1680.9556884765625 ,1679.3565673828125 ,1680.9556884765625 ,1678.726318359375 ,1681.6229248046875 ,1563.7801513671875 ,1567.772216796875 ,1564.52734375 ,1598.990234375 ,1597.3072509765625 ,1594.349609375 ,797.5750122070312 ,911.580078125 ,882.2884521484375 ,797.5750122070312 ,812.12744140625 ,911.580078125 ,911.580078125 ,812.12744140625 ,987.7450561523438 ,779.6307373046875 ,762.6683349609375 ,772.681884765625 ,887.3312377929688 ,927.310791015625 ,864.3307495117188 ,1600.48583984375 ,1600.988525390625 ,1600.8250732421875 ,1659.650634765625 ,1664.548095703125 ,1660.4757080078125 ,1659.650634765625 ,1660.303955078125 ,1664.548095703125 ,1660.4757080078125 ,1664.548095703125 ,1667.19677734375 ,1609.58203125 ,1603.897705078125 ,1622.50927734375 ,1609.58203125 ,1593.3319091796875 ,1603.897705078125 ,1609.58203125 ,1603.6051025390625 ,1593.3319091796875 ,1609.58203125 ,1611.40771484375 ,1603.6051025390625 ,1609.58203125 ,1622.50927734375 ,1611.40771484375 ,1622.50927734375 ,1603.897705078125 ,1620.38330078125 ,1667.91650390625 ,1652.3216552734375 ,1658.8876953125 ,1667.91650390625 ,1641.4759521484375 ,1652.3216552734375 ,1595.56201171875 ,1588.5467529296875 ,1589.62109375 ,1664.9896240234375 ,1666.199951171875 ,1662.9305419921875 ,1664.9896240234375 ,1668.263916015625 ,1666.199951171875 ,1662.6553955078125 ,1660.2691650390625 ,1664.9896240234375 ,1583.322509765625 ,1595.1080322265625 ,1592.0440673828125 ,1564.0841064453125 ,1553.8087158203125 ,1550.7193603515625 ,1655.2957763671875 ,1659.970947265625 ,1655.780517578125 ,1532.6363525390625 ,1541.419677734375 ,1537.858642578125 ,1532.6363525390625 ,1537.4833984375 ,1541.419677734375 ,1638.5103759765625 ,1634.888916015625 ,1636.1795654296875 ,1480.235107421875 ,1590.92431640625 ,1481.825927734375 ,1480.235107421875 ,1477.02099609375 ,1590.92431640625 ,1480.235107421875 ,1457.6270751953125 ,1477.02099609375 ,1690.700439453125 ,1695.4520263671875 ,1688.038818359375 ,1684.2529296875 ,1685.751220703125 ,1677.5621337890625 ,979.1408081054688 ,965.666748046875 ,894.9195556640625 ,979.1408081054688 ,978.31494140625 ,968.7680053710938 ,979.1408081054688 ,968.7680053710938 ,965.666748046875 ,1477.014404296875 ,1491.4222412109375 ,1501.1376953125 ,1664.2130126953125 ,1665.4837646484375 ,1676.6839599609375 ,1567.9937744140625 ,1570.4049072265625 ,1573.0107421875 ,1642.681396484375 ,1640.44482421875 ,1640.646728515625 ,1642.681396484375 ,1646.00439453125 ,1640.44482421875 ,1646.00439453125 ,1642.681396484375 ,1647.38427734375 ,1611.4110107421875 ,1613.4114990234375 ,1609.28369140625 ,-142.7763671875 ,-143.4319305419922 ,-168.16668701171875 ,-142.7763671875 ,-168.16668701171875 ,-151.3717803955078 ,-142.7763671875 ,-151.3717803955078 ,-145.2946014404297 ,-149.2166748046875 ,-141.20297241210938 ,-160.13168334960938 ,1647.4891357421875 ,1632.63623046875 ,1629.9248046875 ,1647.4891357421875 ,1629.9248046875 ,1637.8194580078125 ,1601.9359130859375 ,1602.937255859375 ,1601.5650634765625 ,822.809326171875 ,829.1942138671875 ,825.40185546875 ,822.809326171875 ,843.6236572265625 ,829.1942138671875 ,825.40185546875 ,829.1942138671875 ,813.8816528320312 ,825.40185546875 ,813.8816528320312 ,822.809326171875 ,1660.8375244140625 ,1664.07568359375 ,1657.83203125 ,1657.83203125 ,1656.337158203125 ,1660.8375244140625 ,1106.598876953125 ,1127.22021484375 ,1089.5526123046875 ,1106.598876953125 ,1200.5262451171875 ,1127.22021484375 ,1106.598876953125 ,1089.5526123046875 ,1078.2822265625 ,1106.598876953125 ,1140.5811767578125 ,1200.5262451171875 ,1106.598876953125 ,1088.1229248046875 ,1140.5811767578125 ,1106.598876953125 ,1078.2822265625 ,1088.1229248046875 ,1127.22021484375 ,1110.033203125 ,1089.5526123046875 ,1127.22021484375 ,1154.2872314453125 ,1110.033203125 ,1127.22021484375 ,1200.5262451171875 ,1174.9976806640625 ,1127.22021484375 ,1174.9976806640625 ,1154.2872314453125 ,1089.5526123046875 ,1110.033203125 ,1091.0006103515625 ,1089.5526123046875 ,1042.39111328125 ,1078.2822265625 ,1089.5526123046875 ,1091.0006103515625 ,1067.620361328125 ,1089.5526123046875 ,1067.620361328125 ,1042.39111328125 ,-138.46212768554688 ,-122.85227966308594 ,-133.1144561767578 ,1651.7899169921875 ,1664.110107421875 ,1655.194580078125 ,1682.659912109375 ,1681.4793701171875 ,1679.5113525390625 ,1602.4737548828125 ,1603.49072265625 ,1604.43994140625 ,1602.4737548828125 ,1601.489013671875 ,1601.320556640625 ,1602.4737548828125 ,1601.320556640625 ,1603.49072265625 ,1603.49072265625 ,1601.320556640625 ,1600.82421875 ,238.97511291503906 ,500.4654235839844 ,255.31051635742188 ,238.97511291503906 ,341.78338623046875 ,500.4654235839844 ,1553.7196044921875 ,1553.022705078125 ,1554.8896484375 ,1553.7196044921875 ,1554.8896484375 ,1557.295654296875 ,1553.7196044921875 ,1553.41455078125 ,1556.35205078125 ,1553.7196044921875 ,1557.295654296875 ,1553.41455078125 ,1553.7196044921875 ,1556.35205078125 ,1553.022705078125 ,1592.8089599609375 ,1591.1009521484375 ,1589.6549072265625 ,1156.853515625 ,1083.5889892578125 ,1121.9959716796875 ,1156.853515625 ,1121.9959716796875 ,1135.334228515625 ,1156.853515625 ,1125.035400390625 ,1083.5889892578125 ,1121.9959716796875 ,1107.613525390625 ,1135.334228515625 ,1121.9959716796875 ,1083.5889892578125 ,1055.40966796875 ,1121.9959716796875 ,1055.40966796875 ,1107.613525390625 ,804.7008056640625 ,831.5140991210938 ,965.7979125976562 ,804.7008056640625 ,814.373046875 ,791.092529296875 ,804.7008056640625 ,965.7979125976562 ,814.373046875 ,-410.66534423828125 ,-431.3062438964844 ,-297.3943176269531 ,-410.66534423828125 ,-395.974853515625 ,-431.3062438964844 ,-410.66534423828125 ,-297.3943176269531 ,-395.974853515625 ,-297.3943176269531 ,-431.3062438964844 ,-304.0158386230469 ,-155.86891174316406 ,-154.77008056640625 ,-158.5688018798828 ,1880.57177734375 ,1950.8538818359375 ,1819.286376953125 ,848.1756591796875 ,850.6434326171875 ,853.9212036132812 ,848.1756591796875 ,853.9212036132812 ,852.4119873046875 ,848.1756591796875 ,842.6087646484375 ,850.6434326171875 ,850.6434326171875 ,853.804443359375 ,853.9212036132812 ,892.685302734375 ,894.0360717773438 ,856.873779296875 ,892.685302734375 ,856.873779296875 ,867.0675048828125 ,867.0675048828125 ,821.8519287109375 ,747.9818115234375 ,867.0675048828125 ,856.873779296875 ,821.8519287109375 ,884.280517578125 ,882.060302734375 ,825.8290405273438 ,884.280517578125 ,847.4163208007812 ,882.060302734375 ,884.280517578125 ,873.4906616210938 ,847.4163208007812 ,873.4906616210938 ,771.46240234375 ,847.4163208007812 ,889.2929077148438 ,858.8248901367188 ,861.0339965820312 ,889.2929077148438 ,861.0339965820312 ,896.8179321289062 ,858.8248901367188 ,812.9592895507812 ,861.0339965820312 ,861.0339965820312 ,810.5379028320312 ,854.4637451171875 ,861.0339965820312 ,854.4637451171875 ,896.8179321289062 ,861.0339965820312 ,812.9592895507812 ,810.5379028320312 ,8.591601371765137 ,-34.57811737060547 ,2.1524689197540283 ,864.621826171875 ,854.9761962890625 ,852.0170288085938 ,864.621826171875 ,863.3182373046875 ,854.9761962890625 ,-22.468109130859375 ,37.52220916748047 ,67.64774322509766 ,-22.468109130859375 ,67.64774322509766 ,-24.251636505126953 ,-22.468109130859375 ,-24.251636505126953 ,-51.09827423095703 ,-72.85733032226562 ,-73.13835144042969 ,-22.468109130859375 ,1653.8194580078125 ,1653.762939453125 ,1654.3704833984375 ,1558.3780517578125 ,1555.5506591796875 ,1571.6690673828125 ,1558.3780517578125 ,1551.9730224609375 ,1555.5506591796875 ,1644.2154541015625 ,1649.9161376953125 ,1649.5989990234375 ,1663.33984375 ,1657.8052978515625 ,1653.93603515625 ,1599.3277587890625 ,1607.9539794921875 ,1607.8009033203125 ,1599.3277587890625 ,1607.8009033203125 ,1596.0208740234375 ,1621.833984375 ,1632.9971923828125 ,1633.0953369140625 ,1662.6346435546875 ,1671.3597412109375 ,1662.4249267578125 ,1671.3597412109375 ,1662.6346435546875 ,1667.19677734375 ,1548.4180908203125 ,1482.5047607421875 ,1506.52294921875 ,1548.4180908203125 ,1476.919677734375 ,1482.5047607421875 ,1548.4180908203125 ,1506.52294921875 ,1548.2794189453125 ,1506.52294921875 ,1534.306884765625 ,1548.2794189453125 ,1120.439208984375 ,1242.9195556640625 ,1175.87353515625 ,1643.3203125 ,1640.2740478515625 ,1636.365966796875 ,1665.322509765625 ,1671.78173828125 ,1667.3758544921875 ,1603.8221435546875 ,1606.330322265625 ,1602.3759765625 ,1600.988525390625 ,1605.918212890625 ,1600.8250732421875 ,1600.988525390625 ,1602.3759765625 ,1605.918212890625 ,1387.4476318359375 ,1410.970458984375 ,1384.2012939453125 ,963.9760131835938 ,706.0634765625 ,772.8612060546875 ,706.0634765625 ,792.0645141601562 ,717.0455322265625 ,454.2554016113281 ,202.90794372558594 ,225.7664794921875 ,1615.1953125 ,1624.47802734375 ,1630.4327392578125 ,1611.5498046875 ,1608.4158935546875 ,1609.84326171875 ,1601.3475341796875 ,1599.4454345703125 ,1597.3072509765625 ,1613.9197998046875 ,1590.896484375 ,1592.7005615234375 ,1596.677001953125 ,1607.8541259765625 ,1606.0787353515625 ,1596.677001953125 ,1606.0787353515625 ,1596.00439453125 ,1607.8541259765625 ,1627.878662109375 ,1606.0787353515625 ,1607.8541259765625 ,1608.282958984375 ,1627.878662109375 ,1664.03955078125 ,1667.3428955078125 ,1663.9632568359375 ,1664.03955078125 ,1664.8974609375 ,1667.3428955078125 ,1664.03955078125 ,1660.623779296875 ,1664.8974609375 ,1347.615478515625 ,1286.781494140625 ,1395.549560546875 ,1347.615478515625 ,1395.549560546875 ,1365.6441650390625 ,1664.9874267578125 ,1659.814208984375 ,1661.281982421875 ,1597.2001953125 ,1598.0413818359375 ,1598.3885498046875 ,1597.2001953125 ,1598.3885498046875 ,1599.1964111328125 ,1597.2001953125 ,1599.1964111328125 ,1594.472900390625 ,1598.0413818359375 ,1593.8599853515625 ,1598.3885498046875 ,1598.3885498046875 ,1606.5816650390625 ,1598.5628662109375 ,1598.3885498046875 ,1598.5628662109375 ,1599.1964111328125 ,1597.8408203125 ,1591.385986328125 ,1592.0350341796875 ,798.1160888671875 ,792.5782470703125 ,798.400390625 ,798.1160888671875 ,798.400390625 ,801.35595703125 ,80.88017272949219 ,147.09942626953125 ,70.96662902832031 ,842.20458984375 ,877.5236206054688 ,846.9815063476562 ,842.20458984375 ,846.9815063476562 ,801.0247192382812 ,846.9815063476562 ,776.2487182617188 ,801.0247192382812 ,-55.921024322509766 ,-106.64468383789062 ,-115.22801971435547 ,801.1747436523438 ,803.837158203125 ,833.7054443359375 ,801.1747436523438 ,777.08203125 ,772.87109375 ,801.1747436523438 ,772.87109375 ,803.837158203125 ,1622.50927734375 ,1619.8695068359375 ,1611.40771484375 ,992.80419921875 ,1007.6820678710938 ,1009.9961547851562 ,-172.128173828125 ,-106.98082733154297 ,-182.18698120117188 ,-172.128173828125 ,-182.0306396484375 ,-106.98082733154297 ,-182.18698120117188 ,-106.98082733154297 ,-194.07723999023438 ,1548.9468994140625 ,1546.8094482421875 ,1549.0443115234375 ,1546.8094482421875 ,1544.0799560546875 ,1549.0443115234375 ,1549.0443115234375 ,1548.867919921875 ,1548.9468994140625 ,1650.967041015625 ,1652.4918212890625 ,1648.84814453125 ,1650.967041015625 ,1648.84814453125 ,1648.4556884765625 ,1650.967041015625 ,1648.4556884765625 ,1645.1719970703125 ,745.458740234375 ,742.4617309570312 ,747.1206665039062 ,745.458740234375 ,753.7611083984375 ,742.4617309570312 ,-10.222365379333496 ,-6.674344062805176 ,-8.213500022888184 ,561.6047973632812 ,458.4006042480469 ,461.52252197265625 ,850.8707275390625 ,851.4752197265625 ,845.576171875 ,1008.1751708984375 ,988.9864501953125 ,1022.5490112304688 ,988.9864501953125 ,933.6444702148438 ,1022.5490112304688 ,988.9864501953125 ,885.052490234375 ,933.6444702148438 ,-108.06562805175781 ,-37.49604797363281 ,-69.6546859741211 ,-108.06562805175781 ,-13.013050079345703 ,-37.49604797363281 ,-108.06562805175781 ,-46.94858169555664 ,-13.013050079345703 ,-108.06562805175781 ,-99.30792999267578 ,-46.94858169555664 ,-80.9568099975586 ,-84.93722534179688 ,-43.334495544433594 ,1660.2691650390625 ,1659.756103515625 ,1664.9896240234375 ,1660.2691650390625 ,1656.8359375 ,1659.756103515625 ,1658.153564453125 ,1658.14501953125 ,1661.9881591796875 ,1691.0614013671875 ,1688.48388671875 ,1690.4541015625 ,1689.8787841796875 ,1686.5401611328125 ,1688.736572265625 ,1689.8787841796875 ,1688.9949951171875 ,1686.5401611328125 ,1639.727294921875 ,1595.8602294921875 ,1481.825927734375 ,1541.107177734375 ,1540.3974609375 ,1537.8978271484375 ,1680.30908203125 ,1677.5621337890625 ,1685.751220703125 ,969.9252319335938 ,1010.2650756835938 ,992.80419921875 ,1598.4822998046875 ,1597.8902587890625 ,1599.012451171875 ,1599.4454345703125 ,1603.0877685546875 ,1598.4822998046875 ,1693.86083984375 ,1693.4378662109375 ,1692.35009765625 ,847.5123291015625 ,846.870849609375 ,843.5563354492188 ,-258.9765930175781 ,-217.6927032470703 ,-202.57232666015625 ,-258.9765930175781 ,-202.57232666015625 ,-206.4029083251953 ,-258.9765930175781 ,-206.4029083251953 ,-265.82415771484375 ,-258.9765930175781 ,-265.82415771484375 ,-217.6927032470703 ,1623.6824951171875 ,1617.68212890625 ,1613.71533203125 ,1686.4300537109375 ,1684.5474853515625 ,1682.325927734375 ,1658.670166015625 ,1655.8255615234375 ,1666.1053466796875 ,1657.7835693359375 ,1626.0413818359375 ,1634.2149658203125 ,1673.771728515625 ,1673.615966796875 ,1677.7841796875 ,1677.7841796875 ,1676.400634765625 ,1679.02587890625 ,1677.7841796875 ,1673.615966796875 ,1676.400634765625 ,1673.771728515625 ,1677.7841796875 ,1675.254150390625 ,1673.771728515625 ,1675.254150390625 ,1674.537353515625 ,1650.708740234375 ,1654.254150390625 ,1653.2535400390625 ,1516.1270751953125 ,1540.0787353515625 ,1499.37890625 ,1554.3277587890625 ,1553.022705078125 ,1556.35205078125 ,791.5802001953125 ,806.130859375 ,804.2484741210938 ,791.5802001953125 ,793.9613037109375 ,806.130859375 ,80.88017272949219 ,124.47106170654297 ,363.066162109375 ,1677.6544189453125 ,1664.8780517578125 ,1669.150634765625 ,1677.6544189453125 ,1669.150634765625 ,1678.89990234375 ,1682.1451416015625 ,1677.6544189453125 ,1683.6917724609375 ,1677.6544189453125 ,1667.689453125 ,1664.8780517578125 ,1677.6544189453125 ,1682.1451416015625 ,1667.689453125 ,-173.61891174316406 ,-171.90296936035156 ,-170.8797149658203 ,-173.61891174316406 ,-170.8797149658203 ,-174.07568359375 ,1600.057861328125 ,1597.1424560546875 ,1594.7960205078125 ,1567.772216796875 ,1573.9468994140625 ,1564.52734375 ,1567.772216796875 ,1577.2099609375 ,1573.9468994140625 ,1573.9468994140625 ,1563.7801513671875 ,1564.52734375 ,1573.9468994140625 ,1572.1949462890625 ,1563.7801513671875 ,1573.9468994140625 ,1577.2099609375 ,1572.1949462890625 ,786.45361328125 ,790.7344360351562 ,814.464111328125 ,648.278564453125 ,704.7988891601562 ,683.404296875 ,648.278564453125 ,683.404296875 ,639.7841796875 ,648.278564453125 ,481.72210693359375 ,639.5640869140625 ,561.8804931640625 ,625.8710327148438 ,596.9385375976562 ,1653.9100341796875 ,1657.7440185546875 ,1661.525634765625 ,1585.5823974609375 ,1576.927001953125 ,1567.1591796875 ,1585.5823974609375 ,1567.1591796875 ,1589.208251953125 ,1337.581787109375 ,1272.394287109375 ,1382.652587890625 ,1337.581787109375 ,1382.652587890625 ,1370.767333984375 ,1370.767333984375 ,1422.00341796875 ,1476.919677734375 ,1665.322509765625 ,1662.4249267578125 ,1671.3597412109375 ,1671.3597412109375 ,1673.062744140625 ,1665.322509765625 ,927.310791015625 ,934.7592163085938 ,925.2911987304688 ,-109.26838684082031 ,-151.19723510742188 ,-159.0187530517578 ,1587.4739990234375 ,1588.25830078125 ,1589.70556640625 ,1587.4739990234375 ,1585.217041015625 ,1580.8135986328125 ,1587.4739990234375 ,1588.1551513671875 ,1585.217041015625 ,1638.3662109375 ,1633.1319580078125 ,1604.1265869140625 ,1638.3662109375 ,1641.9266357421875 ,1633.1319580078125 ,1572.697509765625 ,1559.1688232421875 ,1567.9937744140625 ,-79.09713745117188 ,-73.2208480834961 ,-90.81015014648438 ,-79.09713745117188 ,-90.81015014648438 ,-112.6689453125 ,-79.09713745117188 ,-112.6689453125 ,-64.88725280761719 ,-73.2208480834961 ,-74.04899597167969 ,-90.81015014648438 ,-73.2208480834961 ,-60.414794921875 ,-74.04899597167969 ,-73.2208480834961 ,-73.13835144042969 ,-60.414794921875 ,814.1434326171875 ,814.5217895507812 ,827.7611083984375 ,1575.04296875 ,1572.732177734375 ,1568.3416748046875 ,1575.04296875 ,1568.3416748046875 ,1555.5660400390625 ,775.0728759765625 ,764.2892456054688 ,761.9024047851562 ,775.0728759765625 ,761.9024047851562 ,757.730712890625 ,775.0728759765625 ,757.730712890625 ,763.2747192382812 ,764.2892456054688 ,775.0728759765625 ,773.9310302734375 ,761.9024047851562 ,793.8484497070312 ,757.730712890625 ,1455.574462890625 ,1511.5054931640625 ,1436.84033203125 ,849.9226684570312 ,840.1530151367188 ,855.2047119140625 ,849.9226684570312 ,840.7582397460938 ,840.1530151367188 ,855.2047119140625 ,840.1530151367188 ,852.4119873046875 ,855.2047119140625 ,852.4119873046875 ,853.9212036132812 ,-142.4543914794922 ,-99.30792999267578 ,-108.06562805175781 ,-142.4543914794922 ,-129.72067260742188 ,-99.30792999267578 ,-142.4543914794922 ,-157.62338256835938 ,-129.72067260742188 ,-129.72067260742188 ,-157.62338256835938 ,-99.0303726196289 ,-129.72067260742188 ,-99.0303726196289 ,-99.30792999267578 ,1663.9632568359375 ,1667.3428955078125 ,1666.2528076171875 ,1567.1591796875 ,1576.927001953125 ,1565.647705078125 ,1576.927001953125 ,1575.79345703125 ,1565.647705078125 ,117.10556030273438 ,143.4466094970703 ,91.43526458740234 ,68.86013793945312 ,70.74286651611328 ,40.29792022705078 ,1597.156982421875 ,1597.7860107421875 ,1599.64599609375 ,1636.418212890625 ,1631.2967529296875 ,1633.1820068359375 ,1667.8065185546875 ,1654.319580078125 ,1655.4056396484375 ,-142.61868286132812 ,-145.2946014404297 ,-145.7958221435547 ,1643.3670654296875 ,1652.3216552734375 ,1636.007568359375 ,704.05419921875 ,724.1598510742188 ,740.9560546875 ,704.05419921875 ,740.9560546875 ,719.1813354492188 ,724.1598510742188 ,747.0787353515625 ,740.9560546875 ,608.802734375 ,570.5579223632812 ,620.417236328125 ,1578.2080078125 ,1572.86376953125 ,1569.2528076171875 ,-67.07080841064453 ,17.356164932250977 ,-63.78702163696289 ,-67.07080841064453 ,-57.356292724609375 ,17.356164932250977 ,-67.07080841064453 ,-132.90476989746094 ,-57.356292724609375 ,-63.78702163696289 ,17.356164932250977 ,12.802969932556152 ,-63.78702163696289 ,12.802969932556152 ,-58.478668212890625 ,833.7752075195312 ,825.1792602539062 ,796.4855346679688 ,760.6171875 ,757.3011474609375 ,801.0247192382812 ,760.6171875 ,769.0580444335938 ,757.3011474609375 ,760.6171875 ,801.0247192382812 ,776.2487182617188 ,229.74269104003906 ,225.9130401611328 ,167.67335510253906 ,1649.2138671875 ,1650.55078125 ,1653.3548583984375 ,1649.2138671875 ,1653.3548583984375 ,1644.6551513671875 ,1651.905029296875 ,1657.2647705078125 ,1652.837646484375 ,779.9949951171875 ,789.5177612304688 ,783.3239135742188 ,779.9949951171875 ,783.3239135742188 ,777.9764404296875 ,-33.623085021972656 ,-109.26838684082031 ,-112.88627624511719 ,1558.0872802734375 ,1548.560302734375 ,1548.9468994140625 ,1663.065185546875 ,1652.356201171875 ,1761.8521728515625 ,1936.465576171875 ,1891.7158203125 ,1932.8714599609375 ,1936.465576171875 ,1833.514404296875 ,1891.7158203125 ,1660.2691650390625 ,1662.9305419921875 ,1664.6141357421875 ,1660.2691650390625 ,1664.6141357421875 ,1658.14501953125 ,1680.5126953125 ,1678.16552734375 ,1682.081298828125 ,1680.5126953125 ,1675.3055419921875 ,1678.16552734375 ,1680.5126953125 ,1682.081298828125 ,1682.5885009765625 ,1680.5126953125 ,1682.5885009765625 ,1675.08056640625 ,1680.5126953125 ,1675.08056640625 ,1675.3055419921875 ,1604.0233154296875 ,1607.8009033203125 ,1618.7872314453125 ,1607.8009033203125 ,1618.880615234375 ,1618.7872314453125 ,1618.7872314453125 ,1633.2303466796875 ,1604.0233154296875 ,1618.7872314453125 ,1618.880615234375 ,1633.2303466796875 ,1604.0233154296875 ,1633.2303466796875 ,1635.6138916015625 ,1626.9364013671875 ,1625.792724609375 ,1622.3206787109375 ,1626.9364013671875 ,1627.7117919921875 ,1625.792724609375 ,1592.7005615234375 ,1619.9852294921875 ,1613.9197998046875 ,664.9578857421875 ,626.4420776367188 ,706.8468627929688 ,664.9578857421875 ,706.8468627929688 ,708.30078125 ,664.9578857421875 ,708.30078125 ,648.278564453125 ,648.278564453125 ,708.30078125 ,704.7988891601562 ,130.1804656982422 ,39.34755325317383 ,12.802969932556152 ,130.1804656982422 ,130.03395080566406 ,39.34755325317383 ,12.802969932556152 ,17.356164932250977 ,130.1804656982422 ,1566.0189208984375 ,1564.7724609375 ,1561.3687744140625 ,1653.60546875 ,1654.66064453125 ,1653.57763671875 ,238.97511291503906 ,171.44357299804688 ,165.0082244873047 ,238.97511291503906 ,249.11463928222656 ,171.44357299804688 ,1664.8988037109375 ,1658.734619140625 ,1662.99072265625 ,1567.1591796875 ,1565.647705078125 ,1554.7178955078125 ,1593.3438720703125 ,1603.496337890625 ,1607.81689453125 ,1686.5401611328125 ,1687.360595703125 ,1686.6571044921875 ,1686.5401611328125 ,1688.9949951171875 ,1687.360595703125 ,1686.5401611328125 ,1685.1534423828125 ,1684.3946533203125 ,1686.5401611328125 ,1686.6571044921875 ,1685.1534423828125 ,1670.7144775390625 ,1645.1536865234375 ,1662.5382080078125 ,1609.5733642578125 ,1597.1424560546875 ,1600.057861328125 ,1648.0936279296875 ,1644.410888671875 ,1639.416259765625 ,-129.30104064941406 ,-130.08799743652344 ,-131.70802307128906 ,1632.133544921875 ,1623.7742919921875 ,1631.0205078125 ,1623.7742919921875 ,1620.0291748046875 ,1631.0205078125 ,1631.0205078125 ,1620.0291748046875 ,1629.037841796875 ,1574.43994140625 ,1567.772216796875 ,1571.789794921875 ,1688.93359375 ,1688.496826171875 ,1689.44873046875 ,1688.496826171875 ,1688.0460205078125 ,1689.44873046875 ,1677.809814453125 ,1683.33642578125 ,1662.9295654296875 ,1347.615478515625 ,1348.066650390625 ,1312.53857421875 ,1615.4398193359375 ,1606.5816650390625 ,1607.154296875 ,1615.4398193359375 ,1614.394775390625 ,1606.5816650390625 ,1615.4398193359375 ,1607.154296875 ,1617.8851318359375 ,1555.912109375 ,1561.478515625 ,1550.6932373046875 ,1617.6669921875 ,1617.8865966796875 ,1609.5733642578125 ,1617.6669921875 ,1635.6124267578125 ,1617.8865966796875 ,1617.6669921875 ,1630.8304443359375 ,1635.6124267578125 ,1640.7991943359375 ,1647.745361328125 ,1650.5787353515625 ,1061.62109375 ,975.66455078125 ,996.065185546875 ,1061.62109375 ,996.065185546875 ,1076.6728515625 ,1038.2100830078125 ,1011.173583984375 ,1083.865478515625 ,1038.2100830078125 ,1083.865478515625 ,1136.8084716796875 ,1136.8084716796875 ,1083.865478515625 ,1079.8157958984375 ,1136.8084716796875 ,1076.6728515625 ,1038.2100830078125 ,1635.4061279296875 ,1648.0037841796875 ,1651.2750244140625 ,1651.2750244140625 ,1648.0037841796875 ,1659.01953125 ,1589.1885986328125 ,1591.97265625 ,1589.362060546875 ,1589.1885986328125 ,1589.362060546875 ,1577.014892578125 ,1589.1885986328125 ,1577.014892578125 ,1590.654052734375 ,1685.360595703125 ,1686.9090576171875 ,1686.4300537109375 ,1540.01904296875 ,1602.4049072265625 ,1622.7177734375 ,1622.7177734375 ,1651.3546142578125 ,1540.01904296875 ,1622.7177734375 ,1602.4049072265625 ,1649.01171875 ,1690.3095703125 ,1690.71826171875 ,1691.309814453125 ,1690.3095703125 ,1691.309814453125 ,1690.818603515625 ,1690.3095703125 ,1690.2166748046875 ,1690.71826171875 ,1655.8255615234375 ,1637.8812255859375 ,1666.1053466796875 ,1655.8255615234375 ,1658.670166015625 ,1637.8812255859375 ,1632.3934326171875 ,1601.6107177734375 ,1671.5623779296875 ,1663.065185546875 ,1761.8521728515625 ,1676.946533203125 ,1676.946533203125 ,1780.859619140625 ,1600.6480712890625 ,1676.946533203125 ,1761.8521728515625 ,1780.859619140625 ,1664.8953857421875 ,1648.9971923828125 ,1658.7738037109375 ,1664.8953857421875 ,1654.421142578125 ,1648.9971923828125 ,1664.8953857421875 ,1652.9853515625 ,1654.421142578125 ,709.255126953125 ,699.9414672851562 ,709.1033325195312 ,709.255126953125 ,722.618408203125 ,699.9414672851562 ,699.9414672851562 ,694.0750732421875 ,709.1033325195312 ,709.1033325195312 ,694.0750732421875 ,691.135009765625 ,255.31051635742188 ,500.4654235839844 ,461.52252197265625 ,1492.576904296875 ,1536.8348388671875 ,1494.8699951171875 ,-145.90042114257812 ,-139.70440673828125 ,-146.8163604736328 ,-145.90042114257812 ,-141.87368774414062 ,-139.70440673828125 ,1690.560302734375 ,1691.7314453125 ,1689.44873046875 ,1685.6358642578125 ,1680.30908203125 ,1685.751220703125 ,1685.6358642578125 ,1678.669921875 ,1680.30908203125 ,1690.9208984375 ,1689.4713134765625 ,1689.8409423828125 ,1608.5009765625 ,1624.34375 ,1635.94482421875 ,1369.0794677734375 ,1410.970458984375 ,1477.3577880859375 ,957.6220092773438 ,1146.6402587890625 ,959.7281494140625 ,1474.0537109375 ,1487.9423828125 ,1409.114990234375 ,886.61474609375 ,926.3306884765625 ,896.6598510742188 ,886.61474609375 ,807.4749145507812 ,796.4855346679688 ,886.61474609375 ,896.6598510742188 ,807.4749145507812 ,886.61474609375 ,909.6098022460938 ,926.3306884765625 ,1651.2750244140625 ,1659.01953125 ,1659.6895751953125 ,1667.91650390625 ,1648.77978515625 ,1641.4759521484375 ,1640.5447998046875 ,1621.678955078125 ,1634.45361328125 ,742.2379760742188 ,722.6234130859375 ,738.90380859375 ,1643.6181640625 ,1651.705078125 ,1650.708740234375 ,1571.35205078125 ,1492.576904296875 ,1571.0238037109375 ,1604.699951171875 ,1594.5146484375 ,1610.2916259765625 ,1609.28369140625 ,1605.918212890625 ,1611.4110107421875 ,-146.8163604736328 ,-142.97039794921875 ,-147.9262237548828 ,-146.8163604736328 ,-139.70440673828125 ,-142.97039794921875 ,1610.6427001953125 ,1677.451904296875 ,1872.0791015625 ,1872.0791015625 ,1677.451904296875 ,2001.811767578125 ,12.802969932556152 ,39.34755325317383 ,-0.439193993806839 ,812.1361083984375 ,821.8519287109375 ,856.873779296875 ,812.1361083984375 ,856.873779296875 ,829.6168212890625 ,1578.2080078125 ,1583.3828125 ,1577.1654052734375 ,1578.2080078125 ,1577.1654052734375 ,1572.86376953125 ,1664.548095703125 ,1666.320068359375 ,1667.19677734375 ,1658.734619140625 ,1652.7958984375 ,1655.255615234375 ,1652.7958984375 ,1653.2535400390625 ,1655.255615234375 ,1652.7958984375 ,1649.3350830078125 ,1653.2535400390625 ,1309.4805908203125 ,1444.7293701171875 ,1651.383056640625 ,1309.4805908203125 ,1651.383056640625 ,1270.929931640625 ,1309.4805908203125 ,1270.929931640625 ,961.9600830078125 ,1309.4805908203125 ,1562.002685546875 ,1444.7293701171875 ,1444.7293701171875 ,1902.2969970703125 ,1651.383056640625 ,1444.7293701171875 ,1562.002685546875 ,1934.1468505859375 ,1444.7293701171875 ,1934.1468505859375 ,1902.2969970703125 ,1677.451904296875 ,1895.0982666015625 ,2001.811767578125 ,1677.451904296875 ,1798.2933349609375 ,1895.0982666015625 ,1677.451904296875 ,1592.6239013671875 ,1798.2933349609375 ,2001.811767578125 ,1895.0982666015625 ,2316.001708984375 ,1620.38330078125 ,1603.897705078125 ,1613.9197998046875 ,1620.38330078125 ,1636.100341796875 ,1622.50927734375 ,1620.38330078125 ,1627.6866455078125 ,1636.100341796875 ,800.7420043945312 ,798.9462280273438 ,803.7136840820312 ,800.7420043945312 ,803.7136840820312 ,814.5217895507812 ,-170.8797149658203 ,-164.67984008789062 ,-172.18809509277344 ,-170.8797149658203 ,-163.5635528564453 ,-164.67984008789062 ,-170.8797149658203 ,-171.90296936035156 ,-163.5635528564453 ,1612.8060302734375 ,1625.635498046875 ,1629.9248046875 ,1661.9881591796875 ,1664.6141357421875 ,1667.7757568359375 ,1661.9881591796875 ,1662.61474609375 ,1664.6141357421875 ,1664.6141357421875 ,1665.9525146484375 ,1667.7757568359375 ,1664.6141357421875 ,1664.8310546875 ,1665.9525146484375 ,12.554376602172852 ,212.82652282714844 ,53.96044158935547 ,212.82652282714844 ,12.554376602172852 ,100.33374786376953 ,1561.940673828125 ,1583.322509765625 ,1568.362060546875 ,1689.956787109375 ,1686.734130859375 ,1686.08740234375 ,1689.956787109375 ,1688.5379638671875 ,1686.734130859375 ,1686.08740234375 ,1688.41552734375 ,1689.956787109375 ,1550.103271484375 ,1552.0093994140625 ,1548.8284912109375 ,1664.6141357421875 ,1662.9305419921875 ,1664.8310546875 ,1662.61474609375 ,1658.14501953125 ,1664.6141357421875 ,1662.61474609375 ,1661.9881591796875 ,1658.14501953125 ,789.5177612304688 ,805.8684692382812 ,797.4121704101562 ,1570.010009765625 ,1592.7005615234375 ,1565.5657958984375 ,1659.01953125 ,1670.4410400390625 ,1659.6895751953125 ,1659.6895751953125 ,1632.160400390625 ,1651.2750244140625 ,1622.7889404296875 ,1628.7613525390625 ,1631.577392578125 ,1622.7889404296875 ,1631.577392578125 ,1633.0850830078125 ,1622.7889404296875 ,1633.0850830078125 ,1632.854248046875 ,1653.3548583984375 ,1646.9783935546875 ,1644.6551513671875 ,1647.4063720703125 ,1645.2266845703125 ,1623.9122314453125 ,1647.4063720703125 ,1653.598388671875 ,1645.2266845703125 ,1647.4063720703125 ,1651.9390869140625 ,1653.598388671875 ,1645.2266845703125 ,1653.598388671875 ,1660.8126220703125 ,1645.2266845703125 ,1660.8126220703125 ,1623.9122314453125 ,-161.47756958007812 ,-158.5688018798828 ,-154.14077758789062 ,-161.47756958007812 ,-154.14077758789062 ,-152.9228973388672 ,-161.47756958007812 ,-152.9228973388672 ,-162.4461212158203 ,-159.94921875 ,-162.4461212158203 ,-152.40850830078125 ,-159.94921875 ,-152.40850830078125 ,-154.27488708496094 ,-162.4461212158203 ,-152.9228973388672 ,-152.40850830078125 ,-152.40850830078125 ,-147.42669677734375 ,-154.27488708496094 ,-152.40850830078125 ,-152.9228973388672 ,-147.42669677734375 ,-147.58274841308594 ,-112.15628051757812 ,-142.41433715820312 ,-142.41433715820312 ,-123.85717010498047 ,-156.66671752929688 ,-156.4678955078125 ,-155.69383239746094 ,-157.5364990234375 ,-172.18809509277344 ,-164.67984008789062 ,-168.5343017578125 ,-164.67984008789062 ,-163.5635528564453 ,-150.75221252441406 ,1690.700439453125 ,1694.8782958984375 ,1679.518310546875 ,1690.700439453125 ,1694.167724609375 ,1694.8782958984375 ,1582.647705078125 ,1572.422119140625 ,1581.5753173828125 ,1582.647705078125 ,1579.477783203125 ,1572.422119140625 ,1581.5753173828125 ,1588.1551513671875 ,1582.647705078125 ,773.294677734375 ,776.696533203125 ,778.2691650390625 ,1619.8695068359375 ,1622.50927734375 ,1629.330810546875 ,1619.8695068359375 ,1629.330810546875 ,1603.6051025390625 ,1619.8695068359375 ,1603.6051025390625 ,1611.40771484375 ,1646.7174072265625 ,1635.9273681640625 ,1646.2232666015625 ,1646.7174072265625 ,1647.802978515625 ,1649.2138671875 ,-142.7968292236328 ,-145.7958221435547 ,-145.95632934570312 ,732.1451416015625 ,771.9223022460938 ,758.327880859375 ,732.1451416015625 ,751.6642456054688 ,771.9223022460938 ,70.96662902832031 ,13.958344459533691 ,80.88017272949219 ,70.96662902832031 ,-168.038330078125 ,13.958344459533691 ,70.96662902832031 ,147.09942626953125 ,-168.038330078125 ,80.88017272949219 ,13.958344459533691 ,-301.7873840332031 ,80.88017272949219 ,-301.7873840332031 ,124.47106170654297 ,50.2431755065918 ,-49.12808609008789 ,-22.31652069091797 ,1572.697509765625 ,1570.904541015625 ,1567.37890625 ,149.82284545898438 ,171.8939208984375 ,144.2041778564453 ,1639.7213134765625 ,1643.2557373046875 ,1637.7437744140625 ,546.88916015625 ,596.9385375976562 ,625.8710327148438 ,546.88916015625 ,592.302978515625 ,596.9385375976562 ,592.302978515625 ,546.88916015625 ,656.5256958007812 ,592.302978515625 ,656.5256958007812 ,696.59814453125 ,1135.334228515625 ,1107.613525390625 ,1110.033203125 ,1135.334228515625 ,1110.033203125 ,1154.2872314453125 ,-140.76263427734375 ,-151.7123565673828 ,-149.80459594726562 ,-151.7123565673828 ,-152.03746032714844 ,-149.80459594726562 ,-151.7123565673828 ,-151.143798828125 ,-152.03746032714844 ,-149.80459594726562 ,-152.03746032714844 ,-153.2115020751953 ,792.85107421875 ,785.9707641601562 ,795.3846435546875 ,-121.79351806640625 ,-122.85227966308594 ,-134.15402221679688 ,1579.9024658203125 ,1601.041015625 ,1586.1710205078125 ,-169.60626220703125 ,-160.13168334960938 ,-162.84446716308594 ,-169.60626220703125 ,-172.62753295898438 ,-166.1901092529297 ,1589.9259033203125 ,1615.714599609375 ,1605.025390625 ,1589.9259033203125 ,1605.025390625 ,1593.8929443359375 ,-7.0689778327941895 ,69.61405181884766 ,-48.14024353027344 ,831.8568725585938 ,873.3203735351562 ,848.0089111328125 ,831.8568725585938 ,849.3843994140625 ,873.3203735351562 ,975.66455078125 ,826.8889770507812 ,996.065185546875 ,59.6855583190918 ,36.951839447021484 ,454.2554016113281 ,59.6855583190918 ,454.2554016113281 ,303.5206604003906 ,-171.6670379638672 ,-172.2712860107422 ,-170.3991241455078 ,-171.6670379638672 ,-172.8136444091797 ,-172.2712860107422 ,-171.6670379638672 ,-170.53453063964844 ,-172.25660705566406 ,-171.6670379638672 ,-172.25660705566406 ,-172.8136444091797 ,-170.3991241455078 ,-172.2712860107422 ,-167.836669921875 ,1516.1270751953125 ,1564.2630615234375 ,1550.125 ,-157.62338256835938 ,-154.70065307617188 ,-130.72903442382812 ,-157.62338256835938 ,-130.72903442382812 ,-79.97222137451172 ,-157.62338256835938 ,-79.97222137451172 ,-103.8460922241211 ,-157.62338256835938 ,-103.8460922241211 ,-99.0303726196289 ,1649.2138671875 ,1647.802978515625 ,1650.55078125 ,1242.9195556640625 ,1358.700927734375 ,1315.80810546875 ,411.1473388671875 ,590.23095703125 ,431.29559326171875 ,431.29559326171875 ,590.23095703125 ,482.605712890625 ,1639.356201171875 ,1648.0936279296875 ,1639.416259765625 ,-157.62338256835938 ,-168.22259521484375 ,-163.9052276611328 ,-157.62338256835938 ,-142.4543914794922 ,-168.22259521484375 ,1695.4520263671875 ,1690.700439453125 ,1692.29931640625 ,-183.16323852539062 ,-191.14854431152344 ,-243.66262817382812 ,1617.8851318359375 ,1605.025390625 ,1626.0413818359375 ,1626.0413818359375 ,1605.025390625 ,1615.714599609375 ,-137.37747192382812 ,-139.0427703857422 ,-137.9709014892578 ,-137.37747192382812 ,-137.9709014892578 ,-138.2211151123047 ,-137.37747192382812 ,-138.2211151123047 ,-138.11166381835938 ,-137.37747192382812 ,-138.11166381835938 ,-139.5277557373047 ,-137.37747192382812 ,-139.5277557373047 ,-147.42669677734375 ,-137.37747192382812 ,-147.42669677734375 ,-139.0427703857422 ,-139.0427703857422 ,-140.2793426513672 ,-137.9709014892578 ,-139.0427703857422 ,-140.76263427734375 ,-140.2793426513672 ,-139.0427703857422 ,-147.42669677734375 ,-143.44833374023438 ,-139.0427703857422 ,-143.44833374023438 ,-140.76263427734375 ,-137.9709014892578 ,-138.47608947753906 ,-138.2211151123047 ,-137.9709014892578 ,-140.2793426513672 ,-139.95550537109375 ,-137.9709014892578 ,-139.95550537109375 ,-138.47608947753906 ,-138.2211151123047 ,-138.95445251464844 ,-138.8913116455078 ,-138.2211151123047 ,-138.47608947753906 ,-138.95445251464844 ,-138.2211151123047 ,-138.8913116455078 ,-138.11166381835938 ,2293.187255859375 ,2009.0777587890625 ,2235.03515625 ,757.1332397460938 ,759.187255859375 ,764.4428100585938 ,757.1332397460938 ,750.8538208007812 ,759.187255859375 ,1759.4949951171875 ,1766.5675048828125 ,1826.246826171875 ,1759.4949951171875 ,1826.246826171875 ,1843.4600830078125 ,1728.110595703125 ,1798.2933349609375 ,1639.8092041015625 ,-217.6927032470703 ,-243.66262817382812 ,-202.57232666015625 ,-217.6927032470703 ,-288.77471923828125 ,-243.66262817382812 ,-217.6927032470703 ,-265.82415771484375 ,-288.77471923828125 ,1553.41455078125 ,1557.295654296875 ,1556.0218505859375 ,1728.110595703125 ,1639.8092041015625 ,1537.597900390625 ,963.9760131835938 ,1173.2772216796875 ,1298.328369140625 ,963.9760131835938 ,1298.328369140625 ,1233.24560546875 ,963.9760131835938 ,1233.24560546875 ,984.8864135742188 ,814.6633911132812 ,817.1439819335938 ,835.6561889648438 ,814.6633911132812 ,835.6561889648438 ,848.6284790039062 ,814.6633911132812 ,792.990234375 ,804.2484741210938 ,814.6633911132812 ,804.2484741210938 ,817.1439819335938 ,733.4481811523438 ,731.4716186523438 ,739.649169921875 ,733.4481811523438 ,725.7775268554688 ,727.0682983398438 ,733.4481811523438 ,727.0682983398438 ,731.4716186523438 ,739.649169921875 ,731.4716186523438 ,745.3248291015625 ,1665.784912109375 ,1664.1138916015625 ,1651.2080078125 ,1665.784912109375 ,1651.2080078125 ,1662.9033203125 ,411.1473388671875 ,200.7797088623047 ,346.9749755859375 ,411.1473388671875 ,384.8097229003906 ,444.6069030761719 ,411.1473388671875 ,346.9749755859375 ,384.8097229003906 ,200.7797088623047 ,225.9130401611328 ,346.9749755859375 ,1649.5989990234375 ,1645.3931884765625 ,1639.3721923828125 ,1662.9033203125 ,1651.2080078125 ,1647.4891357421875 ,1392.46337890625 ,1376.4482421875 ,1453.39306640625 ,1453.39306640625 ,1376.4482421875 ,1477.3577880859375 ,1550.125 ,1540.0787353515625 ,1516.1270751953125 ,778.3737182617188 ,746.6197509765625 ,786.45361328125 ,778.3737182617188 ,729.2923583984375 ,746.6197509765625 ,1639.492919921875 ,1641.852294921875 ,1641.77685546875 ,1659.970947265625 ,1658.8890380859375 ,1655.780517578125 ,1659.970947265625 ,1664.745849609375 ,1658.8890380859375 ,-116.43762969970703 ,-132.90476989746094 ,-146.54104614257812 ,1661.43212890625 ,1661.525634765625 ,1657.7440185546875 ,1661.43212890625 ,1657.0269775390625 ,1653.6058349609375 ,1661.43212890625 ,1657.7440185546875 ,1662.08154296875 ,1661.43212890625 ,1662.08154296875 ,1657.0269775390625 ,-160.13168334960938 ,-169.60626220703125 ,-166.1901092529297 ,-160.13168334960938 ,-139.79461669921875 ,-162.84446716308594 ,814.9298095703125 ,814.5217895507812 ,803.7136840820312 ,1636.418212890625 ,1638.4283447265625 ,1641.852294921875 ,1660.94091796875 ,1663.043212890625 ,1666.635498046875 ,1666.635498046875 ,1672.285888671875 ,1664.3409423828125 ,1666.635498046875 ,1664.3409423828125 ,1660.94091796875 ,1652.7958984375 ,1649.8121337890625 ,1649.3350830078125 ,1826.246826171875 ,1894.6409912109375 ,1843.4600830078125 ,1826.246826171875 ,1766.5675048828125 ,1894.6409912109375 ,877.5236206054688 ,842.20458984375 ,785.1974487304688 ,877.5236206054688 ,798.5071411132812 ,896.6598510742188 ,877.5236206054688 ,785.1974487304688 ,798.5071411132812 ,1675.3055419921875 ,1670.4793701171875 ,1678.16552734375 ,1643.993896484375 ,1643.9893798828125 ,1642.681396484375 ,1477.014404296875 ,1431.1864013671875 ,1394.346435546875 ,1173.2772216796875 ,1348.49267578125 ,1298.328369140625 ,1606.5872802734375 ,1603.8221435546875 ,1602.937255859375 ,1593.73681640625 ,1595.5892333984375 ,1597.8408203125 ,745.3248291015625 ,731.4716186523438 ,739.1574096679688 ,745.3248291015625 ,739.1574096679688 ,759.187255859375 ,1652.356201171875 ,1701.290283203125 ,1768.0631103515625 ,1652.356201171875 ,1768.0631103515625 ,1761.8521728515625 ,1625.635498046875 ,1637.8194580078125 ,1629.9248046875 ,-170.3991241455078 ,-167.836669921875 ,-162.89971923828125 ,796.2474975585938 ,793.1922607421875 ,794.844482421875 ,794.844482421875 ,795.6617431640625 ,796.2474975585938 ,972.8710327148438 ,912.0824584960938 ,894.9439086914062 ,1233.24560546875 ,1403.7037353515625 ,1340.6717529296875 ,1233.24560546875 ,1298.328369140625 ,1403.7037353515625 ,1233.24560546875 ,1340.6717529296875 ,1147.1209716796875 ,1233.24560546875 ,1147.1209716796875 ,984.8864135742188 ,1403.7037353515625 ,1441.8394775390625 ,1340.6717529296875 ,1340.6717529296875 ,1330.0029296875 ,1147.1209716796875 ,1340.6717529296875 ,1439.11962890625 ,1330.0029296875 ,1340.6717529296875 ,1441.8394775390625 ,1439.11962890625 ,1654.4324951171875 ,1651.218505859375 ,1652.6387939453125 ,1551.9730224609375 ,1541.8375244140625 ,1559.9676513671875 ,1559.9676513671875 ,1541.8375244140625 ,1546.02392578125 ,1551.9730224609375 ,1559.9676513671875 ,1555.5506591796875 ,656.5256958007812 ,618.6279907226562 ,696.59814453125 ,546.88916015625 ,700.0632934570312 ,656.5256958007812 ,-191.14854431152344 ,-183.16323852539062 ,-168.16668701171875 ,-191.14854431152344 ,-168.16668701171875 ,-202.57232666015625 ,-191.14854431152344 ,-202.57232666015625 ,-243.66262817382812 ,1677.0831298828125 ,1683.8060302734375 ,1681.99755859375 ,1677.0831298828125 ,1682.325927734375 ,1683.8060302734375 ,757.1332397460938 ,764.4428100585938 ,761.7636108398438 ,1613.6981201171875 ,1595.2255859375 ,1601.3533935546875 ,-148.95811462402344 ,-150.5584259033203 ,-153.44395446777344 ,-148.95811462402344 ,-146.06394958496094 ,-150.5584259033203 ,-148.95811462402344 ,-153.9589385986328 ,-151.51779174804688 ,-150.5584259033203 ,-146.06394958496094 ,-141.97189331054688 ,1652.6387939453125 ,1659.8006591796875 ,1657.06494140625 ,-154.19302368164062 ,-158.5688018798828 ,-154.77008056640625 ,-154.19302368164062 ,-154.14077758789062 ,-158.5688018798828 ,-154.19302368164062 ,-151.7123565673828 ,-154.14077758789062 ,-154.19302368164062 ,-152.8994903564453 ,-151.7123565673828 ,1562.6962890625 ,1571.1533203125 ,1567.772216796875 ,1571.1533203125 ,1571.789794921875 ,1567.772216796875 ,1571.1533203125 ,1562.6962890625 ,1561.3687744140625 ,1635.4149169921875 ,1555.284912109375 ,1581.4505615234375 ,1635.4149169921875 ,1595.8814697265625 ,1555.284912109375 ,1635.4149169921875 ,1581.4505615234375 ,1718.588134765625 ,791.40380859375 ,782.33935546875 ,793.5814208984375 ,793.5814208984375 ,782.33935546875 ,795.55419921875 ,-162.4461212158203 ,-159.94921875 ,-165.09109497070312 ,8.798081398010254 ,91.43526458740234 ,79.7586669921875 ,8.798081398010254 ,-24.25218963623047 ,29.884546279907227 ,91.43526458740234 ,138.4011688232422 ,79.7586669921875 ,967.1039428710938 ,793.8865356445312 ,1152.3909912109375 ,967.1039428710938 ,930.623046875 ,793.8865356445312 ,873.3203735351562 ,874.3985595703125 ,875.56201171875 ,-22.468109130859375 ,14.137516021728516 ,37.52220916748047 ,1655.6431884765625 ,1636.1689453125 ,1692.1318359375 ,1655.6431884765625 ,1649.2877197265625 ,1636.1689453125 ,1655.6431884765625 ,1692.1318359375 ,1649.2877197265625 ,777.0872802734375 ,773.22314453125 ,789.9561767578125 ,777.0872802734375 ,789.9561767578125 ,781.0104370117188 ,1639.727294921875 ,1481.825927734375 ,1590.92431640625 ,781.876953125 ,804.499267578125 ,761.7636108398438 ,781.876953125 ,792.990234375 ,804.499267578125 ,-158.5607147216797 ,-145.90042114257812 ,-147.9262237548828 ,-145.90042114257812 ,-158.5607147216797 ,-141.87368774414062 ,-145.90042114257812 ,-146.8163604736328 ,-147.9262237548828 ,-147.9262237548828 ,-150.95314025878906 ,-158.5607147216797 ,-153.44395446777344 ,-150.1798553466797 ,-158.6798095703125 ,-153.44395446777344 ,-158.6798095703125 ,-163.9052276611328 ,-150.1798553466797 ,-148.68128967285156 ,-158.6798095703125 ,-158.6798095703125 ,-148.68128967285156 ,-154.70065307617188 ,-158.6798095703125 ,-154.70065307617188 ,-163.9052276611328 ,-170.3991241455078 ,-162.89971923828125 ,-164.23593139648438 ,1891.7158203125 ,1833.514404296875 ,1814.4393310546875 ,1932.8714599609375 ,1891.7158203125 ,1946.9520263671875 ,1665.9525146484375 ,1664.970703125 ,1667.7757568359375 ,1665.9525146484375 ,1664.8310546875 ,1664.970703125 ,1648.0936279296875 ,1649.632568359375 ,1649.1888427734375 ,1648.0936279296875 ,1649.1888427734375 ,1645.428466796875 ,1648.0936279296875 ,1645.428466796875 ,1644.410888671875 ,1687.034912109375 ,1687.4100341796875 ,1685.6358642578125 ,1671.78173828125 ,1665.322509765625 ,1673.062744140625 ,1631.9801025390625 ,1622.14599609375 ,1622.7889404296875 ,1622.7889404296875 ,1643.0556640625 ,1631.9801025390625 ,1598.3885498046875 ,1593.8599853515625 ,1597.4324951171875 ,1598.3885498046875 ,1597.4324951171875 ,1606.5816650390625 ,-170.8787078857422 ,-172.3965606689453 ,-168.5343017578125 ,-168.5343017578125 ,-166.89935302734375 ,-170.8787078857422 ,-170.8787078857422 ,-166.89935302734375 ,-167.836669921875 ,1990.0994873046875 ,1940.6337890625 ,2003.5426025390625 ,1990.0994873046875 ,1939.4962158203125 ,1940.6337890625 ,1990.0994873046875 ,2003.5426025390625 ,1939.4962158203125 ,1940.6337890625 ,1917.1875 ,1950.8538818359375 ,1833.514404296875 ,1696.6854248046875 ,1622.8790283203125 ,1598.179443359375 ,1597.0556640625 ,1597.9581298828125 ,1598.179443359375 ,1597.5272216796875 ,1597.0556640625 ,1597.0556640625 ,1598.1248779296875 ,1597.9581298828125 ,1664.970703125 ,1664.8310546875 ,1663.33984375 ,1664.970703125 ,1663.33984375 ,1657.52294921875 ,1630.8231201171875 ,1627.878662109375 ,1623.6824951171875 ,1630.8231201171875 ,1623.6824951171875 ,1627.998046875 ,1630.8231201171875 ,1643.3203125 ,1627.878662109375 ,-134.15402221679688 ,-122.85227966308594 ,-138.46212768554688 ,-134.15402221679688 ,-138.46212768554688 ,-138.8220977783203 ,-99.0303726196289 ,-103.8460922241211 ,-46.94858169555664 ,-99.0303726196289 ,-66.06815338134766 ,-99.30792999267578 ,-99.0303726196289 ,-46.94858169555664 ,-66.06815338134766 ,807.87060546875 ,814.20654296875 ,851.257080078125 ,807.87060546875 ,851.257080078125 ,851.3971557617188 ,807.87060546875 ,851.3971557617188 ,846.5791625976562 ,807.87060546875 ,777.0872802734375 ,814.20654296875 ,814.20654296875 ,777.0872802734375 ,808.1926879882812 ,814.20654296875 ,808.1926879882812 ,900.3047485351562 ,704.05419921875 ,696.7554931640625 ,724.1598510742188 ,1639.7213134765625 ,1651.2288818359375 ,1643.2557373046875 ,1639.7213134765625 ,1638.164794921875 ,1651.2288818359375 ,1038.2100830078125 ,1012.0601196289062 ,1011.173583984375 ,1659.3050537109375 ,1645.4649658203125 ,1651.2080078125 ,1659.3050537109375 ,1651.2080078125 ,1663.552978515625 ,1567.37890625 ,1570.904541015625 ,1565.482666015625 ,212.82652282714844 ,200.7797088623047 ,411.1473388671875 ,1544.0799560546875 ,1542.2869873046875 ,1548.867919921875 ,1544.0799560546875 ,1548.867919921875 ,1549.0443115234375 ,1593.193115234375 ,1586.2974853515625 ,1593.8599853515625 ,1593.193115234375 ,1591.1419677734375 ,1586.2974853515625 ,1593.193115234375 ,1593.8599853515625 ,1598.0413818359375 ,1593.193115234375 ,1598.0413818359375 ,1591.1419677734375 ,-208.45709228515625 ,-109.26838684082031 ,-159.0187530517578 ,-208.45709228515625 ,-112.88627624511719 ,-109.26838684082031 ,-137.98291015625 ,-138.60194396972656 ,-138.47950744628906 ,-166.76596069335938 ,-165.97145080566406 ,-142.41433715820312 ,-166.76596069335938 ,-142.41433715820312 ,-162.0017547607422 ,-142.41433715820312 ,-156.66671752929688 ,-162.0017547607422 ,-142.41433715820312 ,-165.97145080566406 ,-147.58274841308594 ,-156.66671752929688 ,-146.23471069335938 ,-162.0017547607422 ,1607.9539794921875 ,1617.8865966796875 ,1618.880615234375 ,1607.9539794921875 ,1618.880615234375 ,1607.8009033203125 ,1537.4833984375 ,1534.9771728515625 ,1532.41796875 ,1598.179443359375 ,1597.9581298828125 ,1600.48583984375 ,1410.970458984375 ,1369.0794677734375 ,1408.5050048828125 ,1408.5050048828125 ,1641.736083984375 ,1410.970458984375 ,1408.5050048828125 ,1369.0794677734375 ,1422.2646484375 ,1641.736083984375 ,1408.5050048828125 ,1422.2646484375 ,1536.8348388671875 ,1538.7110595703125 ,1528.123779296875 ,1536.8348388671875 ,1528.123779296875 ,1494.8699951171875 ,1536.8348388671875 ,1563.31787109375 ,1538.7110595703125 ,792.85107421875 ,800.04736328125 ,798.400390625 ,1827.9642333984375 ,1635.5401611328125 ,1568.8011474609375 ,158.07339477539062 ,147.7543487548828 ,179.83291625976562 ,158.07339477539062 ,125.16410064697266 ,147.7543487548828 ,158.07339477539062 ,179.83291625976562 ,179.1769561767578 ,147.7543487548828 ,125.16410064697266 ,102.53659057617188 ,179.83291625976562 ,184.67359924316406 ,179.1769561767578 ,179.83291625976562 ,147.7543487548828 ,171.8939208984375 ,179.83291625976562 ,171.8939208984375 ,184.67359924316406 ,1598.0413818359375 ,1597.2001953125 ,1591.1419677734375 ,-145.7958221435547 ,-150.48141479492188 ,-148.954833984375 ,-145.7958221435547 ,-148.954833984375 ,-146.486328125 ,-148.954833984375 ,-146.34799194335938 ,-146.486328125 ,-166.1901092529297 ,-173.44215393066406 ,-172.63314819335938 ,1622.7889404296875 ,1632.854248046875 ,1638.11376953125 ,1622.7889404296875 ,1638.11376953125 ,1643.0556640625 ,1593.2496337890625 ,1585.3182373046875 ,1596.295654296875 ,1596.295654296875 ,1597.343994140625 ,1593.2496337890625 ,1639.3721923828125 ,1645.3931884765625 ,1642.0712890625 ,384.8097229003906 ,461.52252197265625 ,448.892578125 ,384.8097229003906 ,448.892578125 ,444.6069030761719 ,1732.4056396484375 ,1645.6033935546875 ,1713.242431640625 ,1732.4056396484375 ,1749.2783203125 ,1750.3934326171875 ,1732.4056396484375 ,1750.3934326171875 ,1712.3887939453125 ,1732.4056396484375 ,1713.242431640625 ,1749.2783203125 ,1732.4056396484375 ,1712.3887939453125 ,1645.6033935546875 ,1749.2783203125 ,1766.5675048828125 ,1750.3934326171875 ,1749.2783203125 ,1810.5904541015625 ,1766.5675048828125 ,-83.364990234375 ,-93.32140350341797 ,-92.26326751708984 ,-99.30792999267578 ,-66.06815338134766 ,-46.94858169555664 ,-108.06562805175781 ,-69.6546859741211 ,-108.51872253417969 ,-108.06562805175781 ,-108.51872253417969 ,-142.4543914794922 ,1368.138671875 ,1339.8623046875 ,1436.84033203125 ,-131.700927734375 ,-123.30195617675781 ,-141.19369506835938 ,-123.30195617675781 ,-113.69429779052734 ,-141.19369506835938 ,1671.78515625 ,1667.4793701171875 ,1667.297607421875 ,1685.1209716796875 ,1684.1480712890625 ,1682.7294921875 ,-39.66056442260742 ,12.87821102142334 ,-48.15782165527344 ,-48.15782165527344 ,-106.98082733154297 ,-39.66056442260742 ,1667.8065185546875 ,1661.302978515625 ,1646.99853515625 ,542.66552734375 ,778.0476684570312 ,393.78424072265625 ,1574.69580078125 ,1586.2974853515625 ,1585.680908203125 ,829.6168212890625 ,856.873779296875 ,866.286376953125 ,829.6168212890625 ,827.5255126953125 ,805.8684692382812 ,829.6168212890625 ,866.286376953125 ,827.5255126953125 ,978.31494140625 ,978.5054931640625 ,968.7680053710938 ,978.31494140625 ,966.2996215820312 ,978.5054931640625 ,968.7680053710938 ,978.5054931640625 ,975.6517333984375 ,968.7680053710938 ,975.6517333984375 ,965.666748046875 ,852.0170288085938 ,854.9761962890625 ,827.7611083984375 ,1675.038330078125 ,1664.204345703125 ,1670.7144775390625 ,1469.92626953125 ,1538.773681640625 ,1545.984375 ,1654.347412109375 ,1651.705078125 ,1650.6107177734375 ,1654.347412109375 ,1657.0157470703125 ,1651.705078125 ,1654.347412109375 ,1657.659912109375 ,1657.0157470703125 ,1629.9248046875 ,1614.6343994140625 ,1612.8060302734375 ,892.542236328125 ,885.4091796875 ,875.2785034179688 ,892.542236328125 ,875.2785034179688 ,907.8963012695312 ,1654.254150390625 ,1655.255615234375 ,1653.2535400390625 ,-58.478668212890625 ,12.802969932556152 ,-0.439193993806839 ,-58.478668212890625 ,-49.69411087036133 ,-103.25717163085938 ,-58.478668212890625 ,-0.439193993806839 ,-49.69411087036133 ,1338.5748291015625 ,1101.100830078125 ,1385.2088623046875 ,1585.680908203125 ,1586.2974853515625 ,1587.00634765625 ,1585.680908203125 ,1587.00634765625 ,1574.69580078125 ,850.2197875976562 ,840.1779174804688 ,840.7582397460938 ,840.1779174804688 ,836.3881225585938 ,840.7582397460938 ,1643.2557373046875 ,1642.044677734375 ,1637.7437744140625 ,1592.6134033203125 ,1615.5040283203125 ,1649.01171875 ,-119.7644271850586 ,-139.79461669921875 ,-116.43907928466797 ,-119.7644271850586 ,-138.59707641601562 ,-139.79461669921875 ,1317.367431640625 ,1204.0008544921875 ,1298.5340576171875 ,1669.09912109375 ,1663.552978515625 ,1651.2080078125 ,1173.2772216796875 ,1009.453369140625 ,1223.4453125 ,804.499267578125 ,792.990234375 ,843.0507202148438 ,1563.31787109375 ,1546.6407470703125 ,1538.7110595703125 ,-85.63018035888672 ,-86.76862335205078 ,-87.42422485351562 ,-90.04814910888672 ,-90.16954040527344 ,-86.76862335205078 ,757.044189453125 ,740.1326293945312 ,755.9078369140625 ,770.588134765625 ,775.0728759765625 ,765.1046752929688 ,775.0728759765625 ,763.2747192382812 ,765.1046752929688 ,-141.87368774414062 ,-158.5607147216797 ,-138.25650024414062 ,-141.87368774414062 ,-138.25650024414062 ,-137.81597900390625 ,848.0054931640625 ,843.2396240234375 ,834.166015625 ,-160.13168334960938 ,-166.1901092529297 ,-160.60240173339844 ,-160.13168334960938 ,-160.60240173339844 ,-149.2166748046875 ,1223.4453125 ,1009.453369140625 ,1006.2012939453125 ,1223.4453125 ,1006.2012939453125 ,1179.5418701171875 ,1691.0614013671875 ,1692.1171875 ,1692.2333984375 ,1692.2333984375 ,1692.54150390625 ,1691.0614013671875 ,1691.0614013671875 ,1692.54150390625 ,1690.3802490234375 ,-49.12808609008789 ,-77.23518371582031 ,-48.0750732421875 ,-49.12808609008789 ,-48.0750732421875 ,-22.31652069091797 ,-49.12808609008789 ,11.559826850891113 ,-77.23518371582031 ,1658.1865234375 ,1663.5673828125 ,1665.784912109375 ,1663.5673828125 ,1658.1865234375 ,1669.09912109375 ,1663.5673828125 ,1664.1138916015625 ,1665.784912109375 ,1663.5673828125 ,1669.09912109375 ,1664.1138916015625 ,1665.784912109375 ,1662.61865234375 ,1658.1865234375 ,1673.2763671875 ,1674.09033203125 ,1667.9810791015625 ,1422.2646484375 ,1451.8507080078125 ,1641.736083984375 ,-145.88516235351562 ,-146.34799194335938 ,-148.954833984375 ,-145.88516235351562 ,-148.954833984375 ,-150.79893493652344 ,-145.88516235351562 ,-146.0294189453125 ,-146.34799194335938 ,2.2539000511169434 ,-0.439193993806839 ,39.34755325317383 ,-13.414265632629395 ,-0.7145509719848633 ,-22.144731521606445 ,-49.69411087036133 ,-13.414265632629395 ,-56.86187744140625 ,743.750244140625 ,692.4243774414062 ,683.6290893554688 ,1207.198486328125 ,1312.385986328125 ,1350.0614013671875 ,1584.520263671875 ,1594.5146484375 ,1592.2626953125 ,1584.520263671875 ,1582.167724609375 ,1594.5146484375 ,1569.1812744140625 ,1566.099365234375 ,1577.2099609375 ,1569.1812744140625 ,1577.2099609375 ,1571.789794921875 ,1687.320068359375 ,1689.8233642578125 ,1685.1209716796875 ,-162.84446716308594 ,-139.79461669921875 ,-138.59707641601562 ,12.554376602172852 ,-106.98082733154297 ,100.33374786376953 ,1593.8929443359375 ,1589.718017578125 ,1589.9259033203125 ,1605.025390625 ,1597.4324951171875 ,1593.8929443359375 ,1605.025390625 ,1607.154296875 ,1597.4324951171875 ,1363.8858642578125 ,1536.750244140625 ,1523.9736328125 ,1363.8858642578125 ,1223.4453125 ,1299.4256591796875 ,1363.8858642578125 ,1299.4256591796875 ,1536.750244140625 ,1223.4453125 ,1179.5418701171875 ,1299.4256591796875 ,1011.23486328125 ,1042.73974609375 ,933.3903198242188 ,1011.23486328125 ,1178.7838134765625 ,1042.73974609375 ,933.3903198242188 ,1042.73974609375 ,908.4688720703125 ,933.3903198242188 ,908.4688720703125 ,792.0645141601562 ,1008.1751708984375 ,965.7979125976562 ,988.9864501953125 ,-106.98082733154297 ,-3.2561590671539307 ,100.33374786376953 ,1689.8409423828125 ,1689.8233642578125 ,1691.309814453125 ,1561.04443359375 ,1556.9638671875 ,1569.2528076171875 ,1670.7144775390625 ,1680.5875244140625 ,1681.9757080078125 ,1670.7144775390625 ,1662.5382080078125 ,1680.5875244140625 ,1657.24658203125 ,1662.020263671875 ,1662.9674072265625 ,461.52252197265625 ,458.4006042480469 ,448.892578125 ,1725.84033203125 ,1600.6480712890625 ,1780.859619140625 ,1725.84033203125 ,1571.296142578125 ,1600.6480712890625 ,1633.216552734375 ,1642.0909423828125 ,1609.6234130859375 ,1633.2303466796875 ,1618.880615234375 ,1645.1536865234375 ,1591.97265625 ,1589.1885986328125 ,1594.349609375 ,1591.97265625 ,1594.349609375 ,1595.722412109375 ,1591.97265625 ,1595.722412109375 ,1594.73974609375 ,1591.97265625 ,1594.73974609375 ,1589.362060546875 ,1620.9952392578125 ,1623.7742919921875 ,1629.9200439453125 ,1562.0313720703125 ,1558.181884765625 ,1556.96240234375 ,713.3721923828125 ,744.9285278320312 ,798.5071411132812 ,713.3721923828125 ,798.5071411132812 ,719.7808227539062 ,713.3721923828125 ,716.3633422851562 ,744.9285278320312 ,1683.29248046875 ,1670.7144775390625 ,1681.9757080078125 ,1683.29248046875 ,1681.9757080078125 ,1690.700439453125 ,43.1501350402832 ,67.66964721679688 ,57.81092834472656 ,67.66964721679688 ,4.923157215118408 ,55.008338928222656 ,67.66964721679688 ,68.86013793945312 ,57.81092834472656 ,67.66964721679688 ,55.008338928222656 ,68.86013793945312 ,1652.5123291015625 ,1657.1484375 ,1651.13427734375 ,1652.5123291015625 ,1669.4385986328125 ,1657.1484375 ,1657.1484375 ,1649.50341796875 ,1651.13427734375 ,1651.13427734375 ,1636.100341796875 ,1652.5123291015625 ,1651.13427734375 ,1649.50341796875 ,1633.53173828125 ,1651.13427734375 ,1633.53173828125 ,1636.100341796875 ,1363.837646484375 ,1240.89453125 ,1123.979736328125 ,1363.837646484375 ,1123.979736328125 ,1338.5748291015625 ,729.5888061523438 ,739.697509765625 ,693.4887084960938 ,729.5888061523438 ,804.3577270507812 ,739.697509765625 ,1551.9730224609375 ,1550.7193603515625 ,1541.8375244140625 ,-132.90476989746094 ,-103.25717163085938 ,-131.21571350097656 ,1664.063232421875 ,1662.020263671875 ,1662.50830078125 ,1664.063232421875 ,1662.50830078125 ,1666.826416015625 ,1634.6875 ,1633.1820068359375 ,1626.0142822265625 ,1633.1820068359375 ,1634.6875 ,1635.9273681640625 ,750.1624145507812 ,387.1172790527344 ,552.5986328125 ,792.990234375 ,787.5003662109375 ,804.2484741210938 ,1801.1998291015625 ,1725.84033203125 ,1946.9520263671875 ,1801.1998291015625 ,1946.9520263671875 ,1891.7158203125 ,1801.1998291015625 ,1891.7158203125 ,1814.4393310546875 ,-155.43112182617188 ,-158.23422241210938 ,-150.6800994873047 ,-155.43112182617188 ,-150.6800994873047 ,-150.59349060058594 ,-155.43112182617188 ,-150.59349060058594 ,-158.23422241210938 ,-150.6800994873047 ,-164.6094970703125 ,-158.22862243652344 ,-150.6800994873047 ,-158.23422241210938 ,-164.6094970703125 ,-150.6800994873047 ,-146.49044799804688 ,-150.59349060058594 ,1558.35107421875 ,1556.9703369140625 ,1565.1370849609375 ,1639.365234375 ,1647.197021484375 ,1645.9932861328125 ,1639.365234375 ,1645.9932861328125 ,1637.3267822265625 ,171.44357299804688 ,157.5376434326172 ,165.0082244873047 ,165.0082244873047 ,157.5376434326172 ,157.475830078125 ,1563.7801513671875 ,1572.1949462890625 ,1565.1370849609375 ,1684.94921875 ,1686.7393798828125 ,1686.4478759765625 ,1801.1998291015625 ,1571.296142578125 ,1725.84033203125 ,1659.970947265625 ,1660.91064453125 ,1664.745849609375 ,1654.421142578125 ,1651.3529052734375 ,1646.78857421875 ,1651.3529052734375 ,1652.9853515625 ,1646.78857421875 ,1651.3529052734375 ,1654.421142578125 ,1652.9853515625 ,1232.447021484375 ,1258.1793212890625 ,1076.6728515625 ,1232.447021484375 ,1136.8084716796875 ,1204.0008544921875 ,1232.447021484375 ,1076.6728515625 ,1136.8084716796875 ,1232.447021484375 ,1204.0008544921875 ,1258.1793212890625 ,1258.1793212890625 ,1204.0008544921875 ,1477.02099609375 ,1369.2298583984375 ,1363.8858642578125 ,1512.614501953125 ,1369.2298583984375 ,1512.614501953125 ,1348.49267578125 ,756.6593627929688 ,774.6493530273438 ,813.8816528320312 ,756.6593627929688 ,793.8555297851562 ,778.0476684570312 ,718.0975952148438 ,713.1646728515625 ,717.6968383789062 ,718.0975952148438 ,717.6968383789062 ,723.9068603515625 ,718.0975952148438 ,692.4243774414062 ,713.1646728515625 ,718.0975952148438 ,693.88330078125 ,692.4243774414062 ,718.0975952148438 ,723.9068603515625 ,693.88330078125 ,713.1646728515625 ,692.4243774414062 ,717.6968383789062 ,-49.9060173034668 ,-67.80812072753906 ,-22.144731521606445 ,-49.9060173034668 ,-119.6897964477539 ,-67.80812072753906 ,-49.9060173034668 ,-21.956390380859375 ,-119.6897964477539 ,-49.9060173034668 ,-22.144731521606445 ,-21.956390380859375 ,-67.80812072753906 ,-85.8126449584961 ,-22.144731521606445 ,-22.144731521606445 ,-85.8126449584961 ,-13.414265632629395 ,1581.4505615234375 ,1487.827392578125 ,1494.3138427734375 ,1581.4505615234375 ,1488.171630859375 ,1487.827392578125 ,867.0675048828125 ,747.9818115234375 ,841.958740234375 ,1607.81689453125 ,1627.227294921875 ,1615.5350341796875 ,1607.81689453125 ,1618.046630859375 ,1627.227294921875 ,1537.8978271484375 ,1540.3974609375 ,1532.41796875 ,225.7664794921875 ,221.2639923095703 ,481.72210693359375 ,1565.7703857421875 ,1563.897216796875 ,1569.8341064453125 ,963.122314453125 ,1001.5288696289062 ,892.8511962890625 ,963.122314453125 ,892.8511962890625 ,1081.4989013671875 ,799.7362060546875 ,790.0026245117188 ,777.08203125 ,799.7362060546875 ,777.08203125 ,801.1747436523438 ,1608.087646484375 ,1617.1231689453125 ,1611.4110107421875 ,1634.6875 ,1636.0384521484375 ,1635.9273681640625 ,1615.5040283203125 ,1622.7177734375 ,1649.01171875 ,1615.5040283203125 ,1588.199462890625 ,1651.3546142578125 ,1615.5040283203125 ,1651.3546142578125 ,1622.7177734375 ,1662.3084716796875 ,1659.9517822265625 ,1655.9959716796875 ,1662.3084716796875 ,1655.9959716796875 ,1657.7269287109375 ,144.2041778564453 ,130.14859008789062 ,149.82284545898438 ,144.2041778564453 ,102.53659057617188 ,130.14859008789062 ,144.2041778564453 ,147.7543487548828 ,102.53659057617188 ,144.2041778564453 ,171.8939208984375 ,147.7543487548828 ,885.4091796875 ,892.542236328125 ,930.5149536132812 ,859.4566650390625 ,846.870849609375 ,847.5123291015625 ,784.7091674804688 ,781.025146484375 ,795.6617431640625 ,795.6617431640625 ,794.844482421875 ,784.7091674804688 ,8.798081398010254 ,29.884546279907227 ,91.43526458740234 ,1409.114990234375 ,1324.3756103515625 ,1474.0537109375 ,2009.0777587890625 ,1907.8543701171875 ,2235.03515625 ,-153.9589385986328 ,-154.53662109375 ,-151.51779174804688 ,1595.7293701171875 ,1713.242431640625 ,1645.6033935546875 ,1595.7293701171875 ,1547.40478515625 ,1713.242431640625 ,1595.7293701171875 ,1359.5948486328125 ,1547.40478515625 ,1586.39990234375 ,1563.536865234375 ,1571.6982421875 ,1586.39990234375 ,1571.6982421875 ,1584.6922607421875 ,1586.39990234375 ,1584.6922607421875 ,1588.5467529296875 ,-164.6094970703125 ,-166.89935302734375 ,-158.22862243652344 ,-164.6094970703125 ,-167.836669921875 ,-166.89935302734375 ,-164.6094970703125 ,-158.23422241210938 ,-167.836669921875 ,68.86013793945312 ,45.33297348022461 ,70.74286651611328 ,70.74286651611328 ,45.33297348022461 ,58.55487060546875 ,-156.71910095214844 ,-154.3759307861328 ,-153.44960021972656 ,2119.65625 ,1980.4984130859375 ,1902.2969970703125 ,2119.65625 ,1902.2969970703125 ,2346.43994140625 ,1663.33984375 ,1667.665283203125 ,1665.8795166015625 ,1663.33984375 ,1665.8795166015625 ,1657.8052978515625 ,1654.347412109375 ,1654.3341064453125 ,1657.659912109375 ,1654.3341064453125 ,1660.7755126953125 ,1657.659912109375 ,1603.496337890625 ,1618.046630859375 ,1607.81689453125 ,1581.4888916015625 ,1588.3834228515625 ,1614.396728515625 ,1687.034912109375 ,1685.751220703125 ,1688.627197265625 ,1687.034912109375 ,1685.6358642578125 ,1685.751220703125 ,-138.46212768554688 ,-139.89889526367188 ,-138.8220977783203 ,777.0872802734375 ,809.3809204101562 ,808.1926879882812 ,777.0872802734375 ,781.0104370117188 ,809.3809204101562 ,1649.8121337890625 ,1638.38623046875 ,1649.3350830078125 ,966.7046508789062 ,990.3247680664062 ,965.6051025390625 ,1541.7872314453125 ,1536.6990966796875 ,1541.107177734375 ,1541.107177734375 ,1536.6990966796875 ,1543.718505859375 ,804.499267578125 ,784.0744018554688 ,761.7636108398438 ,804.499267578125 ,787.9410400390625 ,784.0744018554688 ,826.8889770507812 ,961.0006713867188 ,596.9385375976562 ,1603.9329833984375 ,1598.0146484375 ,1591.425537109375 ,1676.636474609375 ,1678.5303955078125 ,1673.2105712890625 ,1676.636474609375 ,1679.259033203125 ,1678.5303955078125 ,1666.1053466796875 ,1637.8812255859375 ,1668.6605224609375 ,1028.039306640625 ,1070.3936767578125 ,1068.9901123046875 ,676.4495849609375 ,774.6493530273438 ,756.6593627929688 ,1408.5682373046875 ,1491.1573486328125 ,1444.950927734375 ,1408.5682373046875 ,1444.950927734375 ,1416.5341796875 ,1667.665283203125 ,1664.8310546875 ,1662.9305419921875 ,-136.6942596435547 ,-395.974853515625 ,-376.84521484375 ,-136.6942596435547 ,-301.7873840332031 ,-395.974853515625 ,-136.6942596435547 ,-376.84521484375 ,-271.23895263671875 ,1548.560302734375 ,1548.9249267578125 ,1546.3587646484375 ,1588.2427978515625 ,1573.8131103515625 ,1561.707763671875 ,1588.2427978515625 ,1589.48583984375 ,1573.8131103515625 ,1601.72216796875 ,1609.4886474609375 ,1616.6317138671875 ,1609.4886474609375 ,1623.7159423828125 ,1616.6317138671875 ,1687.6025390625 ,1686.6595458984375 ,1688.38720703125 ,1687.6025390625 ,1688.736572265625 ,1686.5401611328125 ,1687.6025390625 ,1686.5401611328125 ,1686.6595458984375 ,1687.6025390625 ,1688.38720703125 ,1688.736572265625 ,1686.6595458984375 ,1687.455322265625 ,1688.38720703125 ,-97.04484558105469 ,-105.42487335205078 ,-123.86084747314453 ,-97.04484558105469 ,-101.0987777709961 ,-83.364990234375 ,-97.04484558105469 ,-123.86084747314453 ,-101.0987777709961 ,14.137516021728516 ,6.3370041847229 ,38.12131881713867 ,6.3370041847229 ,-48.63685607910156 ,13.099784851074219 ,6.3370041847229 ,13.099784851074219 ,38.12131881713867 ,-145.84243774414062 ,-141.91162109375 ,-145.3284912109375 ,-141.91162109375 ,-145.95632934570312 ,-145.3284912109375 ,1613.982666015625 ,1618.32177734375 ,1637.375 ,1613.982666015625 ,1637.375 ,1617.992431640625 ,1618.32177734375 ,1643.3487548828125 ,1637.375 ,1685.785888671875 ,1685.358154296875 ,1683.764404296875 ,454.2554016113281 ,198.62681579589844 ,202.90794372558594 ,806.5791015625 ,800.8710327148438 ,765.2786865234375 ,1667.9810791015625 ,1675.5518798828125 ,1672.770751953125 ,1667.9810791015625 ,1674.09033203125 ,1675.5518798828125 ,814.6633911132812 ,824.2406616210938 ,792.990234375 ,832.3193969726562 ,807.5975952148438 ,814.1434326171875 ,840.5704345703125 ,854.8204956054688 ,833.7054443359375 ,840.5704345703125 ,832.3193969726562 ,854.8204956054688 ,1575.0830078125 ,1591.826904296875 ,1583.346435546875 ,894.9195556640625 ,965.666748046875 ,774.2960205078125 ,754.8847045898438 ,740.1326293945312 ,757.044189453125 ,1685.1209716796875 ,1682.7294921875 ,1687.320068359375 ,1585.217041015625 ,1559.339111328125 ,1566.546630859375 ,1676.400634765625 ,1673.615966796875 ,1675.341064453125 ,1210.17138671875 ,1149.0843505859375 ,1285.7158203125 ,1210.17138671875 ,1285.7158203125 ,1249.8555908203125 ,-146.0294189453125 ,-146.309814453125 ,-146.34799194335938 ,-146.0294189453125 ,-145.88516235351562 ,-144.49041748046875 ,-146.0294189453125 ,-144.49041748046875 ,-146.309814453125 ,-166.89935302734375 ,-168.5343017578125 ,-158.22862243652344 ,1434.8817138671875 ,1465.8497314453125 ,1474.0537109375 ,1434.8817138671875 ,1436.84033203125 ,1465.8497314453125 ,1434.8817138671875 ,1474.0537109375 ,1324.3756103515625 ,1434.8817138671875 ,1324.3756103515625 ,1368.138671875 ,1434.8817138671875 ,1368.138671875 ,1436.84033203125 ,1624.34375 ,1627.1104736328125 ,1635.94482421875 ,843.8851318359375 ,851.4752197265625 ,853.9212036132812 ,1648.77978515625 ,1701.290283203125 ,1652.356201171875 ,1648.77978515625 ,1652.356201171875 ,1641.4759521484375 ,867.7277221679688 ,821.3425903320312 ,890.0218505859375 ,70.07876586914062 ,58.55487060546875 ,51.06891632080078 ,-141.20297241210938 ,-149.2166748046875 ,-123.86084747314453 ,1675.254150390625 ,1675.984375 ,1674.537353515625 ,1675.984375 ,1675.1297607421875 ,1674.537353515625 ,1675.984375 ,1678.8447265625 ,1675.1297607421875 ,1674.537353515625 ,1675.1297607421875 ,1674.2576904296875 ,1690.7293701171875 ,1688.93359375 ,1693.0804443359375 ,1688.93359375 ,1689.44873046875 ,1693.0804443359375 ,1664.745849609375 ,1662.7359619140625 ,1658.8890380859375 ,-10.222365379333496 ,-47.91132736206055 ,-6.674344062805176 ,-10.222365379333496 ,-45.470542907714844 ,-47.91132736206055 ,-6.674344062805176 ,14.08456802368164 ,-8.213500022888184 ,-48.15782165527344 ,12.87821102142334 ,126.56841278076172 ,-48.15782165527344 ,126.56841278076172 ,-3.2561590671539307 ,1558.35107421875 ,1552.678466796875 ,1560.2164306640625 ,1689.8409423828125 ,1692.026123046875 ,1690.9208984375 ,1689.8409423828125 ,1691.309814453125 ,1692.026123046875 ,-90.81015014648438 ,-74.04899597167969 ,-112.6689453125 ,-147.9262237548828 ,-142.97039794921875 ,-145.88516235351562 ,-142.97039794921875 ,-143.8408203125 ,-145.88516235351562 ,836.4472045898438 ,876.696044921875 ,808.3765869140625 ,836.4472045898438 ,887.5587158203125 ,876.696044921875 ,836.4472045898438 ,885.3508911132812 ,887.5587158203125 ,-138.8913116455078 ,-138.95445251464844 ,-138.12728881835938 ,-138.8913116455078 ,-138.8220977783203 ,-140.01162719726562 ,-138.8913116455078 ,-138.12728881835938 ,-138.8220977783203 ,-138.8913116455078 ,-140.01162719726562 ,-139.8701171875 ,-138.8913116455078 ,-139.8701171875 ,-138.11166381835938 ,-138.95445251464844 ,-138.60194396972656 ,-138.12728881835938 ,-138.95445251464844 ,-138.47950744628906 ,-138.60194396972656 ,-138.95445251464844 ,-138.47608947753906 ,-138.47950744628906 ,1567.5185546875 ,1593.3319091796875 ,1603.6051025390625 ,1798.2933349609375 ,1907.8543701171875 ,2009.0777587890625 ,1798.2933349609375 ,2009.0777587890625 ,1895.0982666015625 ,797.4121704101562 ,801.7922973632812 ,783.3544921875 ,-159.94921875 ,-154.27488708496094 ,-154.72377014160156 ,1594.9661865234375 ,1594.349609375 ,1590.654052734375 ,1594.9661865234375 ,1593.8614501953125 ,1556.5546875 ,1594.9661865234375 ,1590.654052734375 ,1593.8614501953125 ,1641.4759521484375 ,1652.356201171875 ,1652.3216552734375 ,431.29559326171875 ,482.605712890625 ,495.27227783203125 ,790.7344360351562 ,827.5490112304688 ,814.464111328125 ,790.7344360351562 ,777.0218505859375 ,827.5490112304688 ,827.5490112304688 ,777.0218505859375 ,778.3938598632812 ,1667.8065185546875 ,1646.99853515625 ,1654.319580078125 ,1668.416259765625 ,1664.8988037109375 ,1667.962646484375 ,50.2431755065918 ,54.11753845214844 ,60.37742233276367 ,50.2431755065918 ,51.06891632080078 ,54.11753845214844 ,50.2431755065918 ,8.591601371765137 ,51.06891632080078 ,1605.64599609375 ,1625.792724609375 ,1613.7576904296875 ,1550.125 ,1564.2630615234375 ,1574.69580078125 ,51.283111572265625 ,84.2657470703125 ,128.33255004882812 ,128.33255004882812 ,84.2657470703125 ,126.69802856445312 ,128.33255004882812 ,126.69802856445312 ,154.77740478515625 ,1639.416259765625 ,1637.7620849609375 ,1639.356201171875 ,1639.356201171875 ,1637.7620849609375 ,1627.7117919921875 ,1646.7701416015625 ,1644.28955078125 ,1642.2862548828125 ,1646.7701416015625 ,1645.4742431640625 ,1644.28955078125 ,1422.2646484375 ,1369.0794677734375 ,1371.5784912109375 ,-21.310529708862305 ,-3.9420969486236572 ,-42.26219940185547 ,175.15267944335938 ,130.8192138671875 ,65.91230010986328 ,175.15267944335938 ,128.33255004882812 ,130.8192138671875 ,1078.2822265625 ,1042.39111328125 ,1052.5938720703125 ,1078.2822265625 ,1052.5938720703125 ,1088.1229248046875 ,764.2892456054688 ,799.6619262695312 ,761.9024047851562 ,888.6819458007812 ,945.4508056640625 ,1017.6915893554688 ,766.7696533203125 ,821.8519287109375 ,812.1361083984375 ,-140.2793426513672 ,-141.76776123046875 ,-139.95550537109375 ,592.302978515625 ,696.59814453125 ,616.7412109375 ,1581.5753173828125 ,1559.339111328125 ,1585.217041015625 ,1581.5753173828125 ,1572.422119140625 ,1559.339111328125 ,783.279052734375 ,775.0728759765625 ,770.588134765625 ,783.279052734375 ,770.588134765625 ,780.8228759765625 ,783.279052734375 ,778.2691650390625 ,775.0728759765625 ,776.696533203125 ,764.2892456054688 ,778.2691650390625 ,843.5563354492188 ,848.3840942382812 ,848.0054931640625 ,847.5123291015625 ,844.1985473632812 ,835.4942016601562 ,1683.382080078125 ,1681.99755859375 ,1683.823974609375 ,1683.382080078125 ,1682.6153564453125 ,1679.02587890625 ,1679.02587890625 ,1682.6153564453125 ,1679.267333984375 ,1684.946044921875 ,2080.4912109375 ,1870.11962890625 ,1648.0936279296875 ,1656.053955078125 ,1649.632568359375 ,1648.0936279296875 ,1658.034912109375 ,1656.053955078125 ,1614.6343994140625 ,1629.9248046875 ,1632.63623046875 ,753.0946044921875 ,756.713134765625 ,790.0026245117188 ,790.0026245117188 ,756.713134765625 ,777.08203125 ,1683.8060302734375 ,1682.325927734375 ,1684.5474853515625 ,1107.613525390625 ,1091.0006103515625 ,1110.033203125 ,1107.613525390625 ,1055.40966796875 ,1091.0006103515625 ,743.750244140625 ,706.3660278320312 ,692.4243774414062 ,847.4163208007812 ,771.46240234375 ,777.5641479492188 ,847.4163208007812 ,826.2499389648438 ,868.6121826171875 ,847.4163208007812 ,777.5641479492188 ,826.2499389648438 ,846.5791625976562 ,831.1430053710938 ,807.87060546875 ,-44.69572830200195 ,-45.30834197998047 ,-3.633512020111084 ,-131.70802307128906 ,-130.08799743652344 ,-133.48570251464844 ,-131.70802307128906 ,-133.48570251464844 ,-138.11817932128906 ,1592.2626953125 ,1589.46728515625 ,1584.520263671875 ,1660.303955078125 ,1659.650634765625 ,1658.034912109375 ,1660.303955078125 ,1658.034912109375 ,1660.75048828125 ,-116.43907928466797 ,-141.20297241210938 ,-123.86084747314453 ,1687.320068359375 ,1690.3095703125 ,1689.8233642578125 ,1689.8233642578125 ,1690.3095703125 ,1690.818603515625 ,1042.73974609375 ,1178.7838134765625 ,1100.494384765625 ,1042.73974609375 ,1100.494384765625 ,1035.0845947265625 ,1494.8699951171875 ,1528.123779296875 ,1511.5054931640625 ,-154.27488708496094 ,-139.5277557373047 ,-140.9107666015625 ,-154.27488708496094 ,-147.42669677734375 ,-139.5277557373047 ,-139.5277557373047 ,-138.11166381835938 ,-140.9107666015625 ,773.294677734375 ,762.6683349609375 ,779.6307373046875 ,1689.8233642578125 ,1689.8409423828125 ,1689.4713134765625 ,-167.836669921875 ,-172.2712860107422 ,-170.8787078857422 ,458.4006042480469 ,444.6069030761719 ,448.892578125 ,799.7229614257812 ,778.3762817382812 ,798.1160888671875 ,799.7229614257812 ,798.1160888671875 ,801.35595703125 ,1665.8795166015625 ,1667.950439453125 ,1657.8052978515625 ,1665.8795166015625 ,1667.665283203125 ,1672.9542236328125 ,1665.8795166015625 ,1672.9542236328125 ,1667.950439453125 ,1602.775390625 ,1538.773681640625 ,1604.4119873046875 ,1657.1484375 ,1653.017822265625 ,1649.50341796875 ,1553.118896484375 ,1540.1556396484375 ,1538.919189453125 ,804.499267578125 ,840.1627807617188 ,823.284912109375 ,804.499267578125 ,843.0507202148438 ,840.1627807617188 ,843.0507202148438 ,792.990234375 ,824.2406616210938 ,765.1046752929688 ,781.025146484375 ,770.588134765625 ,1476.919677734375 ,1548.4180908203125 ,1543.3221435546875 ,852.4590454101562 ,880.638427734375 ,862.8421630859375 ,852.4590454101562 ,857.0423583984375 ,842.6087646484375 ,852.4590454101562 ,862.8421630859375 ,857.0423583984375 ,868.5808715820312 ,846.4307861328125 ,872.2061157226562 ,868.5808715820312 ,872.2061157226562 ,872.126220703125 ,872.126220703125 ,878.2056274414062 ,868.5808715820312 ,868.5808715820312 ,878.2056274414062 ,873.3203735351562 ,1542.2869873046875 ,1540.1556396484375 ,1548.867919921875 ,1542.2869873046875 ,1544.0799560546875 ,1538.919189453125 ,1542.2869873046875 ,1538.919189453125 ,1540.1556396484375 ,1548.867919921875 ,1540.1556396484375 ,1542.1912841796875 ,803.9970092773438 ,796.2474975585938 ,795.6617431640625 ,1123.979736328125 ,1240.89453125 ,1146.6402587890625 ,1671.40869140625 ,1668.416259765625 ,1670.6949462890625 ,1550.7193603515625 ,1546.825439453125 ,1541.8375244140625 ,1550.7193603515625 ,1554.1483154296875 ,1546.825439453125 ,1662.50830078125 ,1667.6202392578125 ,1666.826416015625 ,779.3375244140625 ,781.643310546875 ,782.0736083984375 ,808.3765869140625 ,876.696044921875 ,868.6121826171875 ,808.3765869140625 ,868.6121826171875 ,816.8065795898438 ,769.0580444335938 ,760.6171875 ,764.6854248046875 ,1682.1060791015625 ,1674.0220947265625 ,1666.826416015625 ,1682.1060791015625 ,1666.826416015625 ,1675.666015625 ,1674.0220947265625 ,1664.063232421875 ,1666.826416015625 ,1674.0220947265625 ,1673.271484375 ,1664.063232421875 ,1298.328369140625 ,1348.49267578125 ,1403.7037353515625 ,125.14277648925781 ,372.5214538574219 ,364.6614074707031 ,1570.540283203125 ,1591.2655029296875 ,1589.9951171875 ,-202.57232666015625 ,-143.4319305419922 ,-206.4029083251953 ,-202.57232666015625 ,-168.16668701171875 ,-143.4319305419922 ,-143.4319305419922 ,-171.53567504882812 ,-206.4029083251953 ,1339.8623046875 ,1372.3671875 ,1436.84033203125 ,1601.906982421875 ,1600.8970947265625 ,1602.0751953125 ,1601.906982421875 ,1601.023681640625 ,1600.8970947265625 ,1602.0751953125 ,1600.8970947265625 ,1600.6370849609375 ,1602.0751953125 ,1600.6370849609375 ,1601.489013671875 ,1602.0751953125 ,1601.489013671875 ,1602.4737548828125 ,-141.81932067871094 ,-56.9789924621582 ,-41.81604766845703 ,792.5782470703125 ,784.9931640625 ,793.496337890625 ,1654.9130859375 ,1648.6241455078125 ,1655.774658203125 ,1648.6241455078125 ,1650.4656982421875 ,1655.774658203125 ,130.8192138671875 ,138.4011688232422 ,141.32933044433594 ,130.8192138671875 ,141.32933044433594 ,123.47190856933594 ,1689.8787841796875 ,1688.736572265625 ,1689.230224609375 ,1608.6029052734375 ,1602.9510498046875 ,1601.1868896484375 ,120.27181243896484 ,73.47518157958984 ,69.61405181884766 ,69.61405181884766 ,73.47518157958984 ,-48.14024353027344 ,1650.722900390625 ,1648.6241455078125 ,1644.97119140625 ,60.37742233276367 ,54.11753845214844 ,43.80088806152344 ,60.37742233276367 ,43.80088806152344 ,84.98744201660156 ,789.5177612304688 ,785.389404296875 ,783.3239135742188 ,789.5177612304688 ,797.4121704101562 ,785.389404296875 ,1669.38330078125 ,1677.313720703125 ,1674.4515380859375 ,1669.38330078125 ,1673.774169921875 ,1677.313720703125 ,1566.546630859375 ,1580.8135986328125 ,1585.217041015625 ,-132.90476989746094 ,-131.21571350097656 ,-138.25650024414062 ,552.5986328125 ,647.0407104492188 ,750.1624145507812 ,-87.17730712890625 ,-74.53084564208984 ,-75.78340911865234 ,-87.17730712890625 ,-75.78340911865234 ,-81.57925415039062 ,1603.279296875 ,1601.72216796875 ,1613.7200927734375 ,1603.279296875 ,1613.7200927734375 ,1610.650146484375 ,1610.650146484375 ,1613.7200927734375 ,1614.540771484375 ,1581.4505615234375 ,1512.47705078125 ,1606.3082275390625 ,1633.1820068359375 ,1635.9273681640625 ,1636.418212890625 ,1688.0482177734375 ,1686.734130859375 ,1688.5379638671875 ,1651.2750244140625 ,1632.160400390625 ,1635.4061279296875 ,1669.09912109375 ,1658.1865234375 ,1649.7333984375 ,1575.254150390625 ,1591.111083984375 ,1453.39306640625 ,1575.254150390625 ,1453.39306640625 ,1565.561767578125 ,1638.3662109375 ,1614.6343994140625 ,1632.63623046875 ,1600.6370849609375 ,1600.60546875 ,1601.320556640625 ,1600.6370849609375 ,1601.320556640625 ,1601.489013671875 ,706.8468627929688 ,719.3765869140625 ,708.30078125 ,786.3716430664062 ,784.624755859375 ,764.4428100585938 ,454.2554016113281 ,756.6593627929688 ,542.66552734375 ,1688.496826171875 ,1686.9090576171875 ,1685.360595703125 ,1688.496826171875 ,1688.9842529296875 ,1686.9090576171875 ,1688.496826171875 ,1688.93359375 ,1688.9842529296875 ,1615.714599609375 ,1651.2210693359375 ,1634.2149658203125 ,1566.9979248046875 ,1588.4100341796875 ,1564.2630615234375 ,1566.9979248046875 ,1575.330078125 ,1588.4100341796875 ,1639.03369140625 ,1641.5897216796875 ,1643.0556640625 ,1639.03369140625 ,1643.0556640625 ,1638.11376953125 ,20.901628494262695 ,7.397647857666016 ,192.3759765625 ,20.901628494262695 ,192.3759765625 ,156.33731079101562 ,20.901628494262695 ,-95.96955108642578 ,7.397647857666016 ,192.3759765625 ,221.2639923095703 ,225.7664794921875 ,192.3759765625 ,225.7664794921875 ,156.33731079101562 ,156.33731079101562 ,-22.08594512939453 ,20.901628494262695 ,1642.0909423828125 ,1616.628173828125 ,1609.6234130859375 ,1642.0909423828125 ,1626.154296875 ,1616.628173828125 ,1597.3072509765625 ,1595.722412109375 ,1594.349609375 ,1597.3072509765625 ,1599.012451171875 ,1595.722412109375 ,787.8994750976562 ,805.5436401367188 ,754.8847045898438 ,896.6598510742188 ,798.5071411132812 ,807.4749145507812 ,926.3306884765625 ,909.6098022460938 ,896.6598510742188 ,1637.375 ,1634.7216796875 ,1617.992431640625 ,1637.375 ,1641.2344970703125 ,1634.7216796875 ,1634.7216796875 ,1618.046630859375 ,1617.992431640625 ,1634.7216796875 ,1641.2344970703125 ,1638.5665283203125 ,1629.9200439453125 ,1623.7742919921875 ,1632.133544921875 ,1629.9200439453125 ,1632.133544921875 ,1632.61962890625 ,1685.751220703125 ,1685.66845703125 ,1687.360595703125 ,1359.5948486328125 ,1234.9974365234375 ,1207.198486328125 ,1359.5948486328125 ,1207.198486328125 ,1350.0614013671875 ,1630.985595703125 ,1585.3182373046875 ,1625.0286865234375 ,790.466796875 ,827.4510498046875 ,825.4397583007812 ,827.4510498046875 ,790.466796875 ,833.0125122070312 ,827.4510498046875 ,833.0125122070312 ,846.4307861328125 ,1581.4505615234375 ,1606.3082275390625 ,1718.588134765625 ,1671.787109375 ,1674.537353515625 ,1672.0784912109375 ,1671.787109375 ,1672.0784912109375 ,1670.6949462890625 ,1671.787109375 ,1667.962646484375 ,1674.537353515625 ,1671.787109375 ,1670.6949462890625 ,1667.962646484375 ,1674.537353515625 ,1667.962646484375 ,1673.771728515625 ,1674.537353515625 ,1674.2576904296875 ,1672.0784912109375 ,454.2554016113281 ,36.951839447021484 ,198.62681579589844 ,303.5206604003906 ,454.2554016113281 ,393.78424072265625 ,795.3567504882812 ,846.6958618164062 ,897.042724609375 ,795.3567504882812 ,797.3441772460938 ,846.6958618164062 ,846.6958618164062 ,797.3441772460938 ,788.6294555664062 ,846.6958618164062 ,788.6294555664062 ,895.8970947265625 ,846.6958618164062 ,895.8970947265625 ,897.042724609375 ,14.917814254760742 ,84.2657470703125 ,51.283111572265625 ,14.917814254760742 ,6.620456218719482 ,-8.9946870803833 ,14.917814254760742 ,51.283111572265625 ,6.620456218719482 ,84.2657470703125 ,14.917814254760742 ,126.69802856445312 ,51.283111572265625 ,26.925315856933594 ,6.620456218719482 ,1749.2783203125 ,1787.17724609375 ,1810.5904541015625 ,1749.2783203125 ,1763.056884765625 ,1787.17724609375 ,1810.5904541015625 ,1806.966064453125 ,1868.412353515625 ,1810.5904541015625 ,1787.17724609375 ,1806.966064453125 ,1810.5904541015625 ,1868.412353515625 ,1897.2440185546875 ,1810.5904541015625 ,1897.2440185546875 ,1894.6409912109375 ,1810.5904541015625 ,1894.6409912109375 ,1766.5675048828125 ,833.0125122070312 ,790.466796875 ,831.1430053710938 ,833.0125122070312 ,831.1430053710938 ,851.3971557617188 ,833.0125122070312 ,851.3971557617188 ,872.2061157226562 ,872.2061157226562 ,846.4307861328125 ,833.0125122070312 ,-146.06394958496094 ,-143.0941925048828 ,-141.97189331054688 ,43.80088806152344 ,64.75064849853516 ,68.51032257080078 ,43.80088806152344 ,54.11753845214844 ,58.55487060546875 ,43.80088806152344 ,68.51032257080078 ,84.98744201660156 ,-102.38587188720703 ,-98.6882095336914 ,-96.71883392333984 ,1683.3270263671875 ,1683.2618408203125 ,1680.6246337890625 ,1683.2618408203125 ,1683.3270263671875 ,1684.3946533203125 ,1620.0291748046875 ,1623.7742919921875 ,1617.1231689453125 ,1623.7742919921875 ,1611.4110107421875 ,1617.1231689453125 ,1594.349609375 ,1589.1885986328125 ,1590.654052734375 ,1662.3084716796875 ,1660.1500244140625 ,1659.9517822265625 ,1610.2916259765625 ,1590.534423828125 ,1600.42919921875 ,1610.2916259765625 ,1594.5146484375 ,1590.534423828125 ,1640.44482421875 ,1645.8345947265625 ,1634.977783203125 ,958.0819091796875 ,975.6517333984375 ,974.3580322265625 ,958.0819091796875 ,965.666748046875 ,975.6517333984375 ,958.0819091796875 ,974.3580322265625 ,945.1084594726562 ,958.0819091796875 ,774.2960205078125 ,965.666748046875 ,958.0819091796875 ,945.1084594726562 ,943.1546020507812 ,958.0819091796875 ,943.1546020507812 ,774.2960205078125 ,1330.0029296875 ,996.1683959960938 ,998.6987915039062 ,1330.0029296875 ,998.6987915039062 ,1093.8919677734375 ,1621.124755859375 ,1626.0142822265625 ,1614.930419921875 ,1621.124755859375 ,1625.290283203125 ,1626.0142822265625 ,1614.930419921875 ,1608.6029052734375 ,1621.124755859375 ,1604.4119873046875 ,1538.773681640625 ,1604.0233154296875 ,795.6617431640625 ,781.025146484375 ,770.282470703125 ,-159.6973876953125 ,-156.95455932617188 ,-154.16233825683594 ,-61.53770446777344 ,-70.94931030273438 ,-90.96149444580078 ,-61.53770446777344 ,-24.25218963623047 ,-70.94931030273438 ,-61.53770446777344 ,-90.96149444580078 ,-88.02678680419922 ,-24.25218963623047 ,14.917814254760742 ,-70.94931030273438 ,777.6443481445312 ,773.4005737304688 ,773.294677734375 ,800.7431640625 ,803.314697265625 ,814.9298095703125 ,800.7431640625 ,798.9462280273438 ,803.314697265625 ,803.314697265625 ,811.11669921875 ,814.9298095703125 ,803.314697265625 ,806.5247192382812 ,811.11669921875 ,827.4510498046875 ,846.4307861328125 ,825.4397583007812 ,-61.53770446777344 ,-88.02678680419922 ,-28.75667381286621 ,-61.53770446777344 ,-28.75667381286621 ,-24.25218963623047 ,959.7281494140625 ,933.6444702148438 ,717.6920776367188 ,959.7281494140625 ,1022.5490112304688 ,933.6444702148438 ,959.7281494140625 ,1094.449462890625 ,1022.5490112304688 ,1683.0172119140625 ,1686.0943603515625 ,1687.1873779296875 ,1683.0172119140625 ,1682.6153564453125 ,1686.0943603515625 ,1543.2904052734375 ,1553.1898193359375 ,1536.6990966796875 ,1543.2904052734375 ,1536.6990966796875 ,1541.0382080078125 ,841.958740234375 ,750.1624145507812 ,846.4479370117188 ,1668.6605224609375 ,1637.8812255859375 ,1647.19677734375 ,-3.5637929439544678 ,-36.70216751098633 ,-34.57811737060547 ,-3.5637929439544678 ,-9.448720932006836 ,-36.70216751098633 ,125.14277648925781 ,1.143841028213501 ,39.237022399902344 ,1.143841028213501 ,-169.49635314941406 ,39.237022399902344 ,-131.34829711914062 ,-85.8126449584961 ,-119.6897964477539 ,-131.34829711914062 ,-121.91429901123047 ,-85.8126449584961 ,805.4881591796875 ,801.35595703125 ,800.04736328125 ,1636.2884521484375 ,1638.11376953125 ,1634.52197265625 ,1636.2884521484375 ,1636.6739501953125 ,1638.11376953125 ,1636.0384521484375 ,1645.428466796875 ,1646.2232666015625 ,1636.0384521484375 ,1646.2232666015625 ,1635.9273681640625 ,1636.0384521484375 ,1637.1361083984375 ,1645.428466796875 ,1577.2099609375 ,1567.772216796875 ,1574.43994140625 ,1583.74853515625 ,1578.2080078125 ,1579.7054443359375 ,1579.7054443359375 ,1578.2080078125 ,1573.859619140625 ,1579.7054443359375 ,1577.078125 ,1583.74853515625 ,1579.7054443359375 ,1573.859619140625 ,1577.078125 ,1583.74853515625 ,1577.078125 ,1587.5968017578125 ,143.4466094970703 ,141.32933044433594 ,91.43526458740234 ,117.10556030273438 ,84.98744201660156 ,143.4466094970703 ,1682.7294921875 ,1683.0172119140625 ,1687.320068359375 ,1682.7294921875 ,1682.6153564453125 ,1683.0172119140625 ,841.958740234375 ,747.9818115234375 ,750.1624145507812 ,1646.7701416015625 ,1650.67578125 ,1650.722900390625 ,670.9752807617188 ,821.8519287109375 ,766.7696533203125 ,670.9752807617188 ,747.9818115234375 ,821.8519287109375 ,1835.1531982421875 ,2235.03515625 ,1907.8543701171875 ,1835.1531982421875 ,1885.6708984375 ,2235.03515625 ,1835.1531982421875 ,1841.949462890625 ,1885.6708984375 ,751.6642456054688 ,743.750244140625 ,724.7101440429688 ,724.7101440429688 ,743.750244140625 ,683.6290893554688 ,724.7101440429688 ,683.6290893554688 ,692.2950439453125 ,2003.5426025390625 ,2004.421875 ,1946.9520263671875 ,2003.5426025390625 ,1999.923828125 ,2004.421875 ,2004.421875 ,1932.8714599609375 ,1946.9520263671875 ,2004.421875 ,1956.941650390625 ,1932.8714599609375 ,84.34304809570312 ,123.47190856933594 ,141.32933044433594 ,1688.41552734375 ,1685.1209716796875 ,1689.8233642578125 ,1544.1461181640625 ,1546.02392578125 ,1541.8375244140625 ,1544.1461181640625 ,1543.718505859375 ,1546.02392578125 ,1541.8375244140625 ,1539.6844482421875 ,1544.1461181640625 ,-190.1183624267578 ,-215.37332153320312 ,-304.0158386230469 ,-190.1183624267578 ,-396.90313720703125 ,-275.2289733886719 ,-190.1183624267578 ,-304.0158386230469 ,-396.90313720703125 ,1690.71826171875 ,1692.7640380859375 ,1692.538330078125 ,1353.4224853515625 ,1340.32275390625 ,1375.368896484375 ,1353.4224853515625 ,1375.368896484375 ,1517.98193359375 ,1353.4224853515625 ,1156.853515625 ,1340.32275390625 ,1353.4224853515625 ,1202.355224609375 ,1156.853515625 ,1340.32275390625 ,1156.853515625 ,1375.368896484375 ,1548.8284912109375 ,1552.0093994140625 ,1553.022705078125 ,1592.7005615234375 ,1590.896484375 ,1572.6234130859375 ,1586.39990234375 ,1567.1591796875 ,1563.536865234375 ,-117.57561492919922 ,-122.3655776977539 ,-106.56334686279297 ,-117.57561492919922 ,-122.8582763671875 ,-122.3655776977539 ,-106.56334686279297 ,-122.3655776977539 ,-90.48092651367188 ,-106.56334686279297 ,-90.48092651367188 ,-117.57561492919922 ,-117.57561492919922 ,-90.48092651367188 ,-37.357818603515625 ,1655.9959716796875 ,1657.106201171875 ,1657.7269287109375 ,1657.106201171875 ,1657.2174072265625 ,1657.7269287109375 ,1657.106201171875 ,1653.266357421875 ,1657.2174072265625 ,1657.7269287109375 ,1657.2174072265625 ,1660.623779296875 ,759.6661376953125 ,751.6642456054688 ,751.0639038085938 ,803.314697265625 ,803.208251953125 ,806.5247192382812 ,1587.5968017578125 ,1591.425537109375 ,1598.0146484375 ,847.1500244140625 ,832.4279174804688 ,814.6633911132812 ,847.1500244140625 ,814.6633911132812 ,848.6284790039062 ,764.2892456054688 ,773.9310302734375 ,778.2691650390625 ,1687.9541015625 ,1687.455322265625 ,1685.16943359375 ,180.8580780029297 ,130.03395080566406 ,152.2653350830078 ,130.03395080566406 ,130.1804656982422 ,152.2653350830078 ,152.2653350830078 ,191.36724853515625 ,180.8580780029297 ,1775.8941650390625 ,1756.6732177734375 ,1727.8466796875 ,854.9761962890625 ,863.3182373046875 ,827.7611083984375 ,-375.16754150390625 ,-169.49635314941406 ,-262.1553649902344 ,-375.16754150390625 ,-262.1553649902344 ,-232.23538208007812 ,-375.16754150390625 ,-232.23538208007812 ,-297.5017395019531 ,-169.49635314941406 ,1.143841028213501 ,-262.1553649902344 ,732.1451416015625 ,743.750244140625 ,751.6642456054688 ,1567.586669921875 ,1589.718017578125 ,1538.6708984375 ,-122.85227966308594 ,-120.36861419677734 ,-126.1890640258789 ,907.8963012695312 ,875.2785034179688 ,884.965576171875 ,1687.9541015625 ,1689.0537109375 ,1688.38720703125 ,1687.9541015625 ,1688.38720703125 ,1687.455322265625 ,1558.3375244140625 ,1568.3416748046875 ,1573.0107421875 ,1558.3375244140625 ,1573.0107421875 ,1569.6328125 ,1787.17724609375 ,1780.6429443359375 ,1806.966064453125 ,1787.17724609375 ,1763.056884765625 ,1770.8345947265625 ,1787.17724609375 ,1770.8345947265625 ,1780.6429443359375 ,1662.5382080078125 ,1673.310302734375 ,1680.5875244140625 ,1686.7301025390625 ,1685.785888671875 ,1681.7762451171875 ,945.4508056640625 ,974.5388793945312 ,1515.3936767578125 ,1671.489013671875 ,1670.8912353515625 ,1671.922119140625 ,1671.489013671875 ,1671.922119140625 ,1671.78515625 ,1671.489013671875 ,1675.3575439453125 ,1670.8912353515625 ,1571.849853515625 ,1573.0107421875 ,1568.3416748046875 ,1571.849853515625 ,1570.904541015625 ,1573.0107421875 ,1571.849853515625 ,1568.3416748046875 ,1572.732177734375 ,1571.849853515625 ,1572.732177734375 ,1570.904541015625 ,804.499267578125 ,823.284912109375 ,824.8201904296875 ,807.5975952148438 ,795.2511596679688 ,787.6688232421875 ,1647.19677734375 ,1634.8624267578125 ,1668.6605224609375 ,1647.19677734375 ,1637.8812255859375 ,1629.5826416015625 ,1647.19677734375 ,1629.5826416015625 ,1634.8624267578125 ,1548.560302734375 ,1544.0799560546875 ,1546.8094482421875 ,1548.560302734375 ,1546.3587646484375 ,1544.0799560546875 ,1618.9720458984375 ,1631.2967529296875 ,1623.536376953125 ,1672.9542236328125 ,1674.682861328125 ,1671.8157958984375 ,1672.9542236328125 ,1671.8157958984375 ,1667.950439453125 ,1596.295654296875 ,1601.361328125 ,1600.29052734375 ,1601.361328125 ,1598.824462890625 ,1600.859375 ,1601.361328125 ,1596.295654296875 ,1598.824462890625 ,803.8378295898438 ,785.9521484375 ,805.0759887695312 ,805.0759887695312 ,785.9521484375 ,786.1884765625 ,1621.833984375 ,1627.998046875 ,1622.9652099609375 ,1621.833984375 ,1631.4022216796875 ,1627.998046875 ,1627.998046875 ,1625.169189453125 ,1622.9652099609375 ,1001.5288696289062 ,746.8749389648438 ,892.8511962890625 ,892.8511962890625 ,835.4879760742188 ,912.0824584960938 ,892.8511962890625 ,746.8749389648438 ,835.4879760742188 ,892.8511962890625 ,912.0824584960938 ,1081.4989013671875 ,907.8963012695312 ,943.1953125 ,948.989013671875 ,907.8963012695312 ,948.989013671875 ,930.5149536132812 ,1072.1270751953125 ,1068.9901123046875 ,1080.477294921875 ,1080.477294921875 ,1038.2694091796875 ,1072.1270751953125 ,1080.477294921875 ,1087.777587890625 ,1038.2694091796875 ,1546.939697265625 ,1570.8770751953125 ,1563.897216796875 ,1688.38720703125 ,1689.0537109375 ,1689.559814453125 ,798.9462280273438 ,800.7431640625 ,803.7136840820312 ,-288.77471923828125 ,-195.4857635498047 ,-243.66262817382812 ,-146.54104614257812 ,-132.90476989746094 ,-138.25650024414062 ,-146.54104614257812 ,-138.25650024414062 ,-151.19723510742188 ,-151.19723510742188 ,-138.25650024414062 ,-158.5607147216797 ,996.1683959960938 ,1330.0029296875 ,1165.330078125 ,1330.0029296875 ,1455.2423095703125 ,1246.9864501953125 ,1330.0029296875 ,1246.9864501953125 ,1165.330078125 ,-119.6897964477539 ,-85.8126449584961 ,-67.80812072753906 ,-119.6897964477539 ,-130.72903442382812 ,-143.2757110595703 ,-119.6897964477539 ,-143.2757110595703 ,-131.34829711914062 ,966.4069213867188 ,895.8970947265625 ,788.2352294921875 ,966.4069213867188 ,788.2352294921875 ,785.249267578125 ,966.4069213867188 ,785.249267578125 ,903.6100463867188 ,788.2352294921875 ,895.8970947265625 ,792.322509765625 ,1339.8623046875 ,1237.4595947265625 ,1289.6263427734375 ,1339.8623046875 ,1340.64990234375 ,1372.3671875 ,1339.8623046875 ,1289.6263427734375 ,1340.64990234375 ,1645.1536865234375 ,1635.6138916015625 ,1633.2303466796875 ,777.0218505859375 ,734.4566040039062 ,732.3037109375 ,777.0218505859375 ,790.7344360351562 ,734.4566040039062 ,1553.1898193359375 ,1543.2904052734375 ,1568.3416748046875 ,1590.534423828125 ,1594.5111083984375 ,1600.42919921875 ,1594.5111083984375 ,1601.47607421875 ,1600.42919921875 ,1594.5111083984375 ,1590.534423828125 ,1576.539306640625 ,1600.42919921875 ,1601.47607421875 ,1616.628173828125 ,1629.5826416015625 ,1658.670166015625 ,1639.492919921875 ,-154.70065307617188 ,-143.2757110595703 ,-130.72903442382812 ,-154.70065307617188 ,-148.68128967285156 ,-143.2757110595703 ,1604.0233154296875 ,1522.60986328125 ,1552.476318359375 ,1604.0233154296875 ,1552.476318359375 ,1604.3963623046875 ,1565.7703857421875 ,1565.324951171875 ,1559.673828125 ,1472.83349609375 ,1553.195068359375 ,1571.2496337890625 ,1472.83349609375 ,1571.2496337890625 ,1498.0311279296875 ,1498.0311279296875 ,1424.42041015625 ,1472.83349609375 ,1498.0311279296875 ,1422.123779296875 ,1424.42041015625 ,1472.83349609375 ,1424.42041015625 ,1462.50830078125 ,1472.83349609375 ,1462.50830078125 ,1553.195068359375 ,1870.11962890625 ,2068.06982421875 ,1885.6708984375 ,495.27227783203125 ,652.3643798828125 ,626.4420776367188 ,1282.806396484375 ,1356.734619140625 ,1347.18408203125 ,1282.806396484375 ,1240.89453125 ,1356.734619140625 ,1282.806396484375 ,1094.449462890625 ,1240.89453125 ,1356.734619140625 ,1240.89453125 ,1363.837646484375 ,165.0082244873047 ,157.475830078125 ,143.64382934570312 ,1600.82421875 ,1592.876953125 ,1596.3980712890625 ,1596.3980712890625 ,1601.72216796875 ,1603.279296875 ,1596.3980712890625 ,1603.279296875 ,1600.82421875 ,1051.2655029296875 ,979.0367431640625 ,1027.87646484375 ,1051.2655029296875 ,1022.6570434570312 ,979.0367431640625 ,979.0367431640625 ,1003.8096313476562 ,1027.87646484375 ,13.099784851074219 ,-3.9420969486236572 ,23.160655975341797 ,803.8378295898438 ,825.994140625 ,795.92529296875 ,773.22314453125 ,782.33935546875 ,791.40380859375 ,1659.3795166015625 ,1654.9130859375 ,1662.4249267578125 ,1806.966064453125 ,1808.126708984375 ,1868.412353515625 ,1806.966064453125 ,1780.6429443359375 ,1808.126708984375 ,1656.7720947265625 ,1537.597900390625 ,1542.666748046875 ,1656.7720947265625 ,1542.666748046875 ,1623.0599365234375 ,1656.7720947265625 ,1623.0599365234375 ,1712.3887939453125 ,1491.4222412109375 ,1463.4681396484375 ,1540.3077392578125 ,1491.4222412109375 ,1477.014404296875 ,1463.4681396484375 ,1491.4222412109375 ,1540.3077392578125 ,1529.5411376953125 ,1491.4222412109375 ,1529.5411376953125 ,1501.1376953125 ,1618.6702880859375 ,1613.200927734375 ,1620.3421630859375 ,1618.6702880859375 ,1622.14599609375 ,1629.037841796875 ,1618.6702880859375 ,1620.3421630859375 ,1622.14599609375 ,1589.718017578125 ,1593.8929443359375 ,1585.777099609375 ,-84.05589294433594 ,-84.93722534179688 ,-109.1400146484375 ,972.8710327148438 ,886.61474609375 ,891.51708984375 ,844.1985473632812 ,834.166015625 ,823.1783447265625 ,844.1985473632812 ,823.1783447265625 ,835.4942016601562 ,-147.9262237548828 ,-145.88516235351562 ,-153.44960021972656 ,-147.9262237548828 ,-153.44960021972656 ,-150.95314025878906 ,1552.570556640625 ,1544.0389404296875 ,1547.3134765625 ,799.7362060546875 ,818.9583740234375 ,790.0026245117188 ,894.0360717773438 ,866.286376953125 ,856.873779296875 ,806.8790893554688 ,783.8365478515625 ,864.3307495117188 ,1488.171630859375 ,1555.284912109375 ,1454.1854248046875 ,1647.197021484375 ,1646.78857421875 ,1645.9932861328125 ,1647.197021484375 ,1645.8345947265625 ,1646.78857421875 ,-122.3655776977539 ,-102.61859893798828 ,-90.48092651367188 ,-122.3655776977539 ,-114.62600708007812 ,-102.61859893798828 ,-122.3655776977539 ,-130.52609252929688 ,-114.62600708007812 ,-122.3655776977539 ,-122.8582763671875 ,-130.52609252929688 ,1515.3936767578125 ,1726.457275390625 ,1000.3450317382812 ,842.575927734375 ,882.060302734375 ,869.6773071289062 ,-102.61859893798828 ,-77.23518371582031 ,-90.48092651367188 ,-179.4665985107422 ,-171.90296936035156 ,-173.61891174316406 ,1565.561767578125 ,1569.7120361328125 ,1577.014892578125 ,1565.561767578125 ,1577.014892578125 ,1589.362060546875 ,1680.8619384765625 ,1604.458251953125 ,1613.8966064453125 ,1680.8619384765625 ,1613.8966064453125 ,1647.2269287109375 ,1632.133544921875 ,1631.0205078125 ,1644.4151611328125 ,982.1719970703125 ,987.7450561523438 ,945.8577880859375 ,-139.89889526367188 ,-141.83763122558594 ,-138.8220977783203 ,-139.89889526367188 ,-149.0703582763672 ,-141.83763122558594 ,1648.6241455078125 ,1650.55078125 ,1647.802978515625 ,1597.343994140625 ,1600.29052734375 ,1604.053466796875 ,1597.343994140625 ,1604.458251953125 ,1593.2496337890625 ,1597.343994140625 ,1604.053466796875 ,1604.458251953125 ,1597.343994140625 ,1596.295654296875 ,1600.29052734375 ,-190.1183624267578 ,-158.5607147216797 ,-154.3759307861328 ,775.9713745117188 ,761.7636108398438 ,781.8201904296875 ,775.9713745117188 ,787.5003662109375 ,781.876953125 ,775.9713745117188 ,781.876953125 ,761.7636108398438 ,1027.87646484375 ,1100.494384765625 ,1051.2655029296875 ,825.4397583007812 ,846.4307861328125 ,842.704833984375 ,961.0006713867188 ,1101.100830078125 ,561.8804931640625 ,20.901628494262695 ,-22.08594512939453 ,-95.96955108642578 ,-154.14077758789062 ,-151.7123565673828 ,-152.9228973388672 ,755.9078369140625 ,740.1326293945312 ,761.9156494140625 ,832.4279174804688 ,824.2406616210938 ,814.6633911132812 ,764.4428100585938 ,781.8201904296875 ,761.7636108398438 ,1616.628173828125 ,1601.47607421875 ,1609.6234130859375 ,1660.303955078125 ,1660.75048828125 ,1662.6409912109375 ,1660.303955078125 ,1662.6409912109375 ,1664.548095703125 ,1681.9757080078125 ,1680.5875244140625 ,1690.700439453125 ,-153.44395446777344 ,-163.9052276611328 ,-166.50289916992188 ,2004.421875 ,1999.923828125 ,1880.57177734375 ,2004.421875 ,1880.57177734375 ,1956.941650390625 ,1621.124755859375 ,1608.6029052734375 ,1613.7576904296875 ,1682.325927734375 ,1677.0831298828125 ,1675.5518798828125 ,996.1683959960938 ,1246.9864501953125 ,1178.7838134765625 ,996.1683959960938 ,1165.330078125 ,1246.9864501953125 ,996.1683959960938 ,706.0634765625 ,998.6987915039062 ,728.3058471679688 ,716.3633422851562 ,723.6242065429688 ,728.3058471679688 ,723.293212890625 ,716.3633422851562 ,-119.6897964477539 ,-82.16941833496094 ,-130.72903442382812 ,-119.6897964477539 ,-21.956390380859375 ,-82.16941833496094 ,-130.72903442382812 ,-82.16941833496094 ,-79.97222137451172 ,785.7398681640625 ,788.6294555664062 ,797.3441772460938 ,-63.73884963989258 ,-74.53084564208984 ,-87.17730712890625 ,-63.73884963989258 ,-87.17730712890625 ,-92.81271362304688 ,-63.73884963989258 ,-60.050437927246094 ,-74.53084564208984 ,793.8555297851562 ,756.6593627929688 ,813.8816528320312 ,793.8555297851562 ,813.8816528320312 ,830.006103515625 ,1645.9932861328125 ,1646.78857421875 ,1652.9853515625 ,1596.181396484375 ,1692.55908203125 ,1670.688720703125 ,1596.181396484375 ,1515.2393798828125 ,1588.393798828125 ,1596.181396484375 ,1588.393798828125 ,1692.55908203125 ,1692.55908203125 ,1588.393798828125 ,1641.736083984375 ,1692.55908203125 ,1641.736083984375 ,1666.2265625 ,1692.55908203125 ,1666.2265625 ,1670.688720703125 ,1670.688720703125 ,1588.5582275390625 ,1649.01171875 ,1670.688720703125 ,1649.01171875 ,1596.181396484375 ,1670.688720703125 ,1666.2265625 ,1588.5582275390625 ,-153.44395446777344 ,-165.2589569091797 ,-162.77415466308594 ,-153.44395446777344 ,-166.50289916992188 ,-165.2589569091797 ,-168.16668701171875 ,-183.16323852539062 ,-151.3717803955078 ,36.951839447021484 ,59.6855583190918 ,-195.4857635498047 ,11.559826850891113 ,-37.357818603515625 ,-77.23518371582031 ,1940.6337890625 ,1950.8538818359375 ,1999.923828125 ,1940.6337890625 ,1999.923828125 ,2003.5426025390625 ,1638.11376953125 ,1632.854248046875 ,1634.52197265625 ,1632.854248046875 ,1633.0850830078125 ,1634.52197265625 ,1579.477783203125 ,1582.647705078125 ,1593.351806640625 ,1582.647705078125 ,1588.1551513671875 ,1591.385986328125 ,1363.8858642578125 ,1523.9736328125 ,1512.614501953125 ,1827.9642333984375 ,1940.6337890625 ,1686.75048828125 ,1827.9642333984375 ,1686.75048828125 ,1635.5401611328125 ,1600.6480712890625 ,1571.296142578125 ,1579.073974609375 ,1546.825439453125 ,1554.1483154296875 ,1544.3592529296875 ,1522.60986328125 ,1538.773681640625 ,1469.92626953125 ,1691.950927734375 ,1691.991943359375 ,1691.6446533203125 ,1575.330078125 ,1566.9979248046875 ,1589.718017578125 ,1575.330078125 ,1589.718017578125 ,1585.777099609375 ,1575.330078125 ,1585.777099609375 ,1588.4100341796875 ,158.07339477539062 ,162.37506103515625 ,126.56841278076172 ,126.56841278076172 ,162.37506103515625 ,142.91012573242188 ,126.56841278076172 ,125.16410064697266 ,158.07339477539062 ,1592.6134033203125 ,1649.01171875 ,1588.5582275390625 ,-13.414265632629395 ,-85.8126449584961 ,-56.86187744140625 ,1350.0614013671875 ,1312.385986328125 ,1428.7633056640625 ,1595.722412109375 ,1594.6051025390625 ,1594.73974609375 ,1808.126708984375 ,1819.1021728515625 ,1826.67724609375 ,1808.126708984375 ,1787.134765625 ,1819.1021728515625 ,1149.0843505859375 ,965.7979125976562 ,1285.7158203125 ,12.87821102142334 ,48.81981658935547 ,126.56841278076172 ,-150.6800994873047 ,-142.89480590820312 ,-146.49044799804688 ,1826.67724609375 ,1819.1021728515625 ,1825.2783203125 ,1825.2783203125 ,1819.1021728515625 ,1831.2437744140625 ,1594.5146484375 ,1600.057861328125 ,1592.2626953125 ,765.9899291992188 ,778.7622680664062 ,778.0946044921875 ,765.9899291992188 ,778.0946044921875 ,757.3011474609375 ,765.9899291992188 ,757.3011474609375 ,778.7622680664062 ,1642.1343994140625 ,1653.93603515625 ,1657.8052978515625 ,1553.089111328125 ,1546.939697265625 ,1547.5770263671875 ,1553.089111328125 ,1570.8770751953125 ,1546.939697265625 ,1553.089111328125 ,1547.5770263671875 ,1561.940673828125 ,804.1401977539062 ,793.8555297851562 ,815.931396484375 ,804.1401977539062 ,778.0476684570312 ,793.8555297851562 ,1207.198486328125 ,1081.4989013671875 ,1312.385986328125 ,1634.977783203125 ,1645.8345947265625 ,1636.909912109375 ,1632.9971923828125 ,1639.3721923828125 ,1635.6751708984375 ,1632.9971923828125 ,1635.6751708984375 ,1633.0953369140625 ,1579.073974609375 ,1337.89208984375 ,1526.1451416015625 ,1579.073974609375 ,1571.296142578125 ,1337.89208984375 ,1617.8851318359375 ,1607.154296875 ,1605.025390625 ,1002.829345703125 ,966.4069213867188 ,973.200927734375 ,1002.829345703125 ,895.8970947265625 ,966.4069213867188 ,973.200927734375 ,903.6100463867188 ,894.9827880859375 ,973.200927734375 ,966.4069213867188 ,903.6100463867188 ,973.200927734375 ,894.9827880859375 ,818.9485473632812 ,-3.2561590671539307 ,126.56841278076172 ,100.33374786376953 ,800.7431640625 ,814.9298095703125 ,803.7136840820312 ,1671.3597412109375 ,1671.9622802734375 ,1678.15283203125 ,1671.9622802734375 ,1671.3597412109375 ,1667.19677734375 ,1681.99755859375 ,1683.8060302734375 ,1685.4197998046875 ,846.9815063476562 ,865.2728881835938 ,826.6268310546875 ,846.9815063476562 ,877.5236206054688 ,896.8179321289062 ,846.9815063476562 ,896.8179321289062 ,865.2728881835938 ,690.8013305664062 ,717.6920776367188 ,885.052490234375 ,885.052490234375 ,717.6920776367188 ,933.6444702148438 ,1660.7755126953125 ,1667.3758544921875 ,1664.859130859375 ,1618.880615234375 ,1635.6124267578125 ,1645.1536865234375 ,-96.3033676147461 ,-100.40309143066406 ,-102.13951873779297 ,-102.13951873779297 ,-100.40309143066406 ,-109.44664764404297 ,729.4252319335938 ,682.0635986328125 ,727.1863403320312 ,729.4252319335938 ,727.1863403320312 ,729.9891357421875 ,727.1863403320312 ,687.7828979492188 ,725.346923828125 ,727.1863403320312 ,682.0635986328125 ,687.7828979492188 ,727.1863403320312 ,729.0462646484375 ,729.9891357421875 ,-158.23422241210938 ,-150.59349060058594 ,-148.42178344726562 ,1569.2679443359375 ,1559.9676513671875 ,1569.6328125 ,1569.2679443359375 ,1569.6328125 ,1570.4049072265625 ,1553.022705078125 ,1552.0093994140625 ,1554.757080078125 ,1553.022705078125 ,1554.757080078125 ,1554.8896484375 ,1582.6365966796875 ,1589.46728515625 ,1580.0263671875 ,1582.6365966796875 ,1584.520263671875 ,1589.46728515625 ,1670.4793701171875 ,1662.9674072265625 ,1672.82763671875 ,1670.4793701171875 ,1659.263916015625 ,1662.9674072265625 ,1324.3756103515625 ,1237.4595947265625 ,1339.8623046875 ,1324.3756103515625 ,1285.7158203125 ,1237.4595947265625 ,1324.3756103515625 ,1339.8623046875 ,1368.138671875 ,1599.012451171875 ,1597.8902587890625 ,1596.440673828125 ,69.61405181884766 ,81.85975646972656 ,120.27181243896484 ,69.61405181884766 ,-7.0689778327941895 ,81.85975646972656 ,1601.72216796875 ,1616.6317138671875 ,1614.55859375 ,1622.9652099609375 ,1617.012939453125 ,1621.833984375 ,-271.23895263671875 ,-376.84521484375 ,-297.79754638671875 ,-271.23895263671875 ,-195.4857635498047 ,-136.6942596435547 ,792.322509765625 ,895.8970947265625 ,788.6294555664062 ,903.6100463867188 ,890.0218505859375 ,894.9827880859375 ,894.9827880859375 ,890.0218505859375 ,821.3425903320312 ,1068.9901123046875 ,1070.3936767578125 ,1092.355224609375 ,1642.7744140625 ,1641.77685546875 ,1641.852294921875 ,1578.15625 ,1556.6446533203125 ,1569.775390625 ,-77.23518371582031 ,-59.35438537597656 ,-48.0750732421875 ,-77.23518371582031 ,-102.61859893798828 ,-59.35438537597656 ,-48.0750732421875 ,-59.35438537597656 ,-22.31652069091797 ,792.85107421875 ,798.400390625 ,793.496337890625 ,790.466796875 ,807.87060546875 ,831.1430053710938 ,84.98744201660156 ,84.34304809570312 ,143.4466094970703 ,-122.85227966308594 ,-126.1890640258789 ,-133.1144561767578 ,1536.4788818359375 ,1512.614501953125 ,1542.45068359375 ,1542.45068359375 ,1512.614501953125 ,1523.9736328125 ,1542.45068359375 ,1523.9736328125 ,1588.199462890625 ,692.4243774414062 ,590.23095703125 ,661.638916015625 ,692.4243774414062 ,693.88330078125 ,590.23095703125 ,785.9521484375 ,784.9035034179688 ,786.1884765625 ,130.14859008789062 ,92.03718566894531 ,149.82284545898438 ,130.14859008789062 ,102.53659057617188 ,92.03718566894531 ,-146.309814453125 ,-147.2008514404297 ,-146.34799194335938 ,-146.34799194335938 ,-147.2008514404297 ,-147.45188903808594 ,179.1769561767578 ,184.67359924316406 ,158.07339477539062 ,751.6642456054688 ,759.6661376953125 ,771.9223022460938 ,759.6661376953125 ,779.576904296875 ,771.9223022460938 ,-375.16754150390625 ,-396.90313720703125 ,-209.7818145751953 ,-375.16754150390625 ,-297.5017395019531 ,-396.90313720703125 ,-209.7818145751953 ,-396.90313720703125 ,-399.59234619140625 ,1598.4822998046875 ,1602.2880859375 ,1601.2574462890625 ,1601.2574462890625 ,1598.8990478515625 ,1598.4822998046875 ,1647.1204833984375 ,1654.9130859375 ,1653.2147216796875 ,1689.559814453125 ,1688.736572265625 ,1688.38720703125 ,1689.559814453125 ,1689.361083984375 ,1688.736572265625 ,37.52220916748047 ,43.55766677856445 ,67.64774322509766 ,37.52220916748047 ,14.137516021728516 ,43.55766677856445 ,1634.6875 ,1626.0142822265625 ,1625.290283203125 ,1634.6875 ,1625.290283203125 ,1636.0384521484375 ,-37.49604797363281 ,-6.674344062805176 ,-47.91132736206055 ,-37.49604797363281 ,-47.91132736206055 ,-69.6546859741211 ,-37.49604797363281 ,-13.013050079345703 ,-6.674344062805176 ,18.952594757080078 ,50.4521484375 ,38.12131881713867 ,18.952594757080078 ,-106.60688781738281 ,-75.40615844726562 ,18.952594757080078 ,9.825300216674805 ,50.4521484375 ,18.952594757080078 ,-75.40615844726562 ,9.825300216674805 ,38.12131881713867 ,50.4521484375 ,14.137516021728516 ,1603.49072265625 ,1600.82421875 ,1603.279296875 ,1654.3341064453125 ,1659.3795166015625 ,1660.7755126953125 ,1598.22265625 ,1587.8623046875 ,1582.8492431640625 ,1598.22265625 ,1582.8492431640625 ,1589.130126953125 ,1589.130126953125 ,1582.8492431640625 ,1585.578369140625 ,1946.9520263671875 ,1901.060302734375 ,2003.5426025390625 ,1675.666015625 ,1666.826416015625 ,1667.6202392578125 ,1675.666015625 ,1667.6202392578125 ,1670.9056396484375 ,1653.93603515625 ,1642.1343994140625 ,1653.1845703125 ,1609.28369140625 ,1613.4114990234375 ,1605.64599609375 ,1664.745849609375 ,1660.91064453125 ,1660.6507568359375 ,1563.6204833984375 ,1571.12646484375 ,1587.6796875 ,1563.6204833984375 ,1587.6796875 ,1570.010009765625 ,1637.7620849609375 ,1637.1361083984375 ,1630.1005859375 ,1489.4591064453125 ,2080.4912109375 ,1684.946044921875 ,-142.7763671875 ,-142.95718383789062 ,-143.4319305419922 ,1901.060302734375 ,1939.4962158203125 ,1947.9320068359375 ,1901.060302734375 ,1725.84033203125 ,1939.4962158203125 ,1901.060302734375 ,1947.9320068359375 ,2003.5426025390625 ,1901.060302734375 ,1946.9520263671875 ,1725.84033203125 ,846.9815063476562 ,791.2133178710938 ,776.2487182617188 ,1570.010009765625 ,1587.6796875 ,1592.7005615234375 ,1592.0350341796875 ,1591.385986328125 ,1588.1551513671875 ,751.6642456054688 ,724.7101440429688 ,751.0639038085938 ,-172.3965606689453 ,-172.18809509277344 ,-168.5343017578125 ,759.6661376953125 ,772.51806640625 ,786.1884765625 ,759.6661376953125 ,786.1884765625 ,779.576904296875 ,759.6661376953125 ,762.7431640625 ,772.51806640625 ,-163.5635528564453 ,-171.90296936035156 ,-150.53488159179688 ,-163.5635528564453 ,-150.53488159179688 ,-150.75221252441406 ,1683.2618408203125 ,1680.0238037109375 ,1680.6246337890625 ,807.4749145507812 ,798.5071411132812 ,796.4855346679688 ,1589.9951171875 ,1609.4886474609375 ,1601.72216796875 ,1589.9951171875 ,1591.2655029296875 ,1609.4886474609375 ,138.4011688232422 ,130.8192138671875 ,79.7586669921875 ,138.4011688232422 ,91.43526458740234 ,141.32933044433594 ,795.55419921875 ,808.4400634765625 ,804.3980712890625 ,1688.5379638671875 ,1688.48388671875 ,1688.1015625 ,1688.5379638671875 ,1688.1015625 ,1686.4478759765625 ,1686.4478759765625 ,1688.0482177734375 ,1688.5379638671875 ,1149.0843505859375 ,960.0421752929688 ,965.7979125976562 ,1680.30908203125 ,1676.2178955078125 ,1677.5621337890625 ,1680.30908203125 ,1678.31201171875 ,1676.2178955078125 ,1690.700439453125 ,1695.0233154296875 ,1694.167724609375 ,1691.8638916015625 ,1687.61474609375 ,1691.5362548828125 ,1687.61474609375 ,1690.0823974609375 ,1691.272705078125 ,1687.61474609375 ,1691.272705078125 ,1691.5362548828125 ,1691.5362548828125 ,1691.272705078125 ,1691.8638916015625 ,1666.199951171875 ,1668.263916015625 ,1669.50390625 ,-157.68096923828125 ,-147.3275604248047 ,-156.95455932617188 ,-157.68096923828125 ,-149.68702697753906 ,-147.3275604248047 ,-157.68096923828125 ,-156.95455932617188 ,-160.25048828125 ,-157.68096923828125 ,-160.1863555908203 ,-149.68702697753906 ,-157.68096923828125 ,-160.25048828125 ,-160.1863555908203 ,1624.4599609375 ,1643.8046875 ,1655.4056396484375 ,1624.4599609375 ,1655.4056396484375 ,1654.319580078125 ,1624.4599609375 ,1654.319580078125 ,1646.99853515625 ,1624.4599609375 ,1646.99853515625 ,1637.7955322265625 ,1940.6337890625 ,1827.9642333984375 ,1917.1875 ,1685.4197998046875 ,1683.8060302734375 ,1684.5474853515625 ,1685.4197998046875 ,1683.823974609375 ,1681.99755859375 ,1149.0843505859375 ,1070.3936767578125 ,960.0421752929688 ,495.27227783203125 ,466.0267333984375 ,431.29559326171875 ,1582.167724609375 ,1590.534423828125 ,1594.5146484375 ,321.51806640625 ,105.0716323852539 ,147.09942626953125 ,321.51806640625 ,147.09942626953125 ,552.5986328125 ,105.0716323852539 ,321.51806640625 ,387.1172790527344 ,1688.48388671875 ,1687.9541015625 ,1688.1015625 ,1609.0880126953125 ,1602.2877197265625 ,1644.015625 ,1653.4361572265625 ,1655.188720703125 ,1651.813232421875 ,1653.4361572265625 ,1654.4324951171875 ,1655.188720703125 ,1653.4361572265625 ,1650.7645263671875 ,1654.4324951171875 ,1651.813232421875 ,1653.9564208984375 ,1653.6058349609375 ,777.08203125 ,756.713134765625 ,743.8383178710938 ,777.08203125 ,743.8383178710938 ,772.87109375 ,-96.71883392333984 ,-92.52731323242188 ,-92.32088470458984 ,1689.361083984375 ,1689.559814453125 ,1689.9307861328125 ,1689.361083984375 ,1689.9307861328125 ,1689.230224609375 ,1689.361083984375 ,1689.230224609375 ,1688.736572265625 ,1651.9105224609375 ,1651.174560546875 ,1641.9266357421875 ,1642.8101806640625 ,1641.9266357421875 ,1651.174560546875 ,-163.9052276611328 ,-154.70065307617188 ,-157.62338256835938 ,1577.2099609375 ,1566.099365234375 ,1572.1949462890625 ,1547.94482421875 ,1540.3077392578125 ,1540.0787353515625 ,1547.94482421875 ,1561.707763671875 ,1540.3077392578125 ,1547.94482421875 ,1588.2427978515625 ,1561.707763671875 ,894.9439086914062 ,889.2929077148438 ,909.6098022460938 ,869.6773071289062 ,868.6121826171875 ,887.5587158203125 ,1574.396240234375 ,1571.10107421875 ,1564.533203125 ,1686.6571044921875 ,1685.66845703125 ,1685.1534423828125 ,1686.6571044921875 ,1687.360595703125 ,1685.66845703125 ,1687.360595703125 ,1688.9949951171875 ,1689.3079833984375 ,1613.200927734375 ,1614.540771484375 ,1622.14599609375 ,1613.200927734375 ,1622.14599609375 ,1620.3421630859375 ,1640.5447998046875 ,1647.4063720703125 ,1647.9674072265625 ,-101.84134674072266 ,-93.7981948852539 ,-84.37976837158203 ,1010.2650756835938 ,969.9252319335938 ,907.8963012695312 ,-130.52609252929688 ,-122.8582763671875 ,-129.30104064941406 ,-129.30104064941406 ,-122.8582763671875 ,-130.08799743652344 ,212.26077270507812 ,320.3096618652344 ,87.79638671875 ,212.26077270507812 ,125.14277648925781 ,364.6614074707031 ,212.26077270507812 ,87.79638671875 ,125.14277648925781 ,212.26077270507812 ,364.6614074707031 ,320.3096618652344 ,320.3096618652344 ,364.6614074707031 ,391.55621337890625 ,1494.8699951171875 ,1511.5054931640625 ,1455.574462890625 ,1649.9718017578125 ,1653.6058349609375 ,1657.0269775390625 ,1684.2529296875 ,1685.1534423828125 ,1685.66845703125 ,1091.0006103515625 ,1055.40966796875 ,1067.620361328125 ,1028.039306640625 ,890.9190673828125 ,1070.3936767578125 ,1617.8865966796875 ,1635.6124267578125 ,1618.880615234375 ,1540.0787353515625 ,1540.3077392578125 ,1499.37890625 ,158.07339477539062 ,184.67359924316406 ,162.37506103515625 ,1665.5711669921875 ,1667.6173095703125 ,1666.755126953125 ,1665.5711669921875 ,1668.46630859375 ,1667.6173095703125 ,1665.5711669921875 ,1666.7664794921875 ,1668.46630859375 ,1825.2783203125 ,1782.79150390625 ,1826.67724609375 ,1422.123779296875 ,1498.0311279296875 ,1468.338623046875 ,2016.6395263671875 ,1469.92626953125 ,1540.01904296875 ,1289.6263427734375 ,1258.8929443359375 ,1340.64990234375 ,1526.1451416015625 ,1504.46337890625 ,1551.97705078125 ,1584.2979736328125 ,1591.043701171875 ,1567.23486328125 ,1620.9952392578125 ,1622.3206787109375 ,1613.4114990234375 ,1671.44140625 ,1674.3995361328125 ,1678.28515625 ,-143.0941925048828 ,-146.06394958496094 ,-142.55540466308594 ,1523.1141357421875 ,1534.2867431640625 ,1538.6708984375 ,1692.7640380859375 ,1691.8638916015625 ,1693.0911865234375 ,1831.2437744140625 ,1819.1021728515625 ,1798.1724853515625 ,-141.83763122558594 ,-142.54470825195312 ,-138.8220977783203 ,-141.83763122558594 ,-149.0703582763672 ,-142.54470825195312 ,1604.4390869140625 ,1601.1868896484375 ,1600.896484375 ,979.0367431640625 ,981.9210815429688 ,1003.8096313476562 ,1633.53369140625 ,1628.96435546875 ,1623.8203125 ,1633.53369140625 ,1632.4642333984375 ,1628.96435546875 ,1628.96435546875 ,1607.47314453125 ,1623.8203125 ,1623.8203125 ,1610.5791015625 ,1633.53369140625 ,-103.8460922241211 ,-79.97222137451172 ,-46.94858169555664 ,-215.37332153320312 ,-223.46041870117188 ,-304.0158386230469 ,1003.959716796875 ,1072.1270751953125 ,1038.2694091796875 ,1003.959716796875 ,1038.2694091796875 ,1010.2650756835938 ,1540.3974609375 ,1539.6844482421875 ,1537.4833984375 ,1689.44873046875 ,1687.034912109375 ,1688.627197265625 ,1051.2655029296875 ,1100.494384765625 ,1102.5924072265625 ,-151.7123565673828 ,-152.8994903564453 ,-151.143798828125 ,787.5003662109375 ,792.990234375 ,781.876953125 ,848.6284790039062 ,844.9097900390625 ,859.4566650390625 ,1685.5765380859375 ,1685.360595703125 ,1684.5247802734375 ,1655.201416015625 ,1535.486572265625 ,1641.736083984375 ,1655.201416015625 ,1580.21044921875 ,1635.144775390625 ,1655.201416015625 ,1613.2799072265625 ,1580.21044921875 ,1655.201416015625 ,1641.736083984375 ,1613.2799072265625 ,-431.3062438964844 ,-402.4700927734375 ,-399.59234619140625 ,-431.3062438964844 ,-399.59234619140625 ,-304.0158386230469 ,1666.199951171875 ,1669.50390625 ,1667.665283203125 ,1666.199951171875 ,1667.665283203125 ,1662.9305419921875 ,1593.8599853515625 ,1594.5810546875 ,1597.4324951171875 ,1593.8599853515625 ,1594.0908203125 ,1594.5810546875 ,-172.62753295898438 ,-174.07568359375 ,-166.1901092529297 ,777.5641479492188 ,762.6683349609375 ,773.4005737304688 ,777.5641479492188 ,771.46240234375 ,762.6683349609375 ,762.6683349609375 ,773.294677734375 ,773.4005737304688 ,1384.667236328125 ,1487.403564453125 ,1464.8760986328125 ,1123.979736328125 ,1101.100830078125 ,1338.5748291015625 ,1667.689453125 ,1655.0233154296875 ,1664.8780517578125 ,764.4428100585938 ,784.624755859375 ,781.8201904296875 ,764.4428100585938 ,759.187255859375 ,786.3716430664062 ,784.624755859375 ,782.0736083984375 ,775.9713745117188 ,784.624755859375 ,775.9713745117188 ,781.8201904296875 ,1546.7625732421875 ,1565.7703857421875 ,1557.5587158203125 ,1617.8548583984375 ,1620.5557861328125 ,1609.713134765625 ,1620.5557861328125 ,1636.007568359375 ,1609.713134765625 ,1620.5557861328125 ,1643.3670654296875 ,1636.007568359375 ,1609.713134765625 ,1636.007568359375 ,1596.8861083984375 ,948.989013671875 ,943.1953125 ,968.173828125 ,850.6434326171875 ,854.6092529296875 ,842.852294921875 ,850.6434326171875 ,857.0423583984375 ,854.6092529296875 ,850.6434326171875 ,842.6087646484375 ,857.0423583984375 ,1677.5621337890625 ,1675.3109130859375 ,1678.84521484375 ,1677.5621337890625 ,1675.241943359375 ,1675.3109130859375 ,1600.42919921875 ,1616.628173828125 ,1610.2916259765625 ,1604.3963623046875 ,1585.6143798828125 ,1601.7562255859375 ,1604.3963623046875 ,1552.476318359375 ,1585.6143798828125 ,1011.173583984375 ,965.6051025390625 ,998.5934448242188 ,1825.7593994140625 ,1950.8538818359375 ,1917.1875 ,1950.8538818359375 ,1825.7593994140625 ,1819.286376953125 ,1632.2459716796875 ,1627.836669921875 ,1641.77685546875 ,1641.77685546875 ,1627.836669921875 ,1629.5826416015625 ,1627.1104736328125 ,1630.4327392578125 ,1634.977783203125 ,1512.614501953125 ,1448.8497314453125 ,1348.49267578125 ,1512.614501953125 ,1536.4788818359375 ,1448.8497314453125 ,1426.50927734375 ,1338.2554931640625 ,1337.89208984375 ,1617.012939453125 ,1620.7742919921875 ,1606.625 ,1617.012939453125 ,1622.9652099609375 ,1620.7742919921875 ,1606.625 ,1620.7742919921875 ,1575.0830078125 ,1685.360595703125 ,1687.4100341796875 ,1688.496826171875 ,1656.19677734375 ,1649.8121337890625 ,1652.7958984375 ,1656.19677734375 ,1652.7958984375 ,1661.281982421875 ,1656.19677734375 ,1661.281982421875 ,1659.814208984375 ,1656.19677734375 ,1659.814208984375 ,1656.8397216796875 ,1656.19677734375 ,1656.8397216796875 ,1653.5064697265625 ,1656.19677734375 ,1653.5064697265625 ,1649.8121337890625 ,1606.5816650390625 ,1614.394775390625 ,1608.6427001953125 ,1631.4022216796875 ,1635.6751708984375 ,1642.0712890625 ,1631.4022216796875 ,1633.0953369140625 ,1635.6751708984375 ,784.005615234375 ,773.4005737304688 ,777.6443481445312 ,773.4005737304688 ,816.8065795898438 ,777.5641479492188 ,1690.796875 ,1692.0556640625 ,1692.3402099609375 ,1692.0556640625 ,1691.32421875 ,1692.2630615234375 ,1692.0556640625 ,1690.796875 ,1691.32421875 ,1587.611083984375 ,1589.0775146484375 ,1588.2427978515625 ,-115.22801971435547 ,-106.64468383789062 ,-103.65386962890625 ,1591.043701171875 ,1565.91796875 ,1567.23486328125 ,1627.1104736328125 ,1636.909912109375 ,1632.5113525390625 ,1627.1104736328125 ,1632.5113525390625 ,1630.0673828125 ,1072.1270751953125 ,1003.959716796875 ,974.2076416015625 ,1003.959716796875 ,942.9981689453125 ,974.2076416015625 ,-109.1400146484375 ,-84.93722534179688 ,-115.4434585571289 ,1605.64599609375 ,1605.918212890625 ,1609.28369140625 ,1605.64599609375 ,1605.6170654296875 ,1605.1339111328125 ,1591.2655029296875 ,1605.57763671875 ,1609.4886474609375 ,778.7622680664062 ,757.3011474609375 ,769.0580444335938 ,1653.1845703125 ,1621.914794921875 ,1632.9669189453125 ,128.33255004882812 ,149.82284545898438 ,51.283111572265625 ,1553.1898193359375 ,1543.718505859375 ,1536.6990966796875 ,1654.3341064453125 ,1647.1204833984375 ,1653.2147216796875 ,661.638916015625 ,683.6290893554688 ,692.4243774414062 ,1539.6844482421875 ,1540.3974609375 ,1544.1461181640625 ,1675.3109130859375 ,1675.241943359375 ,1672.58154296875 ,143.64382934570312 ,162.90782165527344 ,148.8214874267578 ,894.9195556640625 ,774.2960205078125 ,806.8790893554688 ,-136.4071044921875 ,-158.22862243652344 ,-134.75697326660156 ,-134.75697326660156 ,-150.75221252441406 ,-112.009033203125 ,-134.75697326660156 ,-114.62600708007812 ,-136.4071044921875 ,-134.75697326660156 ,-112.009033203125 ,-114.62600708007812 ,806.5791015625 ,717.0455322265625 ,787.6427001953125 ,806.5791015625 ,787.6427001953125 ,805.5436401367188 ,1639.416259765625 ,1644.410888671875 ,1645.428466796875 ,1590.654052734375 ,1577.014892578125 ,1586.283935546875 ,748.2906494140625 ,753.95947265625 ,690.889404296875 ,690.889404296875 ,753.95947265625 ,707.375732421875 ,1643.2557373046875 ,1657.2647705078125 ,1642.044677734375 ,941.419921875 ,1125.035400390625 ,939.5186767578125 ,941.419921875 ,1014.3953247070312 ,1125.035400390625 ,939.5186767578125 ,882.2884521484375 ,941.419921875 ,939.5186767578125 ,887.4142456054688 ,882.2884521484375 ,1833.514404296875 ,1727.8466796875 ,1696.6854248046875 ,1808.126708984375 ,1780.6429443359375 ,1787.134765625 ,690.8013305664062 ,620.417236328125 ,717.6920776367188 ,552.5986328125 ,387.1172790527344 ,321.51806640625 ,1670.4410400390625 ,1674.808837890625 ,1664.970703125 ,1670.4410400390625 ,1664.970703125 ,1660.89501953125 ,1674.808837890625 ,1670.4410400390625 ,1670.9378662109375 ,716.6488647460938 ,725.346923828125 ,687.7828979492188 ,716.6488647460938 ,687.7828979492188 ,701.0760498046875 ,716.6488647460938 ,701.0760498046875 ,721.634765625 ,-146.88943481445312 ,-133.1144561767578 ,-137.802978515625 ,1582.6365966796875 ,1569.8341064453125 ,1582.167724609375 ,1582.6365966796875 ,1582.167724609375 ,1584.520263671875 ,1672.9542236328125 ,1667.665283203125 ,1669.6793212890625 ,1100.494384765625 ,1027.87646484375 ,1035.0845947265625 ,1035.0845947265625 ,1027.87646484375 ,957.0482788085938 ,1543.718505859375 ,1544.1461181640625 ,1541.107177734375 ,-130.08799743652344 ,-122.8582763671875 ,-124.44517517089844 ,1947.9320068359375 ,1939.4962158203125 ,2003.5426025390625 ,38.12131881713867 ,13.099784851074219 ,23.160655975341797 ,1583.322509765625 ,1574.650390625 ,1568.362060546875 ,1583.322509765625 ,1580.7481689453125 ,1574.650390625 ,1666.320068359375 ,1671.9622802734375 ,1667.19677734375 ,766.7696533203125 ,672.4046020507812 ,670.9752807617188 ,766.7696533203125 ,688.0762329101562 ,672.4046020507812 ,1695.4520263671875 ,1701.8389892578125 ,1704.06396484375 ,1695.4520263671875 ,1692.29931640625 ,1701.8389892578125 ,1727.8466796875 ,1649.6490478515625 ,1696.6854248046875 ,1667.7757568359375 ,1664.970703125 ,1674.808837890625 ,798.9462280273438 ,803.9970092773438 ,803.314697265625 ,1687.61474609375 ,1684.5474853515625 ,1687.83935546875 ,1597.2001953125 ,1592.171875 ,1591.1419677734375 ,1597.2001953125 ,1594.472900390625 ,1592.171875 ,1575.254150390625 ,1596.8861083984375 ,1591.111083984375 ,1575.254150390625 ,1589.362060546875 ,1596.8861083984375 ,1575.254150390625 ,1565.561767578125 ,1589.362060546875 ,1674.682861328125 ,1670.61572265625 ,1671.8157958984375 ,803.8378295898438 ,795.92529296875 ,793.496337890625 ,-32.67344665527344 ,-12.716116905212402 ,-55.921024322509766 ,1651.218505859375 ,1654.4324951171875 ,1647.8907470703125 ,1589.919189453125 ,1589.2406005859375 ,1587.611083984375 ,887.5587158203125 ,868.6121826171875 ,876.696044921875 ,1571.10107421875 ,1562.057861328125 ,1564.533203125 ,1629.3250732421875 ,1665.359130859375 ,1657.325927734375 ,1629.3250732421875 ,1657.325927734375 ,1643.3873291015625 ,1629.3250732421875 ,1609.0736083984375 ,1665.359130859375 ,1583.0238037109375 ,1574.396240234375 ,1574.923828125 ,1675.254150390625 ,1677.7841796875 ,1675.984375 ,1654.9130859375 ,1655.774658203125 ,1662.4249267578125 ,1627.998046875 ,1631.4022216796875 ,1630.8231201171875 ,1583.346435546875 ,1591.826904296875 ,1603.9329833984375 ,1583.346435546875 ,1603.9329833984375 ,1591.425537109375 ,1591.111083984375 ,1609.0880126953125 ,1453.39306640625 ,1453.39306640625 ,1609.0880126953125 ,1551.97705078125 ,1453.39306640625 ,1551.97705078125 ,1392.46337890625 ,1632.1265869140625 ,1590.92431640625 ,1603.4398193359375 ,1632.1265869140625 ,1639.727294921875 ,1590.92431640625 ,1632.1265869140625 ,1643.3873291015625 ,1639.727294921875 ,1632.1265869140625 ,1603.4398193359375 ,1643.3873291015625 ,1590.92431640625 ,1477.02099609375 ,1603.4398193359375 ,1603.4398193359375 ,1629.3250732421875 ,1643.3873291015625 ,1564.7724609375 ,1555.383056640625 ,1558.181884765625 ,1660.7340087890625 ,1659.01953125 ,1648.0037841796875 ,21.5523624420166 ,19.352371215820312 ,-0.7145509719848633 ,690.8013305664062 ,885.052490234375 ,831.5140991210938 ,-151.51779174804688 ,-149.3259735107422 ,-148.0751953125 ,-151.51779174804688 ,-148.0751953125 ,-148.95811462402344 ,1570.8770751953125 ,1576.539306640625 ,1563.897216796875 ,1011.23486328125 ,933.3903198242188 ,706.0634765625 ,1011.23486328125 ,706.0634765625 ,996.1683959960938 ,1011.23486328125 ,996.1683959960938 ,1178.7838134765625 ,1674.682861328125 ,1676.0706787109375 ,1675.4527587890625 ,184.67359924316406 ,171.8939208984375 ,191.36724853515625 ,889.2929077148438 ,896.8179321289062 ,909.6098022460938 ,1596.21337890625 ,1594.73974609375 ,1597.0556640625 ,1563.897216796875 ,1576.539306640625 ,1569.8341064453125 ,-154.77008056640625 ,-151.51779174804688 ,-154.53662109375 ,-154.77008056640625 ,-154.53662109375 ,-154.19302368164062 ,-154.19302368164062 ,-153.94642639160156 ,-152.8994903564453 ,-154.19302368164062 ,-154.53662109375 ,-153.94642639160156 ,1590.354248046875 ,1567.1591796875 ,1586.39990234375 ,1590.354248046875 ,1589.208251953125 ,1567.1591796875 ,1590.354248046875 ,1586.39990234375 ,1596.0208740234375 ,1596.0208740234375 ,1604.0233154296875 ,1590.354248046875 ,-87.2468490600586 ,-97.0417709350586 ,-54.067298889160156 ,-97.0417709350586 ,-97.18619537353516 ,-64.44239044189453 ,-97.0417709350586 ,-64.44239044189453 ,-54.067298889160156 ,-54.067298889160156 ,-64.44239044189453 ,-0.03479800000786781 ,-54.067298889160156 ,-0.03479800000786781 ,12.193948745727539 ,-54.067298889160156 ,12.193948745727539 ,-87.2468490600586 ,690.889404296875 ,707.375732421875 ,616.2135009765625 ,690.889404296875 ,599.6967163085938 ,696.3478393554688 ,690.889404296875 ,616.2135009765625 ,599.6967163085938 ,707.375732421875 ,724.7101440429688 ,616.2135009765625 ,-95.44017791748047 ,-102.72400665283203 ,-101.7322006225586 ,-95.44017791748047 ,-102.25055694580078 ,-102.72400665283203 ,-95.44017791748047 ,-101.7322006225586 ,-92.20603942871094 ,-95.44017791748047 ,-92.20603942871094 ,-93.75316619873047 ,1664.745849609375 ,1669.6060791015625 ,1662.7359619140625 ,1649.2138671875 ,1644.6551513671875 ,1638.4283447265625 ,1649.2138671875 ,1638.4283447265625 ,1645.947998046875 ,1645.947998046875 ,1646.7174072265625 ,1649.2138671875 ,1645.947998046875 ,1638.4283447265625 ,1646.7174072265625 ,1369.0794677734375 ,1477.3577880859375 ,1376.4482421875 ,1631.2967529296875 ,1626.0142822265625 ,1633.1820068359375 ,1631.2967529296875 ,1618.9720458984375 ,1626.0142822265625 ,1559.0006103515625 ,1565.91796875 ,1575.0830078125 ,1559.0006103515625 ,1575.0830078125 ,1558.611572265625 ,1559.0006103515625 ,1558.611572265625 ,1556.5849609375 ,-69.6546859741211 ,-47.91132736206055 ,-45.470542907714844 ,-69.6546859741211 ,-45.470542907714844 ,-75.83655548095703 ,1270.929931640625 ,1651.383056640625 ,1230.4781494140625 ,1258.1793212890625 ,1349.7996826171875 ,1076.6728515625 ,1464.8760986328125 ,1487.403564453125 ,1539.79345703125 ,1539.79345703125 ,1614.8197021484375 ,1464.8760986328125 ,1780.859619140625 ,1868.274169921875 ,1725.84033203125 ,1477.02099609375 ,1457.6270751953125 ,1349.7996826171875 ,1349.7996826171875 ,1457.6270751953125 ,1406.46630859375 ,-133.5084228515625 ,-39.66056442260742 ,-182.0306396484375 ,-133.5084228515625 ,-135.68988037109375 ,-87.2468490600586 ,824.8201904296875 ,823.284912109375 ,828.9366455078125 ,1649.8121337890625 ,1639.03369140625 ,1638.38623046875 ,1658.034912109375 ,1659.650634765625 ,1656.053955078125 ,1603.897705078125 ,1593.3319091796875 ,1590.896484375 ,1242.9195556640625 ,1348.066650390625 ,1358.700927734375 ,1588.5467529296875 ,1584.6922607421875 ,1589.62109375 ,1610.650146484375 ,1614.540771484375 ,1613.200927734375 ,1468.338623046875 ,1422.773193359375 ,1422.123779296875 ,1632.63623046875 ,1645.4649658203125 ,1638.3662109375 ,1629.5826416015625 ,1627.836669921875 ,1634.8624267578125 ,792.0645141601562 ,740.1326293945312 ,717.0455322265625 ,882.060302734375 ,868.6121826171875 ,869.6773071289062 ,882.060302734375 ,847.4163208007812 ,868.6121826171875 ,364.6614074707031 ,372.5214538574219 ,457.18621826171875 ,772.51806640625 ,762.7431640625 ,772.115966796875 ,-151.15257263183594 ,-160.0223388671875 ,-158.8724822998047 ,1600.82421875 ,1598.30029296875 ,1593.052978515625 ,816.8065795898438 ,868.6121826171875 ,777.5641479492188 ,1636.418212890625 ,1635.9273681640625 ,1638.4283447265625 ,1464.3046875 ,1404.30029296875 ,1409.1474609375 ,1409.1474609375 ,1404.30029296875 ,1376.0538330078125 ,-106.98082733154297 ,-182.0306396484375 ,-39.66056442260742 ,1604.43994140625 ,1609.2413330078125 ,1609.84326171875 ,1691.8638916015625 ,1690.71826171875 ,1690.2166748046875 ,1691.8638916015625 ,1690.2166748046875 ,1687.61474609375 ,1690.71826171875 ,1691.8638916015625 ,1692.7640380859375 ,1671.9622802734375 ,1678.3021240234375 ,1678.15283203125 ,1671.9622802734375 ,1673.7159423828125 ,1678.3021240234375 ,1690.700439453125 ,1680.5875244140625 ,1695.0233154296875 ,-243.66262817382812 ,-195.4857635498047 ,-271.23895263671875 ,-101.7322006225586 ,-89.05227661132812 ,-92.20603942871094 ,-92.20603942871094 ,-89.05227661132812 ,-90.16954040527344 ,777.0218505859375 ,732.3037109375 ,746.5462036132812 ,777.0218505859375 ,746.5462036132812 ,778.3938598632812 ,813.8816528320312 ,774.6493530273438 ,822.809326171875 ,774.6493530273438 ,790.0026245117188 ,822.809326171875 ,-85.8126449584961 ,-121.91429901123047 ,-56.86187744140625 ,1614.396728515625 ,1588.3834228515625 ,1597.1463623046875 ,1614.396728515625 ,1624.51708984375 ,1618.32177734375 ,1614.396728515625 ,1597.1463623046875 ,1624.51708984375 ,803.9970092773438 ,795.6617431640625 ,803.208251953125 ,803.9970092773438 ,803.208251953125 ,803.6015625 ,-145.88516235351562 ,-150.79893493652344 ,-153.44960021972656 ,-157.6728057861328 ,-150.53488159179688 ,-171.90296936035156 ,1622.0340576171875 ,1610.0328369140625 ,1591.826904296875 ,1653.5064697265625 ,1643.0556640625 ,1649.8121337890625 ,1643.0556640625 ,1641.5897216796875 ,1649.8121337890625 ,616.2135009765625 ,724.7101440429688 ,679.6201171875 ,1658.153564453125 ,1654.66064453125 ,1653.60546875 ,-142.97039794921875 ,-144.49041748046875 ,-143.8408203125 ,-142.97039794921875 ,-142.55540466308594 ,-144.49041748046875 ,-144.49041748046875 ,-145.88516235351562 ,-143.8408203125 ,957.6220092773438 ,883.0206909179688 ,1101.100830078125 ,957.6220092773438 ,1101.100830078125 ,1123.979736328125 ,1541.419677734375 ,1542.4107666015625 ,1544.49267578125 ,1542.4107666015625 ,1541.419677734375 ,1544.3592529296875 ,1621.124755859375 ,1613.7576904296875 ,1622.59228515625 ,-224.1885223388672 ,-206.4029083251953 ,-228.321533203125 ,-224.1885223388672 ,-228.321533203125 ,-208.4066162109375 ,-224.1885223388672 ,-208.4066162109375 ,-194.07723999023438 ,-126.1890640258789 ,-129.64761352539062 ,-133.1144561767578 ,-126.1890640258789 ,-120.36861419677734 ,-129.64761352539062 ,-115.24518585205078 ,-123.30195617675781 ,-119.94938659667969 ,-115.24518585205078 ,-111.19154357910156 ,-110.93496704101562 ,-115.24518585205078 ,-119.94938659667969 ,-111.19154357910156 ,-110.93496704101562 ,-111.19154357910156 ,-109.44664764404297 ,1667.9810791015625 ,1663.043212890625 ,1664.859130859375 ,1667.9810791015625 ,1666.635498046875 ,1663.043212890625 ,-399.59234619140625 ,-396.90313720703125 ,-304.0158386230469 ,-399.59234619140625 ,-402.4700927734375 ,-209.7818145751953 ,1556.3740234375 ,1557.5587158203125 ,1559.673828125 ,1557.5587158203125 ,1565.7703857421875 ,1559.673828125 ,1083.5889892578125 ,987.7450561523438 ,1055.40966796875 ,987.7450561523438 ,982.1719970703125 ,1055.40966796875 ,1055.40966796875 ,982.1719970703125 ,1042.39111328125 ,831.1430053710938 ,846.5791625976562 ,851.3971557617188 ,-146.06394958496094 ,-148.95811462402344 ,-142.55540466308594 ,1613.200927734375 ,1609.84326171875 ,1610.650146484375 ,-271.23895263671875 ,-297.79754638671875 ,-160.0223388671875 ,14.917814254760742 ,-64.44239044189453 ,-70.94931030273438 ,14.917814254760742 ,-8.9946870803833 ,-64.44239044189453 ,1644.7110595703125 ,1633.1016845703125 ,1642.044677734375 ,1644.7110595703125 ,1645.72412109375 ,1635.94482421875 ,1178.7838134765625 ,1170.9833984375 ,1100.494384765625 ,-138.8220977783203 ,-142.54470825195312 ,-140.01162719726562 ,-148.95811462402344 ,-145.5254364013672 ,-142.55540466308594 ,-148.95811462402344 ,-148.0751953125 ,-145.5254364013672 ,867.532958984375 ,890.9190673828125 ,832.0707397460938 ,1565.482666015625 ,1567.3592529296875 ,1554.4915771484375 ,1580.116943359375 ,1585.578369140625 ,1581.63818359375 ,1154.2872314453125 ,1174.9976806640625 ,1315.204833984375 ,657.6510620117188 ,804.7008056640625 ,687.8463134765625 ,657.6510620117188 ,690.8013305664062 ,804.7008056640625 ,784.7041015625 ,779.576904296875 ,785.9521484375 ,779.576904296875 ,784.7041015625 ,771.9223022460938 ,779.576904296875 ,784.9035034179688 ,785.9521484375 ,1359.5948486328125 ,1464.8760986328125 ,1547.40478515625 ,1690.5087890625 ,1689.9307861328125 ,1691.2550048828125 ,1690.5087890625 ,1689.8787841796875 ,1689.9307861328125 ,1690.5087890625 ,1691.2550048828125 ,1691.13720703125 ,1690.5087890625 ,1691.13720703125 ,1691.32421875 ,1690.5087890625 ,1691.32421875 ,1689.8787841796875 ,1689.9307861328125 ,1689.559814453125 ,1691.2550048828125 ,1689.9307861328125 ,1689.8787841796875 ,1689.230224609375 ,1623.8203125 ,1607.47314453125 ,1635.171875 ,67.64774322509766 ,72.49295806884766 ,32.23271942138672 ,67.64774322509766 ,32.23271942138672 ,70.94438171386719 ,67.64774322509766 ,43.55766677856445 ,72.49295806884766 ,67.64774322509766 ,70.94438171386719 ,-24.251636505126953 ,157.475830078125 ,162.90782165527344 ,143.64382934570312 ,1371.5784912109375 ,1369.0794677734375 ,1365.138916015625 ,-102.72400665283203 ,-117.45018768310547 ,-101.7322006225586 ,732.1451416015625 ,734.4566040039062 ,723.9068603515625 ,732.1451416015625 ,732.3037109375 ,734.4566040039062 ,732.1451416015625 ,723.9068603515625 ,706.3660278320312 ,1749.2783203125 ,1713.242431640625 ,1763.056884765625 ,1604.053466796875 ,1602.7296142578125 ,1604.458251953125 ,1604.053466796875 ,1600.29052734375 ,1602.7296142578125 ,-115.4434585571289 ,-114.91108703613281 ,-76.51492309570312 ,1463.4681396484375 ,1477.014404296875 ,1418.7108154296875 ,1418.7108154296875 ,1477.014404296875 ,1420.429931640625 ,1570.8770751953125 ,1568.362060546875 ,1574.650390625 ,1570.8770751953125 ,1574.650390625 ,1577.8319091796875 ,1537.858642578125 ,1550.6932373046875 ,1541.919921875 ,1537.858642578125 ,1541.919921875 ,1534.9771728515625 ,1315.80810546875 ,1358.700927734375 ,1351.378662109375 ,1885.6708984375 ,2068.06982421875 ,2235.03515625 ,1662.020263671875 ,1664.063232421875 ,1668.54248046875 ,1662.020263671875 ,1668.54248046875 ,1662.9674072265625 ,1687.83935546875 ,1684.5474853515625 ,1686.9090576171875 ,-37.357818603515625 ,-90.48092651367188 ,-77.23518371582031 ,805.5436401367188 ,787.6427001953125 ,754.8847045898438 ,1338.5748291015625 ,1385.2088623046875 ,1396.57275390625 ,1338.5748291015625 ,1396.57275390625 ,1363.837646484375 ,1775.8941650390625 ,1770.8345947265625 ,1756.6732177734375 ,1775.8941650390625 ,1780.6429443359375 ,1770.8345947265625 ,1770.8345947265625 ,1753.8916015625 ,1756.6732177734375 ,1756.6732177734375 ,1753.8916015625 ,1727.8466796875 ,1570.8770751953125 ,1553.089111328125 ,1568.362060546875 ,1568.362060546875 ,1553.089111328125 ,1561.940673828125 ,942.9981689453125 ,1003.959716796875 ,1010.2650756835938 ,1632.9971923828125 ,1626.644287109375 ,1627.227294921875 ,1639.3721923828125 ,1642.0712890625 ,1635.6751708984375 ,1648.089111328125 ,1638.164794921875 ,1632.47265625 ,1648.089111328125 ,1651.2288818359375 ,1638.164794921875 ,1648.089111328125 ,1649.7333984375 ,1651.2288818359375 ,1405.2806396484375 ,1424.42041015625 ,1422.123779296875 ,1405.2806396484375 ,1422.123779296875 ,1396.57275390625 ,1422.123779296875 ,1422.773193359375 ,1396.57275390625 ,-123.30195617675781 ,-129.4573974609375 ,-119.94938659667969 ,1645.921630859375 ,1648.9278564453125 ,1644.4151611328125 ,1645.921630859375 ,1648.4556884765625 ,1648.84814453125 ,1645.921630859375 ,1648.84814453125 ,1648.9278564453125 ,1683.2618408203125 ,1684.3946533203125 ,1684.2529296875 ,1604.458251953125 ,1585.6143798828125 ,1613.8966064453125 ,900.3047485351562 ,808.1926879882812 ,809.3809204101562 ,809.3809204101562 ,780.2534790039062 ,858.2318115234375 ,1517.98193359375 ,1375.368896484375 ,1578.2552490234375 ,1578.2552490234375 ,1375.368896484375 ,1500.01318359375 ,1659.650634765625 ,1662.6346435546875 ,1659.5093994140625 ,1659.650634765625 ,1660.4757080078125 ,1662.6346435546875 ,1662.6346435546875 ,1660.4757080078125 ,1667.19677734375 ,1659.5093994140625 ,1662.6346435546875 ,1655.774658203125 ,1659.5093994140625 ,1655.774658203125 ,1657.146728515625 ,1659.5093994140625 ,1657.146728515625 ,1659.650634765625 ,-133.5084228515625 ,-148.29736328125 ,-135.68988037109375 ,831.0919189453125 ,828.9366455078125 ,823.83154296875 ,782.33935546875 ,790.466796875 ,795.55419921875 ,1589.48583984375 ,1590.207763671875 ,1573.8131103515625 ,1590.207763671875 ,1592.21435546875 ,1586.4669189453125 ,1601.854736328125 ,1600.544921875 ,1601.023681640625 ,1593.351806640625 ,1582.647705078125 ,1594.8846435546875 ,778.0476684570312 ,668.2542114257812 ,393.78424072265625 ,393.78424072265625 ,668.2542114257812 ,363.066162109375 ,-172.63314819335938 ,-170.48284912109375 ,-166.1901092529297 ,-172.63314819335938 ,-172.25660705566406 ,-170.48284912109375 ,-157.5364990234375 ,-153.2115020751953 ,-157.58616638183594 ,-157.5364990234375 ,-155.69383239746094 ,-153.2115020751953 ,14.917814254760742 ,79.7586669921875 ,126.69802856445312 ,1858.9906005859375 ,1841.949462890625 ,1843.4600830078125 ,1858.9906005859375 ,1843.4600830078125 ,1894.6409912109375 ,1858.9906005859375 ,1894.6409912109375 ,1894.75439453125 ,892.542236328125 ,907.8963012695312 ,930.5149536132812 ,887.3312377929688 ,957.0482788085938 ,933.4078369140625 ,887.3312377929688 ,881.7615966796875 ,957.0482788085938 ,729.5888061523438 ,693.4887084960938 ,687.8463134765625 ,1600.05419921875 ,1600.1142578125 ,1600.7247314453125 ,1600.05419921875 ,1600.7247314453125 ,1599.7681884765625 ,1600.05419921875 ,1600.6370849609375 ,1600.1142578125 ,1600.05419921875 ,1598.824462890625 ,1600.6370849609375 ,1600.05419921875 ,1599.7681884765625 ,1598.824462890625 ,1600.1142578125 ,1600.4422607421875 ,1600.7247314453125 ,1600.1142578125 ,1601.023681640625 ,1600.4422607421875 ,1600.1142578125 ,1600.6370849609375 ,1601.023681640625 ,1600.7247314453125 ,1600.4422607421875 ,1601.2574462890625 ,1689.8233642578125 ,1689.4713134765625 ,1688.41552734375 ,1464.3046875 ,1409.1474609375 ,1406.46630859375 ,1562.0313720703125 ,1565.5657958984375 ,1592.7005615234375 ,1562.0313720703125 ,1592.7005615234375 ,1572.6234130859375 ,1562.0313720703125 ,1572.6234130859375 ,1570.0733642578125 ,1511.5054931640625 ,1465.8497314453125 ,1436.84033203125 ,909.6098022460938 ,886.61474609375 ,894.9439086914062 ,13.958344459533691 ,-168.038330078125 ,-301.7873840332031 ,-117.45018768310547 ,-129.64761352539062 ,-120.36861419677734 ,-129.64761352539062 ,-137.802978515625 ,-133.1144561767578 ,1657.1484375 ,1665.584716796875 ,1653.017822265625 ,1657.1484375 ,1669.4385986328125 ,1665.584716796875 ,1641.5897216796875 ,1639.03369140625 ,1649.8121337890625 ,48.81981658935547 ,63.12164306640625 ,125.16410064697266 ,48.81981658935547 ,12.87821102142334 ,63.12164306640625 ,125.16410064697266 ,126.56841278076172 ,48.81981658935547 ,-190.1183624267578 ,-275.2289733886719 ,-208.45709228515625 ,743.8383178710938 ,778.3737182617188 ,772.87109375 ,743.8383178710938 ,729.2923583984375 ,778.3737182617188 ,743.8383178710938 ,683.404296875 ,729.2923583984375 ,40.656192779541016 ,-3.302182912826538 ,11.090381622314453 ,774.6493530273438 ,741.1661987304688 ,790.0026245117188 ,797.3441772460938 ,793.8865356445312 ,774.7361450195312 ,793.8865356445312 ,782.3931274414062 ,774.7361450195312 ,774.7361450195312 ,782.3931274414062 ,793.8484497070312 ,774.7361450195312 ,793.8484497070312 ,797.3441772460938 ,979.0367431640625 ,968.173828125 ,943.1953125 ,979.0367431640625 ,1022.6570434570312 ,968.173828125 ,968.173828125 ,967.2301635742188 ,948.989013671875 ,1684.2529296875 ,1678.84521484375 ,1683.2618408203125 ,1684.2529296875 ,1677.5621337890625 ,1678.84521484375 ,1170.9833984375 ,1246.9864501953125 ,1223.370849609375 ,803.314697265625 ,803.9970092773438 ,803.6015625 ,1684.94921875 ,1685.16943359375 ,1684.0565185546875 ,-146.486328125 ,-145.95632934570312 ,-145.7958221435547 ,1637.1361083984375 ,1639.416259765625 ,1645.428466796875 ,1637.1361083984375 ,1637.7620849609375 ,1639.416259765625 ,1665.4837646484375 ,1645.7232666015625 ,1641.5775146484375 ,1665.4837646484375 ,1641.5775146484375 ,1651.0067138671875 ,804.2484741210938 ,787.5003662109375 ,791.5802001953125 ,791.5802001953125 ,787.5003662109375 ,783.5720825195312 ,1825.7593994140625 ,1822.6085205078125 ,1819.286376953125 ,623.9884643554688 ,687.7828979492188 ,682.0635986328125 ,682.0635986328125 ,687.5601806640625 ,621.688720703125 ,682.0635986328125 ,621.688720703125 ,623.9884643554688 ,143.4466094970703 ,84.34304809570312 ,141.32933044433594 ,1567.23486328125 ,1558.35107421875 ,1560.2164306640625 ,1560.2164306640625 ,1552.678466796875 ,1557.9974365234375 ,1567.23486328125 ,1565.91796875 ,1558.35107421875 ,43.55766677856445 ,14.137516021728516 ,50.4521484375 ,43.55766677856445 ,50.4521484375 ,51.920265197753906 ,43.55766677856445 ,51.920265197753906 ,72.49295806884766 ,1455.2423095703125 ,1223.370849609375 ,1246.9864501953125 ,1538.7110595703125 ,1546.6407470703125 ,1534.2867431640625 ,1538.7110595703125 ,1534.2867431640625 ,1528.123779296875 ,1372.3671875 ,1340.64990234375 ,1347.18408203125 ,1372.3671875 ,1347.18408203125 ,1406.17626953125 ,-92.26326751708984 ,-93.72039031982422 ,-97.40780639648438 ,-92.26326751708984 ,-97.40780639648438 ,-97.81755828857422 ,854.6092529296875 ,857.0423583984375 ,862.65185546875 ,1591.826904296875 ,1617.2596435546875 ,1603.9329833984375 ,1591.826904296875 ,1610.0328369140625 ,1617.2596435546875 ,974.2076416015625 ,942.9981689453125 ,890.9190673828125 ,942.9981689453125 ,884.965576171875 ,890.9190673828125 ,1629.037841796875 ,1643.0020751953125 ,1631.0205078125 ,-115.4434585571289 ,-84.93722534179688 ,-114.91108703613281 ,829.1942138671875 ,830.006103515625 ,813.8816528320312 ,966.7046508789062 ,866.9893798828125 ,774.2960205078125 ,1659.63916015625 ,1656.557861328125 ,1657.4427490234375 ,1659.63916015625 ,1660.75048828125 ,1658.034912109375 ,1659.63916015625 ,1662.6409912109375 ,1660.75048828125 ,1659.63916015625 ,1657.4427490234375 ,1662.6409912109375 ,832.0707397460938 ,865.3997802734375 ,867.532958984375 ,865.3997802734375 ,786.929931640625 ,777.9039916992188 ,-297.3943176269531 ,-304.0158386230469 ,-223.46041870117188 ,793.496337890625 ,777.6443481445312 ,783.1329956054688 ,1557.9974365234375 ,1547.3134765625 ,1555.195556640625 ,1557.9974365234375 ,1552.678466796875 ,1547.3134765625 ,1547.3134765625 ,1544.49267578125 ,1555.195556640625 ,1617.68212890625 ,1623.6824951171875 ,1627.878662109375 ,798.400390625 ,800.04736328125 ,801.35595703125 ,1674.808837890625 ,1670.9378662109375 ,1673.802490234375 ,1673.802490234375 ,1674.3995361328125 ,1674.808837890625 ,1673.802490234375 ,1673.563720703125 ,1674.3995361328125 ,1673.802490234375 ,1670.9378662109375 ,1673.563720703125 ,1664.204345703125 ,1681.109130859375 ,1665.359130859375 ,1664.204345703125 ,1675.038330078125 ,1681.109130859375 ,1665.359130859375 ,1681.109130859375 ,1685.0931396484375 ,1660.8375244140625 ,1669.9747314453125 ,1671.489013671875 ,1660.8375244140625 ,1671.489013671875 ,1667.297607421875 ,1660.8375244140625 ,1667.297607421875 ,1667.4793701171875 ,1657.2174072265625 ,1656.9443359375 ,1660.623779296875 ,1657.2174072265625 ,1653.266357421875 ,1656.9443359375 ,1678.3021240234375 ,1673.7159423828125 ,1675.08056640625 ,1629.3250732421875 ,1603.4398193359375 ,1609.0736083984375 ,-135.0819854736328 ,-143.4319305419922 ,-139.26251220703125 ,-135.0819854736328 ,-148.29736328125 ,-143.4319305419922 ,-139.26251220703125 ,-143.4319305419922 ,-137.65219116210938 ,-139.26251220703125 ,-137.65219116210938 ,-127.38860321044922 ,-139.26251220703125 ,-127.38860321044922 ,-135.0819854736328 ,1125.4884033203125 ,1234.9974365234375 ,1347.417236328125 ,1557.9974365234375 ,1555.195556640625 ,1560.262451171875 ,1671.44140625 ,1672.2923583984375 ,1674.808837890625 ,1671.44140625 ,1674.808837890625 ,1674.3995361328125 ,786.3716430664062 ,759.187255859375 ,778.0946044921875 ,786.3716430664062 ,778.0946044921875 ,778.7622680664062 ,1537.597900390625 ,1506.75048828125 ,1542.666748046875 ,991.6287841796875 ,998.5934448242188 ,965.6051025390625 ,991.6287841796875 ,1009.9961547851562 ,1018.4336547851562 ,991.6287841796875 ,1018.4336547851562 ,998.5934448242188 ,991.6287841796875 ,965.6051025390625 ,990.3247680664062 ,991.6287841796875 ,990.3247680664062 ,1009.9961547851562 ,1538.919189453125 ,1537.8978271484375 ,1537.7679443359375 ,1544.1461181640625 ,1540.3974609375 ,1541.107177734375 ,725.7775268554688 ,717.6525268554688 ,727.0682983398438 ,1617.2596435546875 ,1622.0340576171875 ,1625.169189453125 ,1617.2596435546875 ,1617.3553466796875 ,1622.0340576171875 ,1656.557861328125 ,1651.5751953125 ,1657.4427490234375 ,1642.1343994140625 ,1657.8052978515625 ,1652.9178466796875 ,1693.4378662109375 ,1693.0911865234375 ,1691.8638916015625 ,1568.663818359375 ,1581.1905517578125 ,1566.70947265625 ,1568.663818359375 ,1578 ,1581.1905517578125 ,1581.1905517578125 ,1580.116943359375 ,1566.70947265625 ,1561.478515625 ,1552.7763671875 ,1550.6932373046875 ,1561.478515625 ,1561.940673828125 ,1552.7763671875 ,757.730712890625 ,793.8484497070312 ,768.367431640625 ,793.8484497070312 ,782.3931274414062 ,768.367431640625 ,-152.8994903564453 ,-153.84323120117188 ,-151.143798828125 ,-152.8994903564453 ,-153.94642639160156 ,-153.84323120117188 ,-110.61604309082031 ,-102.13951873779297 ,-111.19154357910156 ,1688.41552734375 ,1686.08740234375 ,1685.1209716796875 ,1552.476318359375 ,1489.4591064453125 ,1523.4749755859375 ,1523.4749755859375 ,1598.2261962890625 ,1552.476318359375 ,755.9078369140625 ,712.0097045898438 ,722.6234130859375 ,1606.3082275390625 ,1512.47705078125 ,1562.5577392578125 ,1540.1556396484375 ,1546.7625732421875 ,1542.1912841796875 ,1542.1912841796875 ,1546.7625732421875 ,1543.416748046875 ,1542.1912841796875 ,1543.416748046875 ,1548.867919921875 ,364.6614074707031 ,457.18621826171875 ,391.55621337890625 ,1638.36181640625 ,1649.4178466796875 ,1646.806640625 ,1638.36181640625 ,1645.72412109375 ,1649.4178466796875 ,1638.36181640625 ,1635.94482421875 ,1645.72412109375 ,1646.806640625 ,1649.4178466796875 ,1645.72412109375 ,1554.4915771484375 ,1567.3592529296875 ,1559.339111328125 ,806.8987426757812 ,740.1326293945312 ,792.0645141601562 ,693.4887084960938 ,739.697509765625 ,726.8759765625 ,957.0482788085938 ,918.0545654296875 ,1035.0845947265625 ,-208.4066162109375 ,-206.4029083251953 ,-171.53567504882812 ,-108.51872253417969 ,-69.6546859741211 ,-75.83655548095703 ,-108.51872253417969 ,-147.58274841308594 ,-142.4543914794922 ,-108.51872253417969 ,-112.15628051757812 ,-147.58274841308594 ,-108.51872253417969 ,-75.83655548095703 ,-112.15628051757812 ,979.0367431640625 ,943.1953125 ,981.9210815429688 ,1660.21875 ,1663.5411376953125 ,1667.793701171875 ,1660.21875 ,1632.47265625 ,1663.5411376953125 ,1663.5411376953125 ,1663.552978515625 ,1667.793701171875 ,1663.5411376953125 ,1659.3050537109375 ,1663.552978515625 ,1667.793701171875 ,1669.09912109375 ,1660.21875 ,1667.793701171875 ,1663.552978515625 ,1669.09912109375 ,1685.785888671875 ,1682.081298828125 ,1681.7762451171875 ,142.91012573242188 ,126.7732162475586 ,126.56841278076172 ,126.7732162475586 ,97.57292175292969 ,126.56841278076172 ,126.7732162475586 ,142.91012573242188 ,97.57292175292969 ,1604.3963623046875 ,1602.7296142578125 ,1604.5452880859375 ,1587.6796875 ,1601.7579345703125 ,1592.7005615234375 ,710.6922607421875 ,700.0632934570312 ,546.88916015625 ,454.2554016113281 ,542.66552734375 ,393.78424072265625 ,1753.8916015625 ,1649.6490478515625 ,1727.8466796875 ,1753.8916015625 ,1629.09130859375 ,1614.8197021484375 ,1753.8916015625 ,1614.8197021484375 ,1649.6490478515625 ,1009.9961547851562 ,978.0360717773438 ,988.48779296875 ,988.48779296875 ,978.0360717773438 ,978.5054931640625 ,787.6688232421875 ,778.3762817382812 ,799.7229614257812 ,1669.6060791015625 ,1678.28515625 ,1678.89990234375 ,852.4119873046875 ,840.1530151367188 ,845.933349609375 ,659.8430786132812 ,500.4654235839844 ,616.2135009765625 ,616.2135009765625 ,679.6201171875 ,659.8430786132812 ,1613.9197998046875 ,1619.9852294921875 ,1646.99853515625 ,1687.4100341796875 ,1687.034912109375 ,1689.44873046875 ,1687.4100341796875 ,1689.44873046875 ,1688.0460205078125 ,1669.09912109375 ,1648.089111328125 ,1660.21875 ,1669.09912109375 ,1649.7333984375 ,1648.089111328125 ,-190.1183624267578 ,-208.45709228515625 ,-158.5607147216797 ,1347.18408203125 ,1417.4075927734375 ,1409.03564453125 ,1347.18408203125 ,1422.773193359375 ,1417.4075927734375 ,1347.18408203125 ,1409.03564453125 ,1406.17626953125 ,1588.5582275390625 ,1666.2265625 ,1527.3734130859375 ,1588.5582275390625 ,1536.4788818359375 ,1592.6134033203125 ,1588.5582275390625 ,1527.3734130859375 ,1536.4788818359375 ,-105.42487335205078 ,-116.43907928466797 ,-123.86084747314453 ,724.7101440429688 ,692.2950439453125 ,679.6201171875 ,-148.42178344726562 ,-147.34451293945312 ,-149.68702697753906 ,1609.0736083984375 ,1616.805419921875 ,1665.359130859375 ,50.4521484375 ,9.825300216674805 ,51.920265197753906 ,-142.19842529296875 ,-142.89480590820312 ,-150.6800994873047 ,-142.19842529296875 ,-136.4071044921875 ,-142.89480590820312 ,-142.19842529296875 ,-158.22862243652344 ,-136.4071044921875 ,-142.19842529296875 ,-150.6800994873047 ,-158.22862243652344 ,-145.7958221435547 ,-156.220947265625 ,-151.15257263183594 ,966.7046508789062 ,965.6051025390625 ,866.9893798828125 ,1591.826904296875 ,1575.0830078125 ,1622.0340576171875 ,1600.60546875 ,1598.30029296875 ,1601.320556640625 ,1600.60546875 ,1600.6370849609375 ,1598.30029296875 ,784.7041015625 ,803.8378295898438 ,793.496337890625 ,784.7041015625 ,785.9521484375 ,803.8378295898438 ,1660.623779296875 ,1656.9443359375 ,1659.2353515625 ,1678.8447265625 ,1680.8697509765625 ,1682.7294921875 ,1607.9425048828125 ,1620.97802734375 ,1620.9906005859375 ,1607.9425048828125 ,1585.0457763671875 ,1620.97802734375 ,1607.9425048828125 ,1620.9906005859375 ,1616.751220703125 ,1620.9906005859375 ,1620.778564453125 ,1616.751220703125 ,1620.9906005859375 ,1620.97802734375 ,1620.778564453125 ,1597.5272216796875 ,1600.8250732421875 ,1597.9208984375 ,1648.6241455078125 ,1647.1204833984375 ,1644.97119140625 ,1596.8861083984375 ,1636.007568359375 ,1591.111083984375 ,1636.007568359375 ,1602.2877197265625 ,1591.111083984375 ,1582.167724609375 ,1576.539306640625 ,1590.534423828125 ,1678.15283203125 ,1678.3021240234375 ,1679.8707275390625 ,1593.195068359375 ,1583.0238037109375 ,1574.923828125 ,805.0759887695312 ,825.994140625 ,803.8378295898438 ,561.8804931640625 ,1101.100830078125 ,883.0206909179688 ,-151.19723510742188 ,-158.5607147216797 ,-159.0187530517578 ,1593.8929443359375 ,1597.4324951171875 ,1594.5810546875 ,1593.8929443359375 ,1594.5810546875 ,1588.4100341796875 ,1588.4100341796875 ,1594.5810546875 ,1594.0908203125 ,982.1719970703125 ,945.8577880859375 ,1042.39111328125 ,105.0716323852539 ,-209.7818145751953 ,-402.4700927734375 ,105.0716323852539 ,387.1172790527344 ,-209.7818145751953 ,2068.06982421875 ,1870.11962890625 ,2080.4912109375 ,2068.06982421875 ,2080.4912109375 ,2391.385498046875 ,2068.06982421875 ,2391.385498046875 ,2235.03515625 ,143.64382934570312 ,248.44900512695312 ,165.0082244873047 ,1534.2867431640625 ,1546.6407470703125 ,1538.6708984375 ,1546.6407470703125 ,1563.31787109375 ,1567.586669921875 ,1546.6407470703125 ,1567.586669921875 ,1538.6708984375 ,495.27227783203125 ,482.605712890625 ,590.23095703125 ,495.27227783203125 ,693.88330078125 ,652.3643798828125 ,1083.865478515625 ,1011.173583984375 ,1018.4336547851562 ,1011.173583984375 ,998.5934448242188 ,1018.4336547851562 ,833.7752075195312 ,744.9285278320312 ,781.4766845703125 ,833.7752075195312 ,781.4766845703125 ,887.4142456054688 ,972.8710327148438 ,1065.2171630859375 ,912.0824584960938 ,1666.755126953125 ,1667.6173095703125 ,1667.3428955078125 ,1666.755126953125 ,1667.3428955078125 ,1664.8974609375 ,87.79638671875 ,1.143841028213501 ,125.14277648925781 ,1637.9412841796875 ,1646.7701416015625 ,1642.2862548828125 ,54.11753845214844 ,51.06891632080078 ,58.55487060546875 ,2016.6395263671875 ,1980.4984130859375 ,2080.4912109375 ,-166.4710693359375 ,-165.2589569091797 ,-166.96328735351562 ,-166.4710693359375 ,-162.77415466308594 ,-165.2589569091797 ,-165.2589569091797 ,-166.50289916992188 ,-166.96328735351562 ,1574.396240234375 ,1564.533203125 ,1574.923828125 ,965.5859985351562 ,907.8963012695312 ,969.9252319335938 ,965.5859985351562 ,966.2996215820312 ,907.8963012695312 ,965.5859985351562 ,978.5054931640625 ,966.2996215820312 ,1594.8846435546875 ,1582.647705078125 ,1591.385986328125 ,793.496337890625 ,784.005615234375 ,777.6443481445312 ,885.052490234375 ,988.9864501953125 ,831.5140991210938 ,-22.08594512939453 ,-224.1885223388672 ,-95.96955108642578 ,-97.74697875976562 ,-55.224124908447266 ,-84.37976837158203 ,-97.74697875976562 ,-75.83655548095703 ,-45.470542907714844 ,-97.74697875976562 ,-45.470542907714844 ,-55.224124908447266 ,-97.74697875976562 ,-112.15628051757812 ,-75.83655548095703 ,-166.1901092529297 ,-170.48284912109375 ,-160.60240173339844 ,795.9425048828125 ,800.8710327148438 ,806.5247192382812 ,670.9752807617188 ,672.4046020507812 ,668.2109985351562 ,1070.3936767578125 ,1079.9857177734375 ,1092.355224609375 ,1552.476318359375 ,1598.2261962890625 ,1585.6143798828125 ,1582.832275390625 ,1597.1463623046875 ,1588.3834228515625 ,692.2950439453125 ,659.8430786132812 ,679.6201171875 ,692.2950439453125 ,683.6290893554688 ,659.8430786132812 ,-48.14024353027344 ,-57.356292724609375 ,-116.43762969970703 ,-48.14024353027344 ,-116.43762969970703 ,-121.85279083251953 ,165.0082244873047 ,248.44900512695312 ,238.97511291503906 ,238.97511291503906 ,248.44900512695312 ,341.78338623046875 ,799.5333251953125 ,815.1546020507812 ,821.3425903320312 ,1662.5382080078125 ,1665.584716796875 ,1673.310302734375 ,1673.310302734375 ,1669.4385986328125 ,1680.5875244140625 ,1673.310302734375 ,1665.584716796875 ,1669.4385986328125 ,781.025146484375 ,784.7091674804688 ,783.279052734375 ,781.025146484375 ,783.279052734375 ,780.8228759765625 ,1682.081298828125 ,1678.16552734375 ,1670.4793701171875 ,1682.081298828125 ,1670.4793701171875 ,1672.82763671875 ,1640.646728515625 ,1640.44482421875 ,1630.4327392578125 ,1694.8782958984375 ,1678.83642578125 ,1684.8160400390625 ,1694.8782958984375 ,1694.167724609375 ,1678.83642578125 ,1027.87646484375 ,962.6599731445312 ,957.0482788085938 ,-170.48284912109375 ,-172.25660705566406 ,-170.53453063964844 ,-170.48284912109375 ,-162.18087768554688 ,-160.60240173339844 ,806.5247192382812 ,823.83154296875 ,818.7212524414062 ,823.83154296875 ,828.9366455078125 ,818.7212524414062 ,1692.538330078125 ,1692.223876953125 ,1691.309814453125 ,1692.538330078125 ,1691.309814453125 ,1690.71826171875 ,-140.02178955078125 ,-133.48570251464844 ,-137.036376953125 ,-140.02178955078125 ,-138.11817932128906 ,-133.48570251464844 ,149.82284545898438 ,92.03718566894531 ,51.283111572265625 ,1554.2913818359375 ,1548.867919921875 ,1556.6285400390625 ,1554.2913818359375 ,1556.6285400390625 ,1556.0794677734375 ,621.688720703125 ,608.802734375 ,623.9884643554688 ,621.688720703125 ,570.5579223632812 ,608.802734375 ,621.688720703125 ,640.021728515625 ,570.5579223632812 ,621.688720703125 ,687.5601806640625 ,640.021728515625 ,1600.82421875 ,1593.052978515625 ,1592.876953125 ,87.79638671875 ,143.64382934570312 ,36.17856216430664 ,-97.66888427734375 ,-92.81271362304688 ,-110.61604309082031 ,978.5054931640625 ,978.0360717773438 ,975.6517333984375 ,1763.056884765625 ,1713.242431640625 ,1763.4459228515625 ,1618.220947265625 ,1653.017822265625 ,1650.9715576171875 ,1592.2626953125 ,1600.057861328125 ,1594.7960205078125 ,1631.577392578125 ,1632.4642333984375 ,1633.0850830078125 ,1631.577392578125 ,1628.7613525390625 ,1632.4642333984375 ,1625.290283203125 ,1630.1005859375 ,1637.1361083984375 ,162.90782165527344 ,153.8966064453125 ,148.8214874267578 ,-114.11538696289062 ,-118.78472900390625 ,-103.92625427246094 ,-103.92625427246094 ,-118.78472900390625 ,-107.67842864990234 ,707.375732421875 ,753.95947265625 ,724.7101440429688 ,842.704833984375 ,868.5808715820312 ,880.638427734375 ,842.704833984375 ,880.638427734375 ,852.4590454101562 ,842.704833984375 ,846.4307861328125 ,868.5808715820312 ,842.704833984375 ,852.4590454101562 ,825.4397583007812 ,778.2691650390625 ,778.7959594726562 ,773.294677734375 ,1663.3662109375 ,1664.8974609375 ,1660.623779296875 ,1663.3662109375 ,1660.623779296875 ,1664.044677734375 ,1076.6728515625 ,1349.7996826171875 ,1391.6668701171875 ,1701.290283203125 ,1784.3990478515625 ,1768.0631103515625 ,1701.290283203125 ,1698.6005859375 ,1784.3990478515625 ,1175.87353515625 ,1123.282470703125 ,1120.439208984375 ,1659.6895751953125 ,1670.4410400390625 ,1660.89501953125 ,1597.156982421875 ,1598.9300537109375 ,1597.928955078125 ,221.2639923095703 ,466.0267333984375 ,481.72210693359375 ,719.1813354492188 ,754.551025390625 ,704.05419921875 ,719.1813354492188 ,740.9560546875 ,754.551025390625 ,933.4078369140625 ,957.0482788085938 ,962.6599731445312 ,1645.6033935546875 ,1623.0599365234375 ,1595.7293701171875 ,1645.6033935546875 ,1712.3887939453125 ,1623.0599365234375 ,-112.15628051757812 ,-97.74697875976562 ,-142.41433715820312 ,-97.74697875976562 ,-123.85717010498047 ,-142.41433715820312 ,-97.74697875976562 ,-93.7981948852539 ,-123.85717010498047 ,29.884546279907227 ,-24.25218963623047 ,-28.75667381286621 ,126.56841278076172 ,97.57292175292969 ,100.33374786376953 ,1686.08740234375 ,1683.40087890625 ,1684.1480712890625 ,1686.08740234375 ,1684.1480712890625 ,1685.1209716796875 ,1009.9961547851562 ,993.6325073242188 ,978.0360717773438 ,1009.9961547851562 ,1007.6820678710938 ,1003.965576171875 ,1003.965576171875 ,1018.4336547851562 ,1009.9961547851562 ,1003.965576171875 ,1007.6820678710938 ,1018.4336547851562 ,786.45361328125 ,746.6197509765625 ,790.7344360351562 ,784.005615234375 ,793.496337890625 ,795.92529296875 ,1672.3841552734375 ,1666.635498046875 ,1667.9810791015625 ,1672.3841552734375 ,1667.9810791015625 ,1672.770751953125 ,-174.07568359375 ,-173.44215393066406 ,-166.1901092529297 ,1464.3046875 ,1420.555419921875 ,1404.30029296875 ,1464.3046875 ,1462.50830078125 ,1420.555419921875 ,1370.767333984375 ,1476.919677734375 ,1460.7689208984375 ,1650.7645263671875 ,1646.0880126953125 ,1647.8907470703125 ,1650.7645263671875 ,1647.8907470703125 ,1654.4324951171875 ,1557.5587158203125 ,1543.416748046875 ,1546.7625732421875 ,1595.2255859375 ,1601.7579345703125 ,1587.6796875 ,1464.8760986328125 ,1629.09130859375 ,1547.40478515625 ,1665.5714111328125 ,1620.778564453125 ,1692.29931640625 ,1692.29931640625 ,1620.778564453125 ,1669.949462890625 ,1692.29931640625 ,1679.518310546875 ,1665.5714111328125 ,1246.9864501953125 ,1170.9833984375 ,1178.7838134765625 ,1489.4591064453125 ,1519.374267578125 ,1513.2626953125 ,1513.2626953125 ,1519.374267578125 ,1454.7735595703125 ,1565.324951171875 ,1578 ,1568.663818359375 ,1565.324951171875 ,1568.663818359375 ,1567.0540771484375 ,1648.815673828125 ,1644.97119140625 ,1647.1204833984375 ,1542.4107666015625 ,1555.195556640625 ,1544.49267578125 ,1542.4107666015625 ,1554.1483154296875 ,1555.195556640625 ,966.7046508789062 ,774.2960205078125 ,945.1084594726562 ,1677.7841796875 ,1679.267333984375 ,1675.984375 ,1659.814208984375 ,1659.2353515625 ,1656.8397216796875 ,1659.814208984375 ,1660.623779296875 ,1659.2353515625 ,1659.814208984375 ,1664.044677734375 ,1660.623779296875 ,1591.1419677734375 ,1589.919189453125 ,1586.2974853515625 ,1640.2740478515625 ,1642.681396484375 ,1637.527587890625 ,693.88330078125 ,723.9068603515625 ,673.703857421875 ,1592.45556640625 ,1580.116943359375 ,1595.38623046875 ,676.4495849609375 ,454.2554016113281 ,741.1661987304688 ,72.49295806884766 ,51.920265197753906 ,16.696008682250977 ,72.49295806884766 ,16.696008682250977 ,33.578060150146484 ,1548.4180908203125 ,1560.2115478515625 ,1570.3974609375 ,1548.4180908203125 ,1570.3974609375 ,1543.3221435546875 ,1548.4180908203125 ,1548.2794189453125 ,1560.2115478515625 ,717.6525268554688 ,687.5601806640625 ,727.0682983398438 ,1569.2528076171875 ,1573.859619140625 ,1578.2080078125 ,1654.347412109375 ,1650.6107177734375 ,1648.815673828125 ,1654.347412109375 ,1648.815673828125 ,1654.3341064453125 ,-129.30104064941406 ,-150.59349060058594 ,-146.49044799804688 ,-129.30104064941406 ,-137.9761505126953 ,-150.59349060058594 ,1685.358154296875 ,1684.94921875 ,1683.764404296875 ,1683.764404296875 ,1684.94921875 ,1682.7386474609375 ,1649.5989990234375 ,1649.9161376953125 ,1653.306640625 ,1653.5064697265625 ,1656.8397216796875 ,1656.9443359375 ,142.91012573242188 ,162.37506103515625 ,157.5376434326172 ,1571.10107421875 ,1563.51953125 ,1561.6275634765625 ,1571.10107421875 ,1561.6275634765625 ,1562.057861328125 ,-102.13951873779297 ,-109.44664764404297 ,-111.19154357910156 ,832.0707397460938 ,844.8190307617188 ,885.4091796875 ,844.8190307617188 ,875.2785034179688 ,885.4091796875 ,1678.669921875 ,1677.287109375 ,1677.669189453125 ,1678.669921875 ,1675.5518798828125 ,1677.287109375 ,-75.40615844726562 ,-154.95399475097656 ,9.825300216674805 ,-75.40615844726562 ,-106.60688781738281 ,-154.95399475097656 ,1667.6202392578125 ,1666.2528076171875 ,1667.523681640625 ,862.65185546875 ,857.0423583984375 ,862.8421630859375 ,1593.8599853515625 ,1586.2974853515625 ,1574.69580078125 ,1677.0831298828125 ,1675.341064453125 ,1675.5518798828125 ,1548.867919921875 ,1554.2913818359375 ,1555.225830078125 ,1548.867919921875 ,1555.225830078125 ,1552.0093994140625 ,952.6613159179688 ,969.8532104492188 ,943.1953125 ,952.6613159179688 ,934.7592163085938 ,943.5916137695312 ,952.6613159179688 ,943.5916137695312 ,969.8532104492188 ,1688.9842529296875 ,1688.93359375 ,1690.7293701171875 ,1598.1248779296875 ,1596.3753662109375 ,1597.8902587890625 ,1598.1248779296875 ,1597.0556640625 ,1596.3753662109375 ,1597.8902587890625 ,1596.3753662109375 ,1596.440673828125 ,1604.3963623046875 ,1604.5452880859375 ,1604.0233154296875 ,1685.751220703125 ,1689.3079833984375 ,1688.627197265625 ,1685.751220703125 ,1687.360595703125 ,1689.3079833984375 ,1580.116943359375 ,1581.1905517578125 ,1582.463134765625 ,1701.290283203125 ,1648.77978515625 ,1698.6005859375 ,1548.560302734375 ,1546.8094482421875 ,1548.9468994140625 ,-136.6942596435547 ,124.47106170654297 ,-301.7873840332031 ,-136.6942596435547 ,363.066162109375 ,124.47106170654297 ,1682.1451416015625 ,1683.6917724609375 ,1683.5225830078125 ,1683.5225830078125 ,1683.6917724609375 ,1681.4715576171875 ,975.66455078125 ,986.6577758789062 ,826.8889770507812 ,1713.242431640625 ,1715.095703125 ,1763.4459228515625 ,1763.4459228515625 ,1753.8916015625 ,1763.056884765625 ,1763.4459228515625 ,1715.095703125 ,1753.8916015625 ,1683.40087890625 ,1679.259033203125 ,1684.1480712890625 ,-101.7322006225586 ,-93.75887298583984 ,-89.28755950927734 ,-101.7322006225586 ,-89.28755950927734 ,-90.85780334472656 ,1677.451904296875 ,1381.69482421875 ,1592.6239013671875 ,1677.451904296875 ,1610.6427001953125 ,1381.69482421875 ,-92.26326751708984 ,-93.32140350341797 ,-93.72039031982422 ,1686.5401611328125 ,1684.3946533203125 ,1685.5919189453125 ,1678.669921875 ,1677.669189453125 ,1676.799072265625 ,758.327880859375 ,746.5462036132812 ,732.3037109375 ,771.9223022460938 ,778.3762817382812 ,758.327880859375 ,1555.5660400390625 ,1574.4034423828125 ,1576.6949462890625 ,-153.84323120117188 ,-153.94642639160156 ,-154.53662109375 ,-153.84323120117188 ,-154.53662109375 ,-157.58616638183594 ,1500.01318359375 ,1636.1689453125 ,1690.1962890625 ,1500.01318359375 ,1690.1962890625 ,1578.2552490234375 ,1675.1097412109375 ,1675.4527587890625 ,1638.5665283203125 ,1675.1097412109375 ,1672.923583984375 ,1675.4527587890625 ,1675.1097412109375 ,1669.6181640625 ,1672.923583984375 ,1675.1097412109375 ,1670.8839111328125 ,1669.6181640625 ,1675.1097412109375 ,1638.5665283203125 ,1670.8839111328125 ,1638.5665283203125 ,1641.2344970703125 ,1670.8839111328125 ,764.2892456054688 ,767.6109008789062 ,799.6619262695312 ,1664.859130859375 ,1674.104736328125 ,1673.2763671875 ,843.6236572265625 ,850.8707275390625 ,845.576171875 ,843.6236572265625 ,845.576171875 ,829.1942138671875 ,843.6236572265625 ,853.600830078125 ,850.8707275390625 ,1620.97802734375 ,1669.949462890625 ,1620.778564453125 ,1623.536376953125 ,1620.5557861328125 ,1619.4249267578125 ,1559.0006103515625 ,1558.35107421875 ,1565.91796875 ,1559.0006103515625 ,1556.9703369140625 ,1558.35107421875 ,1559.0006103515625 ,1556.5849609375 ,1556.9703369140625 ,1582.832275390625 ,1578.3837890625 ,1597.1463623046875 ,805.0759887695312 ,786.1884765625 ,797.41650390625 ,805.0759887695312 ,809.3734130859375 ,822.8524780273438 ,805.0759887695312 ,797.41650390625 ,809.3734130859375 ,1647.38427734375 ,1649.5989990234375 ,1646.00439453125 ,1428.7633056640625 ,1512.47705078125 ,1350.0614013671875 ,1670.6949462890625 ,1668.416259765625 ,1667.962646484375 ,1707.3741455078125 ,1601.7646484375 ,1684.946044921875 ,1707.3741455078125 ,1867.8238525390625 ,1679.489990234375 ,1707.3741455078125 ,1684.946044921875 ,1867.8238525390625 ,1684.946044921875 ,1870.11962890625 ,1867.8238525390625 ,748.2906494140625 ,772.115966796875 ,753.95947265625 ,748.2906494140625 ,779.9949951171875 ,772.115966796875 ,748.2906494140625 ,688.0762329101562 ,779.9949951171875 ,-119.19314575195312 ,-109.40483856201172 ,-141.19369506835938 ,1677.7841796875 ,1679.02587890625 ,1679.267333984375 ,1042.39111328125 ,1067.620361328125 ,1055.40966796875 ,863.3182373046875 ,848.3939208984375 ,827.7611083984375 ,863.3182373046875 ,865.5841674804688 ,848.3939208984375 ,770.282470703125 ,795.9425048828125 ,799.779541015625 ,770.282470703125 ,799.779541015625 ,795.6617431640625 ,847.5123291015625 ,846.8115844726562 ,865.5841674804688 ,1588.1551513671875 ,1581.5753173828125 ,1585.217041015625 ,1601.361328125 ,1602.7296142578125 ,1600.29052734375 ,-104.18303680419922 ,-103.55646514892578 ,-102.38587188720703 ,1570.010009765625 ,1556.96240234375 ,1563.6204833984375 ,1570.010009765625 ,1565.5657958984375 ,1556.96240234375 ,-174.07568359375 ,-170.8797149658203 ,-173.44215393066406 ,1606.0787353515625 ,1615.1953125 ,1596.00439453125 ,1606.0787353515625 ,1627.878662109375 ,1615.1953125 ,1606.5816650390625 ,1608.6427001953125 ,1598.5628662109375 ,1648.748779296875 ,1601.6107177734375 ,1591.2655029296875 ,1647.878662109375 ,1652.7374267578125 ,1650.792236328125 ,1647.878662109375 ,1646.00439453125 ,1652.7374267578125 ,1647.878662109375 ,1640.44482421875 ,1646.00439453125 ,1683.2618408203125 ,1678.84521484375 ,1680.0238037109375 ,1670.8912353515625 ,1677.313720703125 ,1673.774169921875 ,1670.8912353515625 ,1675.3575439453125 ,1677.313720703125 ,1657.4427490234375 ,1650.5787353515625 ,1659.263916015625 ,693.4887084960938 ,703.1891479492188 ,687.8463134765625 ,1547.3134765625 ,1544.0389404296875 ,1544.49267578125 ,1593.8614501953125 ,1590.654052734375 ,1586.283935546875 ,1593.8614501953125 ,1586.283935546875 ,1556.5546875 ,1693.2091064453125 ,1692.35009765625 ,1693.468017578125 ,-112.009033203125 ,-150.75221252441406 ,-133.311767578125 ,771.5061645507812 ,795.2511596679688 ,778.3938598632812 ,771.5061645507812 ,787.6688232421875 ,795.2511596679688 ,1546.02392578125 ,1558.3375244140625 ,1569.6328125 ,1546.02392578125 ,1543.718505859375 ,1553.1898193359375 ,1546.02392578125 ,1553.1898193359375 ,1558.3375244140625 ,805.4881591796875 ,800.04736328125 ,796.2474975585938 ,1670.5738525390625 ,1673.2105712890625 ,1678.5303955078125 ,1648.4556884765625 ,1645.921630859375 ,1645.1719970703125 ,804.3577270507812 ,687.8463134765625 ,790.1590576171875 ,1422.773193359375 ,1468.338623046875 ,1435.064453125 ,1636.007568359375 ,1644.015625 ,1602.2877197265625 ,1621.914794921875 ,1627.7359619140625 ,1632.9669189453125 ,1621.914794921875 ,1597.1463623046875 ,1592.7901611328125 ,1621.914794921875 ,1592.7901611328125 ,1627.7359619140625 ,1687.1873779296875 ,1690.2166748046875 ,1687.320068359375 ,743.0693359375 ,746.5005493164062 ,761.1368408203125 ,743.0693359375 ,761.1368408203125 ,747.8978881835938 ,743.0693359375 ,729.0462646484375 ,746.5005493164062 ,743.0693359375 ,747.8978881835938 ,729.0462646484375 ,761.1368408203125 ,759.187255859375 ,747.8978881835938 ,761.1368408203125 ,778.0946044921875 ,759.187255859375 ,1545.984375 ,1540.01904296875 ,1469.92626953125 ,1662.9295654296875 ,1653.598388671875 ,1651.9390869140625 ,1662.9295654296875 ,1651.9390869140625 ,1647.4063720703125 ,1556.6285400390625 ,1548.867919921875 ,1556.3740234375 ,1556.6285400390625 ,1556.3740234375 ,1558.2471923828125 ,1556.6285400390625 ,1558.2471923828125 ,1560.1588134765625 ,1337.89208984375 ,1571.296142578125 ,1426.50927734375 ,1545.1953125 ,1543.2904052734375 ,1541.0382080078125 ,1545.1953125 ,1541.0382080078125 ,1538.50439453125 ,1541.0382080078125 ,1536.6990966796875 ,1538.50439453125 ,1606.5872802734375 ,1606.330322265625 ,1603.8221435546875 ,1606.5872802734375 ,1608.2562255859375 ,1606.330322265625 ,1691.950927734375 ,1691.6446533203125 ,1691.998779296875 ,-143.4319305419922 ,-142.95718383789062 ,-137.65219116210938 ,1638.38623046875 ,1639.03369140625 ,1638.11376953125 ,1424.42041015625 ,1405.2806396484375 ,1462.50830078125 ,92.03718566894531 ,102.53659057617188 ,39.96271514892578 ,92.03718566894531 ,12.193948745727539 ,51.283111572265625 ,92.03718566894531 ,39.96271514892578 ,12.193948745727539 ,1426.50927734375 ,1571.296142578125 ,1801.1998291015625 ,12.87821102142334 ,-39.66056442260742 ,39.96271514892578 ,804.3577270507812 ,812.12744140625 ,795.3270874023438 ,1662.4249267578125 ,1655.774658203125 ,1662.6346435546875 ,1544.49267578125 ,1544.0389404296875 ,1541.419677734375 ,865.3997802734375 ,804.3577270507812 ,790.1590576171875 ,1565.7703857421875 ,1571.97705078125 ,1565.324951171875 ,1565.7703857421875 ,1580.0263671875 ,1571.97705078125 ,1682.5885009765625 ,1682.081298828125 ,1683.5235595703125 ,1682.5885009765625 ,1678.3021240234375 ,1675.08056640625 ,1387.4476318359375 ,1556.5546875 ,1574.4801025390625 ,1586.105712890625 ,1579.202392578125 ,1583.3828125 ,1586.105712890625 ,1589.6549072265625 ,1579.202392578125 ,842.20458984375 ,801.0247192382812 ,757.3011474609375 ,842.20458984375 ,757.3011474609375 ,785.1974487304688 ,1556.0218505859375 ,1565.161865234375 ,1568.7576904296875 ,1565.161865234375 ,1556.0218505859375 ,1568.649169921875 ,1565.161865234375 ,1578.0010986328125 ,1568.7576904296875 ,835.4942016601562 ,811.1006469726562 ,844.23388671875 ,1576.927001953125 ,1584.786865234375 ,1575.79345703125 ,1940.6337890625 ,1872.8701171875 ,1686.75048828125 ,639.7841796875 ,662.4285278320312 ,454.2554016113281 ,-376.84521484375 ,-297.3943176269531 ,-283.53369140625 ,-376.84521484375 ,-283.53369140625 ,-297.79754638671875 ,-376.84521484375 ,-395.974853515625 ,-297.3943176269531 ,1725.84033203125 ,1868.274169921875 ,1939.4962158203125 ,1868.274169921875 ,1780.859619140625 ,1885.945556640625 ,1868.274169921875 ,1885.945556640625 ,1939.4962158203125 ,-7.0689778327941895 ,-109.26838684082031 ,-33.623085021972656 ,126.69802856445312 ,79.7586669921875 ,130.8192138671875 ,126.69802856445312 ,130.8192138671875 ,154.77740478515625 ,1428.7633056640625 ,1043.316162109375 ,1616.56201171875 ,1569.4425048828125 ,1592.876953125 ,1593.052978515625 ,1819.1021728515625 ,1775.8941650390625 ,1798.1724853515625 ,1819.1021728515625 ,1787.134765625 ,1775.8941650390625 ,864.3307495117188 ,927.310791015625 ,949.4277954101562 ,1614.8197021484375 ,1629.09130859375 ,1464.8760986328125 ,53.96044158935547 ,7.397647857666016 ,12.554376602172852 ,1692.35009765625 ,1693.4378662109375 ,1691.8638916015625 ,1692.35009765625 ,1691.8638916015625 ,1691.272705078125 ,785.1974487304688 ,757.3011474609375 ,798.5071411132812 ,1566.9979248046875 ,1564.2630615234375 ,1538.6708984375 ,708.30078125 ,729.2923583984375 ,704.7988891601562 ,708.30078125 ,719.3765869140625 ,729.2923583984375 ,1599.7681884765625 ,1600.7247314453125 ,1602.168701171875 ,1599.7681884765625 ,1602.168701171875 ,1600.859375 ,1599.7681884765625 ,1600.859375 ,1598.824462890625 ,811.1006469726562 ,801.1747436523438 ,833.7054443359375 ,1819.286376953125 ,1680.8619384765625 ,1734.58935546875 ,1819.286376953125 ,1734.58935546875 ,1744.6837158203125 ,1577.1654052734375 ,1583.3828125 ,1579.202392578125 ,1713.242431640625 ,1629.09130859375 ,1715.095703125 ,1713.242431640625 ,1547.40478515625 ,1629.09130859375 ,1715.095703125 ,1629.09130859375 ,1753.8916015625 ,1602.7296142578125 ,1604.3963623046875 ,1604.458251953125 ,748.2906494140625 ,690.889404296875 ,696.3478393554688 ,748.2906494140625 ,696.3478393554688 ,688.0762329101562 ,1644.7110595703125 ,1642.044677734375 ,1651.905029296875 ,-160.0223388671875 ,-297.79754638671875 ,-283.53369140625 ,885.4091796875 ,945.8577880859375 ,883.9874877929688 ,885.4091796875 ,930.5149536132812 ,945.8577880859375 ,883.9874877929688 ,945.8577880859375 ,890.6671752929688 ,1358.700927734375 ,1403.621826171875 ,1351.378662109375 ,1358.700927734375 ,1431.1864013671875 ,1403.621826171875 ,1784.3990478515625 ,1698.6005859375 ,1686.75048828125 ,1784.3990478515625 ,1686.75048828125 ,1864.595458984375 ,1784.3990478515625 ,1864.595458984375 ,1768.0631103515625 ,1665.4837646484375 ,1656.165283203125 ,1645.7232666015625 ,1567.0540771484375 ,1568.663818359375 ,1566.70947265625 ,1763.056884765625 ,1753.8916015625 ,1770.8345947265625 ,1594.5111083984375 ,1577.8319091796875 ,1592.0440673828125 ,1594.5111083984375 ,1592.0440673828125 ,1601.47607421875 ,1594.5111083984375 ,1576.539306640625 ,1577.8319091796875 ,1688.496826171875 ,1687.4100341796875 ,1688.0460205078125 ,1515.2393798828125 ,1410.970458984375 ,1588.393798828125 ,1515.2393798828125 ,1384.2012939453125 ,1410.970458984375 ,1601.3475341796875 ,1603.0877685546875 ,1599.4454345703125 ,1623.536376953125 ,1643.3670654296875 ,1620.5557861328125 ,782.0736083984375 ,781.643310546875 ,775.9713745117188 ,782.0736083984375 ,784.624755859375 ,779.3375244140625 ,741.1661987304688 ,454.2554016113281 ,662.4285278320312 ,1665.359130859375 ,1685.0931396484375 ,1657.325927734375 ,744.9285278320312 ,716.3633422851562 ,781.4766845703125 ,1556.3740234375 ,1559.673828125 ,1558.2471923828125 ,1625.290283203125 ,1637.1361083984375 ,1636.0384521484375 ,1632.71142578125 ,1640.1123046875 ,1633.0225830078125 ,1632.71142578125 ,1639.517333984375 ,1640.1123046875 ,1632.71142578125 ,1625.2537841796875 ,1639.517333984375 ,1537.7679443359375 ,1537.8978271484375 ,1532.41796875 ,1689.956787109375 ,1690.4541015625 ,1688.5379638671875 ,804.2484741210938 ,806.130859375 ,819.1377563476562 ,1687.455322265625 ,1686.6595458984375 ,1685.16943359375 ,-195.4857635498047 ,59.6855583190918 ,-136.6942596435547 ,1675.3975830078125 ,1678.5303955078125 ,1681.121337890625 ,1675.3975830078125 ,1675.3382568359375 ,1673.9615478515625 ,1675.3975830078125 ,1675.666015625 ,1675.3382568359375 ,1675.3975830078125 ,1681.121337890625 ,1675.666015625 ,1675.3975830078125 ,1673.9615478515625 ,1670.5738525390625 ,894.9827880859375 ,821.3425903320312 ,795.1342163085938 ,821.3425903320312 ,810.5379028320312 ,795.1342163085938 ,1692.3402099609375 ,1694.019775390625 ,1691.265380859375 ,1692.3402099609375 ,1692.0556640625 ,1693.8438720703125 ,1640.2740478515625 ,1637.527587890625 ,1636.365966796875 ,1025.4761962890625 ,1018.4336547851562 ,1007.6820678710938 ,-149.68702697753906 ,-145.3284912109375 ,-147.3275604248047 ,-149.68702697753906 ,-147.34451293945312 ,-145.84243774414062 ,-149.68702697753906 ,-145.84243774414062 ,-145.3284912109375 ,-145.3284912109375 ,-145.95632934570312 ,-147.3275604248047 ,-147.3275604248047 ,-145.95632934570312 ,-146.486328125 ,-97.40780639648438 ,-93.72039031982422 ,-97.81755828857422 ,-146.486328125 ,-146.34799194335938 ,-147.45188903808594 ,833.7054443359375 ,854.8204956054688 ,811.1006469726562 ,723.9068603515625 ,734.4566040039062 ,790.7344360351562 ,1587.8623046875 ,1598.22265625 ,1601.3533935546875 ,1582.8492431640625 ,1587.8623046875 ,1577.8433837890625 ,29.884546279907227 ,-28.75667381286621 ,-37.357818603515625 ,1582.8492431640625 ,1578.0010986328125 ,1581.63818359375 ,1582.8492431640625 ,1581.63818359375 ,1585.578369140625 ,1582.8492431640625 ,1577.8433837890625 ,1578.0010986328125 ,1600.896484375 ,1605.64599609375 ,1605.1339111328125 ,1600.896484375 ,1600.8250732421875 ,1605.64599609375 ,1605.64599609375 ,1600.8250732421875 ,1605.918212890625 ,1647.2269287109375 ,1585.6143798828125 ,1598.2261962890625 ,1647.2269287109375 ,1613.8966064453125 ,1585.6143798828125 ,1647.2269287109375 ,1734.58935546875 ,1680.8619384765625 ,1647.2269287109375 ,1598.2261962890625 ,1734.58935546875 ,1597.4324951171875 ,1607.154296875 ,1606.5816650390625 ,1775.8941650390625 ,1787.134765625 ,1780.6429443359375 ,1384.667236328125 ,1512.47705078125 ,1487.403564453125 ,81.85975646972656 ,-7.0689778327941895 ,-33.623085021972656 ,1453.39306640625 ,1561.9427490234375 ,1569.7120361328125 ,1453.39306640625 ,1550.9483642578125 ,1561.9427490234375 ,1453.39306640625 ,1477.3577880859375 ,1550.9483642578125 ,1550.9483642578125 ,1477.3577880859375 ,1552.2708740234375 ,1211.4088134765625 ,1242.9195556640625 ,1120.439208984375 ,1596.3753662109375 ,1597.0556640625 ,1594.6051025390625 ,1596.3753662109375 ,1594.6051025390625 ,1599.012451171875 ,1596.3753662109375 ,1599.012451171875 ,1596.440673828125 ,1597.0556640625 ,1594.73974609375 ,1594.6051025390625 ,793.496337890625 ,783.1329956054688 ,792.85107421875 ,-147.34451293945312 ,-148.42178344726562 ,-143.90379333496094 ,-148.42178344726562 ,-150.59349060058594 ,-143.90379333496094 ,-143.90379333496094 ,-150.59349060058594 ,-140.41754150390625 ,1369.0794677734375 ,1376.4482421875 ,1337.89208984375 ,1369.0794677734375 ,1337.89208984375 ,1365.138916015625 ,363.066162109375 ,668.2542114257812 ,772.7360229492188 ,-86.76862335205078 ,-90.16954040527344 ,-87.38944244384766 ,-90.16954040527344 ,-89.05227661132812 ,-87.38944244384766 ,806.130859375 ,816.6506958007812 ,819.1377563476562 ,1025.4761962890625 ,1007.6820678710938 ,1065.7030029296875 ,1659.2353515625 ,1656.9443359375 ,1656.8397216796875 ,1435.064453125 ,1406.17626953125 ,1417.4075927734375 ,1435.064453125 ,1468.338623046875 ,1484.3262939453125 ,1435.064453125 ,1484.3262939453125 ,1406.17626953125 ,1435.064453125 ,1417.4075927734375 ,1422.773193359375 ,-153.84323120117188 ,-157.58616638183594 ,-153.2115020751953 ,-153.84323120117188 ,-153.2115020751953 ,-152.03746032714844 ,1574.4801025390625 ,1556.5546875 ,1589.6539306640625 ,1574.4801025390625 ,1589.6539306640625 ,1550.9483642578125 ,1550.9483642578125 ,1552.2708740234375 ,1574.4801025390625 ,1550.9483642578125 ,1589.6539306640625 ,1586.283935546875 ,1569.2528076171875 ,1556.9638671875 ,1573.859619140625 ,793.8865356445312 ,790.1903686523438 ,782.3931274414062 ,978.0540161132812 ,927.310791015625 ,966.2996215820312 ,978.0540161132812 ,966.2996215820312 ,978.31494140625 ,907.8963012695312 ,966.2996215820312 ,925.2911987304688 ,-102.12205505371094 ,-107.67842864990234 ,-118.78472900390625 ,776.2487182617188 ,790.4133911132812 ,786.6719970703125 ,776.2487182617188 ,789.9561767578125 ,790.4133911132812 ,776.2487182617188 ,786.6719970703125 ,775.156005859375 ,-146.49044799804688 ,-142.89480590820312 ,-130.52609252929688 ,1637.6385498046875 ,1638.23876953125 ,1633.53369140625 ,1911.8431396484375 ,1940.2425537109375 ,1956.941650390625 ,1911.8431396484375 ,1880.57177734375 ,1825.2783203125 ,1911.8431396484375 ,1825.2783203125 ,1940.2425537109375 ,1911.8431396484375 ,1956.941650390625 ,1880.57177734375 ,1940.2425537109375 ,1825.2783203125 ,1831.2437744140625 ,1940.2425537109375 ,1932.8714599609375 ,1956.941650390625 ,1204.0008544921875 ,1136.8084716796875 ,1079.8157958984375 ,781.4766845703125 ,882.2884521484375 ,887.4142456054688 ,1598.30029296875 ,1600.82421875 ,1601.320556640625 ,1567.23486328125 ,1560.2164306640625 ,1557.9974365234375 ,-172.25660705566406 ,-172.63314819335938 ,-172.8136444091797 ,1574.69580078125 ,1564.2630615234375 ,1593.8599853515625 ,716.3633422851562 ,713.6329956054688 ,723.6242065429688 ,1625.169189453125 ,1627.998046875 ,1623.6824951171875 ,1003.8096313476562 ,981.9210815429688 ,969.8532104492188 ,1003.8096313476562 ,962.6599731445312 ,1027.87646484375 ,1003.8096313476562 ,969.8532104492188 ,962.6599731445312 ,939.5186767578125 ,1202.355224609375 ,1616.56201171875 ,939.5186767578125 ,1616.56201171875 ,1043.316162109375 ,1051.2655029296875 ,1102.5924072265625 ,1088.1229248046875 ,1051.2655029296875 ,1088.1229248046875 ,1022.6570434570312 ,1102.5924072265625 ,1140.5811767578125 ,1088.1229248046875 ,1588.393798828125 ,1410.970458984375 ,1641.736083984375 ,1593.2496337890625 ,1625.0286865234375 ,1585.3182373046875 ,1658.670166015625 ,1629.5826416015625 ,1637.8812255859375 ,1083.865478515625 ,1018.4336547851562 ,1093.7362060546875 ,1645.7117919921875 ,1643.3487548828125 ,1618.32177734375 ,1645.7117919921875 ,1664.5697021484375 ,1643.3487548828125 ,1643.3487548828125 ,1664.5697021484375 ,1669.6181640625 ,1625.0286865234375 ,1740.9375 ,1822.6085205078125 ,125.16410064697266 ,63.12164306640625 ,102.53659057617188 ,100.33374786376953 ,97.57292175292969 ,200.7797088623047 ,100.33374786376953 ,200.7797088623047 ,212.82652282714844 ,-150.75221252441406 ,-158.22862243652344 ,-164.67984008789062 ,-150.75221252441406 ,-134.75697326660156 ,-158.22862243652344 ,1622.50927734375 ,1633.53173828125 ,1629.330810546875 ,1578.15625 ,1603.6051025390625 ,1593.12060546875 ,1603.6051025390625 ,1604.80224609375 ,1593.12060546875 ,-3.302182912826538 ,-25.64232063293457 ,-2.8962490558624268 ,-3.302182912826538 ,-2.8962490558624268 ,11.090381622314453 ,-170.53453063964844 ,-162.18087768554688 ,-170.48284912109375 ,1761.8521728515625 ,1768.0631103515625 ,1864.595458984375 ,1761.8521728515625 ,1864.595458984375 ,1780.859619140625 ,561.8804931640625 ,570.5579223632812 ,625.8710327148438 ,1673.916259765625 ,1669.6793212890625 ,1669.50390625 ,1678.3021240234375 ,1682.5885009765625 ,1679.8707275390625 ,1679.8707275390625 ,1678.726318359375 ,1678.15283203125 ,19.352371215820312 ,64.75064849853516 ,43.80088806152344 ,43.80088806152344 ,45.33297348022461 ,19.352371215820312 ,43.80088806152344 ,58.55487060546875 ,45.33297348022461 ,19.352371215820312 ,45.33297348022461 ,6.033566951751709 ,783.3544921875 ,785.389404296875 ,797.4121704101562 ,1347.615478515625 ,1365.6441650390625 ,1418.7108154296875 ,719.3765869140625 ,706.8468627929688 ,746.6197509765625 ,719.3765869140625 ,746.6197509765625 ,729.2923583984375 ,1416.5341796875 ,1494.3138427734375 ,1487.827392578125 ,754.8847045898438 ,787.6427001953125 ,717.0455322265625 ,1025.4761962890625 ,1065.7030029296875 ,1079.087646484375 ,1025.4761962890625 ,1079.087646484375 ,1104.0047607421875 ,1621.833984375 ,1633.0953369140625 ,1631.4022216796875 ,1422.2646484375 ,1454.1854248046875 ,1451.8507080078125 ,1451.8507080078125 ,1454.1854248046875 ,1580.21044921875 ,49.47584915161133 ,40.656192779541016 ,40.29792022705078 ,49.47584915161133 ,40.29792022705078 ,74.84351348876953 ,1624.51708984375 ,1627.009521484375 ,1645.7117919921875 ,1624.51708984375 ,1597.1463623046875 ,1627.009521484375 ,1624.51708984375 ,1645.7117919921875 ,1618.32177734375 ,751.0639038085938 ,762.7431640625 ,759.6661376953125 ,-87.42422485351562 ,-86.76862335205078 ,-90.85780334472656 ,-87.42422485351562 ,-89.9217529296875 ,-89.28755950927734 ,-87.42422485351562 ,-90.85780334472656 ,-89.9217529296875 ,1651.905029296875 ,1642.044677734375 ,1657.2647705078125 ,993.6325073242188 ,973.2190551757812 ,974.3580322265625 ,993.6325073242188 ,974.3580322265625 ,978.0360717773438 ,993.6325073242188 ,1009.9961547851562 ,973.2190551757812 ,-93.32140350341797 ,-94.87836456298828 ,-93.72039031982422 ,1582.167724609375 ,1569.8341064453125 ,1576.539306640625 ,1676.6839599609375 ,1680.5875244140625 ,1669.4385986328125 ,1676.6839599609375 ,1695.0233154296875 ,1680.5875244140625 ,-86.76862335205078 ,-87.38944244384766 ,-90.85780334472656 ,1635.9273681640625 ,1646.7174072265625 ,1638.4283447265625 ,1237.4595947265625 ,1285.7158203125 ,965.7979125976562 ,728.3058471679688 ,721.634765625 ,723.293212890625 ,723.293212890625 ,726.8759765625 ,781.4766845703125 ,1600.4422607421875 ,1599.591064453125 ,1598.8990478515625 ,1598.8990478515625 ,1599.591064453125 ,1599.11962890625 ,1598.8990478515625 ,1601.2574462890625 ,1600.4422607421875 ,943.1953125 ,969.8532104492188 ,981.9210815429688 ,1651.5751953125 ,1648.0936279296875 ,1639.356201171875 ,11.090381622314453 ,40.29792022705078 ,40.656192779541016 ,-70.94931030273438 ,-97.18619537353516 ,-111.2472915649414 ,-70.94931030273438 ,-111.2472915649414 ,-104.98910522460938 ,-70.94931030273438 ,-64.44239044189453 ,-97.18619537353516 ,-70.94931030273438 ,-104.98910522460938 ,-90.96149444580078 ,1603.6051025390625 ,1635.490478515625 ,1604.80224609375 ,1657.325927734375 ,1685.0931396484375 ,1686.7740478515625 ,1657.325927734375 ,1686.7740478515625 ,1643.3873291015625 ,1685.0931396484375 ,1699.156982421875 ,1686.7740478515625 ,1685.0931396484375 ,1681.109130859375 ,1699.156982421875 ,868.7754516601562 ,873.3203735351562 ,878.2056274414062 ,868.7754516601562 ,878.2056274414062 ,872.126220703125 ,868.7754516601562 ,848.0089111328125 ,873.3203735351562 ,1142.978759765625 ,1385.2088623046875 ,1101.100830078125 ,1142.978759765625 ,1101.100830078125 ,1018.4519653320312 ,1553.195068359375 ,1462.50830078125 ,1548.0048828125 ,481.72210693359375 ,466.0267333984375 ,513.69580078125 ,719.7808227539062 ,738.3677368164062 ,746.5005493164062 ,719.7808227539062 ,746.5005493164062 ,723.6242065429688 ,738.3677368164062 ,719.7808227539062 ,757.3011474609375 ,738.3677368164062 ,757.3011474609375 ,747.5623168945312 ,738.3677368164062 ,747.5623168945312 ,746.5005493164062 ,97.57292175292969 ,225.9130401611328 ,200.7797088623047 ,1477.02099609375 ,1349.7996826171875 ,1258.1793212890625 ,-169.49635314941406 ,-375.16754150390625 ,-209.7818145751953 ,-117.45018768310547 ,-120.36861419677734 ,-101.7322006225586 ,-101.7322006225586 ,-120.36861419677734 ,-107.33910369873047 ,1601.023681640625 ,1600.6370849609375 ,1600.8970947265625 ,726.8759765625 ,804.3577270507812 ,787.5234985351562 ,726.8759765625 ,739.697509765625 ,804.3577270507812 ,804.3577270507812 ,795.3270874023438 ,787.5234985351562 ,787.5234985351562 ,795.3270874023438 ,812.12744140625 ,787.5234985351562 ,812.12744140625 ,726.8759765625 ,787.5003662109375 ,775.9713745117188 ,783.5720825195312 ,1639.8092041015625 ,1592.6239013671875 ,1537.597900390625 ,1639.8092041015625 ,1798.2933349609375 ,1592.6239013671875 ,1557.5587158203125 ,1548.867919921875 ,1543.416748046875 ,1557.5587158203125 ,1556.3740234375 ,1548.867919921875 ,577.8530883789062 ,659.8430786132812 ,683.6290893554688 ,1691.0614013671875 ,1689.0537109375 ,1688.48388671875 ,1691.0614013671875 ,1690.3802490234375 ,1689.0537109375 ,690.8013305664062 ,608.802734375 ,620.417236328125 ,998.6987915039062 ,706.0634765625 ,1093.8919677734375 ,1651.3546142578125 ,2294.779296875 ,1980.4984130859375 ,-87.38944244384766 ,-89.05227661132812 ,-90.85780334472656 ,-121.46614837646484 ,-114.72260284423828 ,-145.39947509765625 ,-121.46614837646484 ,-145.39947509765625 ,-162.1982421875 ,1662.99072265625 ,1664.3409423828125 ,1667.962646484375 ,1667.962646484375 ,1664.3409423828125 ,1672.285888671875 ,1617.012939453125 ,1606.625 ,1591.043701171875 ,1617.012939453125 ,1591.043701171875 ,1601.041015625 ,1428.7633056640625 ,1606.3082275390625 ,1562.5577392578125 ,1428.7633056640625 ,1616.56201171875 ,1606.3082275390625 ,-127.38860321044922 ,-135.68988037109375 ,-135.0819854736328 ,-127.38860321044922 ,-123.2637939453125 ,-135.68988037109375 ,-127.38860321044922 ,-97.18619537353516 ,-97.0417709350586 ,-127.38860321044922 ,-97.0417709350586 ,-123.2637939453125 ,-127.38860321044922 ,-124.65084075927734 ,-97.18619537353516 ,774.962646484375 ,748.1673583984375 ,767.950927734375 ,774.962646484375 ,767.950927734375 ,930.623046875 ,930.623046875 ,767.950927734375 ,793.8865356445312 ,16.696008682250977 ,9.825300216674805 ,-154.95399475097656 ,16.696008682250977 ,51.920265197753906 ,9.825300216674805 ,16.696008682250977 ,-118.19950103759766 ,33.578060150146484 ,16.696008682250977 ,-154.95399475097656 ,-118.19950103759766 ,-154.95399475097656 ,-106.60688781738281 ,-169.80703735351562 ,-19.886470794677734 ,33.578060150146484 ,-118.19950103759766 ,-19.886470794677734 ,32.23271942138672 ,33.578060150146484 ,33.578060150146484 ,32.23271942138672 ,72.49295806884766 ,896.8179321289062 ,877.5236206054688 ,896.6598510742188 ,896.8179321289062 ,896.6598510742188 ,909.6098022460938 ,1636.1689453125 ,1523.725830078125 ,1692.1318359375 ,1636.1689453125 ,1500.01318359375 ,1523.725830078125 ,1833.514404296875 ,1622.8790283203125 ,1814.4393310546875 ,1638.36181640625 ,1634.45361328125 ,1623.8583984375 ,882.2884521484375 ,781.4766845703125 ,797.5750122070312 ,-168.038330078125 ,105.0716323852539 ,-402.4700927734375 ,-83.364990234375 ,-101.0987777709961 ,-96.97508239746094 ,-83.364990234375 ,-96.97508239746094 ,-93.32140350341797 ,620.417236328125 ,570.5579223632812 ,561.8804931640625 ,1170.9833984375 ,1140.5811767578125 ,1102.5924072265625 ,1170.9833984375 ,1102.5924072265625 ,1100.494384765625 ,-107.33910369873047 ,-120.36861419677734 ,-122.85227966308594 ,767.6109008789062 ,797.3441772460938 ,799.6619262695312 ,767.6109008789062 ,785.7398681640625 ,797.3441772460938 ,1581.471435546875 ,1609.0736083984375 ,1570.3974609375 ,795.2511596679688 ,829.766357421875 ,778.3938598632812 ,-163.9052276611328 ,-168.22259521484375 ,-166.50289916992188 ,747.8978881835938 ,729.9891357421875 ,729.0462646484375 ,729.9891357421875 ,747.8978881835938 ,729.4252319335938 ,1638.11376953125 ,1636.6739501953125 ,1638.38623046875 ,-172.2712860107422 ,-172.63314819335938 ,-170.8787078857422 ,-172.2712860107422 ,-172.8136444091797 ,-172.63314819335938 ,640.021728515625 ,687.5601806640625 ,626.051025390625 ,640.021728515625 ,626.051025390625 ,570.5579223632812 ,-138.11817932128906 ,-145.84243774414062 ,-137.9761505126953 ,793.9613037109375 ,790.4133911132812 ,794.5354614257812 ,1537.7679443359375 ,1553.118896484375 ,1538.919189453125 ,36.951839447021484 ,-17.97229766845703 ,-22.08594512939453 ,1629.037841796875 ,1620.0291748046875 ,1618.6702880859375 ,1546.02392578125 ,1569.6328125 ,1559.9676513671875 ,-79.97222137451172 ,-21.956390380859375 ,-7.566917896270752 ,-79.97222137451172 ,-7.566917896270752 ,-5.270526885986328 ,-79.97222137451172 ,-5.270526885986328 ,-46.94858169555664 ,-79.97222137451172 ,-82.16941833496094 ,-21.956390380859375 ,1676.799072265625 ,1680.30908203125 ,1678.669921875 ,1676.799072265625 ,1678.31201171875 ,1680.30908203125 ,772.115966796875 ,779.9949951171875 ,777.9764404296875 ,801.7922973632812 ,804.2978515625 ,797.41650390625 ,801.7922973632812 ,797.41650390625 ,782.7861328125 ,0.48955801129341125 ,-8.213500022888184 ,14.08456802368164 ,1646.99853515625 ,1661.302978515625 ,1651.0067138671875 ,1646.99853515625 ,1651.0067138671875 ,1641.5775146484375 ,1282.9049072265625 ,1272.394287109375 ,1239.4842529296875 ,-228.321533203125 ,-206.4029083251953 ,-208.4066162109375 ,1392.46337890625 ,1526.1451416015625 ,1337.89208984375 ,1392.46337890625 ,1337.89208984375 ,1376.4482421875 ,-165.97145080566406 ,-166.4710693359375 ,-166.96328735351562 ,1690.796875 ,1691.265380859375 ,1689.3079833984375 ,1580.116943359375 ,1568.649169921875 ,1566.70947265625 ,-5.270526885986328 ,4.923157215118408 ,-13.013050079345703 ,-5.270526885986328 ,10.203259468078613 ,4.923157215118408 ,4.923157215118408 ,-6.674344062805176 ,-13.013050079345703 ,1677.3021240234375 ,1671.58349609375 ,1670.2049560546875 ,1677.3021240234375 ,1677.809814453125 ,1671.58349609375 ,1608.2562255859375 ,1608.087646484375 ,1606.330322265625 ,782.7861328125 ,797.41650390625 ,786.1884765625 ,801.7922973632812 ,782.7861328125 ,783.3544921875 ,1688.5379638671875 ,1690.4541015625 ,1688.48388671875 ,1564.7724609375 ,1558.181884765625 ,1561.3687744140625 ,1691.32421875 ,1691.6614990234375 ,1693.0771484375 ,1691.32421875 ,1693.0771484375 ,1692.2630615234375 ,1691.32421875 ,1690.796875 ,1689.8787841796875 ,-87.2468490600586 ,-39.66056442260742 ,-133.5084228515625 ,1147.1209716796875 ,1330.0029296875 ,1093.8919677734375 ,1147.1209716796875 ,1007.3907470703125 ,984.8864135742188 ,1147.1209716796875 ,1093.8919677734375 ,1007.3907470703125 ,972.8710327148438 ,891.51708984375 ,1065.2171630859375 ,1609.0880126953125 ,1591.111083984375 ,1602.2877197265625 ,1565.482666015625 ,1566.546630859375 ,1567.3592529296875 ,1679.489990234375 ,1867.8238525390625 ,1782.79150390625 ,-224.1885223388672 ,-288.77471923828125 ,-265.82415771484375 ,-288.77471923828125 ,-224.1885223388672 ,-17.97229766845703 ,1544.3592529296875 ,1554.1483154296875 ,1542.4107666015625 ,1081.4989013671875 ,912.0824584960938 ,1065.2171630859375 ,1654.254150390625 ,1662.99072265625 ,1655.255615234375 ,84.34304809570312 ,64.75064849853516 ,19.352371215820312 ,1692.0556640625 ,1692.2630615234375 ,1693.0771484375 ,1692.0556640625 ,1693.0771484375 ,1693.8438720703125 ,1693.8438720703125 ,1693.0771484375 ,1693.6707763671875 ,1698.6005859375 ,1671.5623779296875 ,1648.748779296875 ,1698.6005859375 ,1648.748779296875 ,1686.75048828125 ,1385.2088623046875 ,1405.2806396484375 ,1396.57275390625 ,-137.65219116210938 ,-138.2955322265625 ,-125.6340103149414 ,-137.65219116210938 ,-142.95718383789062 ,-138.2955322265625 ,-143.4319305419922 ,-148.29736328125 ,-171.53567504882812 ,1641.736083984375 ,1535.486572265625 ,1666.2265625 ,1666.2265625 ,1535.486572265625 ,1527.3734130859375 ,1018.4336547851562 ,1025.4761962890625 ,1093.7362060546875 ,1686.4300537109375 ,1686.9090576171875 ,1684.5474853515625 ,688.91357421875 ,618.6279907226562 ,689.94873046875 ,688.91357421875 ,753.7611083984375 ,738.90380859375 ,19.352371215820312 ,-5.711810111999512 ,-0.7145509719848633 ,1640.5447998046875 ,1634.45361328125 ,1646.806640625 ,1646.806640625 ,1634.45361328125 ,1638.36181640625 ,1691.6446533203125 ,1689.956787109375 ,1690.9208984375 ,-87.2468490600586 ,12.193948745727539 ,39.96271514892578 ,-87.2468490600586 ,39.96271514892578 ,-39.66056442260742 ,1492.576904296875 ,1468.338623046875 ,1498.0311279296875 ,1492.576904296875 ,1498.0311279296875 ,1571.0238037109375 ,1686.7740478515625 ,1701.5162353515625 ,1685.72265625 ,1686.7740478515625 ,1699.156982421875 ,1701.5162353515625 ,1699.156982421875 ,1695.4520263671875 ,1704.06396484375 ,1699.156982421875 ,1704.06396484375 ,1701.5162353515625 ,1650.4656982421875 ,1647.802978515625 ,1650.5126953125 ,1650.5126953125 ,1647.802978515625 ,1646.2232666015625 ,1650.5126953125 ,1651.294921875 ,1650.4656982421875 ,701.0760498046875 ,657.6510620117188 ,721.634765625 ,701.0760498046875 ,687.7828979492188 ,657.6510620117188 ,657.6510620117188 ,703.1891479492188 ,721.634765625 ,1156.853515625 ,1202.355224609375 ,1125.035400390625 ,1688.48388671875 ,1689.0537109375 ,1687.9541015625 ,-45.470542907714844 ,-10.222365379333496 ,-55.224124908447266 ,-55.224124908447266 ,-10.222365379333496 ,-45.30834197998047 ,-55.224124908447266 ,-45.30834197998047 ,-61.866416931152344 ,-55.224124908447266 ,-61.866416931152344 ,-84.37976837158203 ,-10.222365379333496 ,-3.633512020111084 ,-45.30834197998047 ,1659.263916015625 ,1657.24658203125 ,1662.9674072265625 ,1644.4151611328125 ,1648.9278564453125 ,1648.9373779296875 ,1523.725830078125 ,1500.01318359375 ,1312.3348388671875 ,1223.370849609375 ,1455.2423095703125 ,1523.725830078125 ,1646.7701416015625 ,1650.722900390625 ,1644.97119140625 ,1632.47265625 ,1639.4248046875 ,1649.9718017578125 ,1578.3837890625 ,1582.832275390625 ,1567.9937744140625 ,1676.6839599609375 ,1669.4385986328125 ,1664.2130126953125 ,1917.1875 ,1827.9642333984375 ,1801.9376220703125 ,1917.1875 ,1801.9376220703125 ,1825.7593994140625 ,1477.014404296875 ,1394.346435546875 ,1420.429931640625 ,1574.271484375 ,1571.6690673828125 ,1555.5506591796875 ,1662.9295654296875 ,1647.4063720703125 ,1655.194580078125 ,1543.3221435546875 ,1570.3974609375 ,1609.0736083984375 ,1602.2880859375 ,1598.4822998046875 ,1603.0877685546875 ,1637.6385498046875 ,1627.56640625 ,1637.099853515625 ,1375.368896484375 ,1315.204833984375 ,1354.074951171875 ,1375.368896484375 ,1354.074951171875 ,1500.01318359375 ,757.2192993164062 ,750.1624145507812 ,647.0407104492188 ,757.2192993164062 ,843.5925903320312 ,750.1624145507812 ,647.0407104492188 ,816.103271484375 ,757.2192993164062 ,908.4688720703125 ,806.8987426757812 ,792.0645141601562 ,1536.6990966796875 ,1541.7872314453125 ,1538.50439453125 ,-89.9217529296875 ,-90.85780334472656 ,-89.28755950927734 ,1550.9483642578125 ,1586.283935546875 ,1561.9427490234375 ,865.3997802734375 ,790.1590576171875 ,786.929931640625 ,812.9592895507812 ,795.1342163085938 ,810.5379028320312 ,724.1598510742188 ,696.7554931640625 ,704.5260009765625 ,1681.121337890625 ,1682.1060791015625 ,1675.666015625 ,1076.6728515625 ,1391.6668701171875 ,1355.326171875 ,1685.1534423828125 ,1684.2529296875 ,1684.3946533203125 ,1623.536376953125 ,1611.3134765625 ,1618.9720458984375 ,1623.536376953125 ,1619.4249267578125 ,1611.3134765625 ,1689.3079833984375 ,1691.265380859375 ,1688.627197265625 ,1641.736083984375 ,1451.8507080078125 ,1505.4681396484375 ,-102.12205505371094 ,-62.83191680908203 ,-94.17471313476562 ,1680.8619384765625 ,1724.7464599609375 ,1740.9375 ,-118.19950103759766 ,-176.13626098632812 ,-19.886470794677734 ,1633.0225830078125 ,1644.6551513671875 ,1638.189208984375 ,1633.0225830078125 ,1638.189208984375 ,1632.71142578125 ,1638.189208984375 ,1644.6551513671875 ,1637.38037109375 ,1638.189208984375 ,1637.099853515625 ,1632.71142578125 ,1638.189208984375 ,1637.38037109375 ,1637.099853515625 ,1684.94921875 ,1685.358154296875 ,1686.605712890625 ,-150.75221252441406 ,-150.53488159179688 ,-133.311767578125 ,-107.67842864990234 ,-102.12205505371094 ,-94.17471313476562 ,794.5354614257812 ,790.4133911132812 ,789.9561767578125 ,-93.72039031982422 ,-94.87836456298828 ,-93.44713592529297 ,-93.72039031982422 ,-93.75316619873047 ,-97.81755828857422 ,-93.72039031982422 ,-93.44713592529297 ,-93.75316619873047 ,-123.2982406616211 ,-146.23471069335938 ,-116.95503997802734 ,-58.43694305419922 ,-51.333580017089844 ,-58.127685546875 ,-58.43694305419922 ,-58.539974212646484 ,-52.834678649902344 ,-58.43694305419922 ,-52.834678649902344 ,-51.333580017089844 ,-58.43694305419922 ,-65.2342300415039 ,-58.539974212646484 ,-58.127685546875 ,-51.333580017089844 ,-43.43236541748047 ,1685.16943359375 ,1684.94921875 ,1687.9541015625 ,1649.9161376953125 ,1644.2154541015625 ,1638.5665283203125 ,-135.65972900390625 ,-131.45046997070312 ,-133.80435180664062 ,-135.65972900390625 ,-139.70440673828125 ,-137.81597900390625 ,-135.65972900390625 ,-137.81597900390625 ,-131.45046997070312 ,-135.65972900390625 ,-133.80435180664062 ,-137.67189025878906 ,-135.65972900390625 ,-137.67189025878906 ,-139.70440673828125 ,-131.45046997070312 ,-130.15724182128906 ,-133.80435180664062 ,-133.80435180664062 ,-130.15724182128906 ,-137.67189025878906 ,1598.9300537109375 ,1601.3255615234375 ,1609.713134765625 ,1609.713134765625 ,1601.3255615234375 ,1611.3134765625 ,1594.7960205078125 ,1592.21435546875 ,1592.2626953125 ,1567.9937744140625 ,1582.832275390625 ,1570.4049072265625 ,1567.5185546875 ,1564.0540771484375 ,1566.099365234375 ,1569.4425048828125 ,1568.8011474609375 ,1570.540283203125 ,887.3312377929688 ,783.8365478515625 ,881.7615966796875 ,198.62681579589844 ,36.951839447021484 ,-22.08594512939453 ,198.62681579589844 ,-22.08594512939453 ,156.33731079101562 ,198.62681579589844 ,156.33731079101562 ,202.90794372558594 ,1653.306640625 ,1646.00439453125 ,1649.5989990234375 ,1647.4891357421875 ,1651.2080078125 ,1632.63623046875 ,724.7101440429688 ,753.95947265625 ,751.0639038085938 ,783.279052734375 ,785.9707641601562 ,778.2691650390625 ,1635.5401611328125 ,1648.748779296875 ,1568.8011474609375 ,1477.02099609375 ,1563.18798828125 ,1603.4398193359375 ,1608.6029052734375 ,1614.930419921875 ,1602.9510498046875 ,965.7979125976562 ,890.9190673828125 ,814.373046875 ,965.7979125976562 ,960.0421752929688 ,890.9190673828125 ,1685.360595703125 ,1685.5765380859375 ,1687.4100341796875 ,1639.7213134765625 ,1632.47265625 ,1638.164794921875 ,1677.5621337890625 ,1676.8214111328125 ,1674.104736328125 ,1677.5621337890625 ,1674.104736328125 ,1675.241943359375 ,1631.489013671875 ,1629.037841796875 ,1622.14599609375 ,123.47190856933594 ,65.91230010986328 ,130.8192138671875 ,1565.324951171875 ,1571.97705078125 ,1578 ,1691.6446533203125 ,1690.9208984375 ,1691.998779296875 ,-137.81597900390625 ,-139.70440673828125 ,-141.87368774414062 ,894.9439086914062 ,886.61474609375 ,972.8710327148438 ,1022.6570434570312 ,1014.3856811523438 ,1007.3656616210938 ,1022.6570434570312 ,1032.4320068359375 ,1014.3856811523438 ,1022.6570434570312 ,1088.1229248046875 ,1051.304931640625 ,1022.6570434570312 ,1051.304931640625 ,1032.4320068359375 ,1674.104736328125 ,1676.8214111328125 ,1676.2178955078125 ,1693.1881103515625 ,1691.7314453125 ,1694.019775390625 ,1694.019775390625 ,1691.7314453125 ,1690.560302734375 ,1694.019775390625 ,1690.560302734375 ,1691.265380859375 ,1694.019775390625 ,1694.115234375 ,1693.1881103515625 ,1662.7359619140625 ,1669.6060791015625 ,1665.25 ,1249.8555908203125 ,1286.781494140625 ,1210.17138671875 ,1544.0389404296875 ,1544.6461181640625 ,1541.419677734375 ,1544.0389404296875 ,1547.5792236328125 ,1544.6461181640625 ,1544.6461181640625 ,1537.858642578125 ,1541.419677734375 ,1691.309814453125 ,1692.15234375 ,1692.026123046875 ,156.33731079101562 ,225.7664794921875 ,202.90794372558594 ,803.6015625 ,803.208251953125 ,803.314697265625 ,-90.96149444580078 ,-120.13593292236328 ,-88.02678680419922 ,-90.96149444580078 ,-104.98910522460938 ,-120.13593292236328 ,891.906494140625 ,899.0311279296875 ,896.1288452148438 ,891.906494140625 ,896.1288452148438 ,851.257080078125 ,891.906494140625 ,851.257080078125 ,814.20654296875 ,891.906494140625 ,814.20654296875 ,900.3047485351562 ,-154.71624755859375 ,1.143841028213501 ,-33.623085021972656 ,1632.5113525390625 ,1637.7437744140625 ,1633.1016845703125 ,1683.764404296875 ,1680.9556884765625 ,1683.5235595703125 ,1651.2288818359375 ,1649.7333984375 ,1658.1865234375 ,1651.2288818359375 ,1658.1865234375 ,1643.2557373046875 ,1825.7593994140625 ,1801.9376220703125 ,1822.6085205078125 ,1592.2626953125 ,1592.21435546875 ,1589.46728515625 ,1595.38623046875 ,1594.472900390625 ,1596.6580810546875 ,1595.38623046875 ,1590.464111328125 ,1594.472900390625 ,-147.25537109375 ,-156.220947265625 ,-145.2946014404297 ,-147.25537109375 ,-145.2946014404297 ,-151.3717803955078 ,-147.25537109375 ,-151.3717803955078 ,-156.220947265625 ,1676.6839599609375 ,1684.030029296875 ,1695.0233154296875 ,1676.6839599609375 ,1678.83642578125 ,1684.030029296875 ,1683.40087890625 ,1678.5303955078125 ,1679.259033203125 ,786.1884765625 ,784.9035034179688 ,779.576904296875 ,105.0716323852539 ,-168.038330078125 ,147.09942626953125 ,1645.4742431640625 ,1644.97119140625 ,1648.815673828125 ,-114.72260284423828 ,-112.6689453125 ,-145.39947509765625 ,1630.985595703125 ,1801.9376220703125 ,1827.9642333984375 ,1528.123779296875 ,1534.2867431640625 ,1511.5054931640625 ,757.3011474609375 ,761.1368408203125 ,746.5005493164062 ,757.3011474609375 ,778.0946044921875 ,761.1368408203125 ,757.3011474609375 ,746.5005493164062 ,747.5623168945312 ,1693.54931640625 ,1693.0771484375 ,1693.3846435546875 ,1693.54931640625 ,1693.6707763671875 ,1693.0771484375 ,1693.6707763671875 ,1693.54931640625 ,1693.3846435546875 ,873.7798461914062 ,851.3971557617188 ,896.1288452148438 ,873.7798461914062 ,874.5257568359375 ,851.3971557617188 ,896.1288452148438 ,851.3971557617188 ,851.257080078125 ,687.5601806640625 ,673.9083251953125 ,626.051025390625 ,687.8463134765625 ,777.9039916992188 ,786.929931640625 ,687.8463134765625 ,786.929931640625 ,790.1590576171875 ,1181.88525390625 ,1391.05419921875 ,1381.69482421875 ,1181.88525390625 ,1146.396484375 ,1391.05419921875 ,1651.5751953125 ,1639.356201171875 ,1646.39453125 ,1652.4918212890625 ,1653.266357421875 ,1648.84814453125 ,1652.4918212890625 ,1656.9443359375 ,1653.266357421875 ,1648.84814453125 ,1653.266357421875 ,1648.9278564453125 ,1638.8861083984375 ,1648.0037841796875 ,1635.4061279296875 ,1638.8861083984375 ,1635.4061279296875 ,1623.9122314453125 ,1882.818359375 ,1867.8238525390625 ,1870.11962890625 ,1892.9903564453125 ,1894.75439453125 ,1868.412353515625 ,1892.9903564453125 ,1868.412353515625 ,1898.9945068359375 ,1892.9903564453125 ,1898.9945068359375 ,1882.818359375 ,1600.7247314453125 ,1601.2574462890625 ,1602.168701171875 ,1101.100830078125 ,961.0006713867188 ,1018.4519653320312 ,570.5579223632812 ,673.9083251953125 ,625.8710327148438 ,1562.0313720703125 ,1561.3687744140625 ,1558.181884765625 ,-57.356292724609375 ,-48.14024353027344 ,17.356164932250977 ,738.90380859375 ,753.7611083984375 ,744.73828125 ,-131.700927734375 ,-129.4573974609375 ,-123.30195617675781 ,1604.458251953125 ,1601.7562255859375 ,1585.6143798828125 ,846.870849609375 ,859.4566650390625 ,848.5045776367188 ,1668.600830078125 ,1670.8912353515625 ,1673.774169921875 ,-132.90476989746094 ,-116.43762969970703 ,-57.356292724609375 ,1780.859619140625 ,1864.595458984375 ,1885.945556640625 ,-138.25650024414062 ,-131.21571350097656 ,-137.81597900390625 ,-131.21571350097656 ,-131.45046997070312 ,-137.81597900390625 ,1649.632568359375 ,1656.053955078125 ,1650.5126953125 ,1650.5126953125 ,1656.053955078125 ,1659.650634765625 ,1650.5126953125 ,1659.650634765625 ,1657.146728515625 ,-62.83191680908203 ,-56.81816482543945 ,-94.17471313476562 ,1469.92626953125 ,2016.6395263671875 ,1643.9481201171875 ,1589.0775146484375 ,1584.3056640625 ,1580.0263671875 ,1589.0775146484375 ,1580.0263671875 ,1590.1669921875 ,1589.0775146484375 ,1587.611083984375 ,1584.3056640625 ,1627.836669921875 ,1632.2459716796875 ,1634.8624267578125 ,1673.916259765625 ,1669.50390625 ,1668.263916015625 ,1574.650390625 ,1592.0440673828125 ,1577.8319091796875 ,1574.650390625 ,1580.7481689453125 ,1592.0440673828125 ,1683.5235595703125 ,1685.785888671875 ,1683.764404296875 ,1565.482666015625 ,1578.07763671875 ,1566.546630859375 ,1565.482666015625 ,1575.04296875 ,1578.07763671875 ,1125.035400390625 ,1014.3953247070312 ,1083.5889892578125 ,835.4942016601562 ,844.23388671875 ,847.5123291015625 ,-101.84134674072266 ,-61.866416931152344 ,-114.91108703613281 ,-101.84134674072266 ,-84.37976837158203 ,-61.866416931152344 ,959.7281494140625 ,717.6920776367188 ,620.417236328125 ,1570.4049072265625 ,1582.832275390625 ,1569.2679443359375 ,1272.394287109375 ,1282.9049072265625 ,1382.652587890625 ,868.6121826171875 ,826.2499389648438 ,777.5641479492188 ,1571.97705078125 ,1580.0263671875 ,1578 ,-94.17471313476562 ,-98.61483764648438 ,-107.67842864990234 ,-94.17471313476562 ,-56.81816482543945 ,-88.27867126464844 ,-94.17471313476562 ,-88.27867126464844 ,-98.61483764648438 ,1551.97705078125 ,1504.46337890625 ,1392.46337890625 ,1392.46337890625 ,1504.46337890625 ,1526.1451416015625 ,1676.2178955078125 ,1676.8214111328125 ,1677.5621337890625 ,1676.2178955078125 ,1678.31201171875 ,1676.799072265625 ,1685.5919189453125 ,1686.6595458984375 ,1686.419921875 ,1685.5919189453125 ,1684.72509765625 ,1686.6595458984375 ,1094.449462890625 ,1258.8929443359375 ,1289.6263427734375 ,1094.449462890625 ,1289.6263427734375 ,1129.8260498046875 ,-118.19950103759766 ,-154.95399475097656 ,-174.0264892578125 ,-224.1885223388672 ,-22.08594512939453 ,-17.97229766845703 ,1644.6551513671875 ,1633.0225830078125 ,1638.4283447265625 ,1598.8990478515625 ,1599.11962890625 ,1598.4822998046875 ,1655.188720703125 ,1654.4324951171875 ,1651.813232421875 ,1652.7374267578125 ,1646.00439453125 ,1653.306640625 ,1629.330810546875 ,1635.490478515625 ,1603.6051025390625 ,-125.6340103149414 ,-138.2955322265625 ,-120.13593292236328 ,1565.161865234375 ,1568.649169921875 ,1578.0010986328125 ,717.0455322265625 ,740.1326293945312 ,754.8847045898438 ,768.367431640625 ,782.3931274414062 ,772.416748046875 ,1541.419677734375 ,1537.4833984375 ,1544.3592529296875 ,1617.2596435546875 ,1613.71533203125 ,1603.9329833984375 ,1298.5340576171875 ,1204.0008544921875 ,1272.394287109375 ,1083.865478515625 ,1093.7362060546875 ,1079.8157958984375 ,1564.2630615234375 ,1523.1141357421875 ,1538.6708984375 ,1690.4541015625 ,1691.6446533203125 ,1691.991943359375 ,1690.4541015625 ,1689.956787109375 ,1691.6446533203125 ,1668.421142578125 ,1669.6590576171875 ,1667.6202392578125 ,1668.421142578125 ,1669.1170654296875 ,1669.6590576171875 ,1668.421142578125 ,1667.6202392578125 ,1667.523681640625 ,1668.421142578125 ,1667.523681640625 ,1668.1595458984375 ,1668.421142578125 ,1668.1595458984375 ,1669.1170654296875 ,1657.24658203125 ,1659.263916015625 ,1650.775146484375 ,1671.489013671875 ,1671.78515625 ,1667.297607421875 ,1671.489013671875 ,1677.313720703125 ,1675.3575439453125 ,1671.489013671875 ,1669.9747314453125 ,1677.313720703125 ,-142.55540466308594 ,-145.5254364013672 ,-144.49041748046875 ,-142.55540466308594 ,-139.70440673828125 ,-143.0941925048828 ,1454.7735595703125 ,1469.92626953125 ,2080.4912109375 ,778.7959594726562 ,778.2691650390625 ,785.9707641601562 ,1523.725830078125 ,1312.3348388671875 ,1223.370849609375 ,1051.304931640625 ,1052.5938720703125 ,1006.5462646484375 ,1051.304931640625 ,1006.5462646484375 ,1032.4320068359375 ,1051.304931640625 ,1088.1229248046875 ,1052.5938720703125 ,1555.5506591796875 ,1559.9676513671875 ,1574.271484375 ,1694.019775390625 ,1692.3402099609375 ,1693.8438720703125 ,1635.5401611328125 ,1686.75048828125 ,1648.748779296875 ,1550.6932373046875 ,1552.7763671875 ,1541.919921875 ,1620.7742919921875 ,1622.9652099609375 ,1622.0340576171875 ,1620.7742919921875 ,1622.0340576171875 ,1575.0830078125 ,790.0026245117188 ,741.1661987304688 ,753.0946044921875 ,1580.21044921875 ,1595.8814697265625 ,1635.144775390625 ,1682.081298828125 ,1685.785888671875 ,1683.5235595703125 ,762.7431640625 ,751.0639038085938 ,772.115966796875 ,1363.837646484375 ,1396.57275390625 ,1422.773193359375 ,687.5601806640625 ,729.4252319335938 ,727.0682983398438 ,687.5601806640625 ,682.0635986328125 ,729.4252319335938 ,727.0682983398438 ,729.4252319335938 ,731.4716186523438 ,1555.225830078125 ,1554.8896484375 ,1552.0093994140625 ,1555.225830078125 ,1554.2913818359375 ,1554.8896484375 ,866.286376953125 ,894.0360717773438 ,874.3985595703125 ,1605.57763671875 ,1611.38037109375 ,1609.4886474609375 ,1637.7437744140625 ,1637.0882568359375 ,1639.7213134765625 ,1586.283935546875 ,1569.7120361328125 ,1561.9427490234375 ,961.0006713867188 ,826.8889770507812 ,986.6577758789062 ,961.0006713867188 ,986.6577758789062 ,1018.4519653320312 ,1548.867919921875 ,1552.0093994140625 ,1550.103271484375 ,1539.6844482421875 ,1544.3592529296875 ,1537.4833984375 ,1544.3592529296875 ,1539.6844482421875 ,1541.8375244140625 ,1392.0789794921875 ,1488.171630859375 ,1433.00927734375 ,1392.0789794921875 ,1433.00927734375 ,1371.5784912109375 ,1488.171630859375 ,1454.1854248046875 ,1433.00927734375 ,1638.287841796875 ,1662.5382080078125 ,1645.1536865234375 ,1638.287841796875 ,1642.0909423828125 ,1662.5382080078125 ,1638.287841796875 ,1645.1536865234375 ,1635.6124267578125 ,1558.2471923828125 ,1565.324951171875 ,1567.0540771484375 ,1558.2471923828125 ,1559.673828125 ,1565.324951171875 ,1567.0540771484375 ,1566.70947265625 ,1558.2471923828125 ,1613.4114990234375 ,1625.792724609375 ,1605.64599609375 ,795.9425048828125 ,806.5247192382812 ,799.779541015625 ,1520.814453125 ,1448.8497314453125 ,1535.486572265625 ,1631.0205078125 ,1645.921630859375 ,1644.4151611328125 ,1631.0205078125 ,1643.0020751953125 ,1645.921630859375 ,1615.1953125 ,1627.878662109375 ,1624.47802734375 ,-103.25717163085938 ,-49.69411087036133 ,-86.79059600830078 ,-121.91429901123047 ,-130.15724182128906 ,-103.25717163085938 ,-103.25717163085938 ,-86.79059600830078 ,-121.91429901123047 ,1140.5811767578125 ,1170.9833984375 ,1223.370849609375 ,1636.909912109375 ,1627.1104736328125 ,1634.977783203125 ,1541.4324951171875 ,1554.7178955078125 ,1506.52294921875 ,1596.00439453125 ,1615.1953125 ,1593.195068359375 ,-0.7145509719848633 ,-21.956390380859375 ,-22.144731521606445 ,-0.7145509719848633 ,-5.711810111999512 ,-21.956390380859375 ,763.2747192382812 ,740.9560546875 ,765.1046752929688 ,1674.682861328125 ,1672.923583984375 ,1670.61572265625 ,1674.682861328125 ,1675.4527587890625 ,1672.923583984375 ,1638.38623046875 ,1642.71826171875 ,1649.3350830078125 ,1825.2783203125 ,1880.57177734375 ,1782.79150390625 ,-7.566917896270752 ,-21.956390380859375 ,10.203259468078613 ,1587.6796875 ,1587.8623046875 ,1595.2255859375 ,1587.6796875 ,1571.12646484375 ,1587.8623046875 ,45.33297348022461 ,68.86013793945312 ,51.839210510253906 ,45.33297348022461 ,51.839210510253906 ,6.033566951751709 ,-146.23471069335938 ,-156.66671752929688 ,-123.85717010498047 ,1649.9161376953125 ,1675.4527587890625 ,1661.6192626953125 ,1649.9161376953125 ,1638.5665283203125 ,1675.4527587890625 ,783.3239135742188 ,785.389404296875 ,772.115966796875 ,783.3239135742188 ,772.115966796875 ,777.9764404296875 ,1676.1666259765625 ,1671.78173828125 ,1674.8221435546875 ,1674.8221435546875 ,1673.062744140625 ,1678.726318359375 ,1674.8221435546875 ,1678.726318359375 ,1676.1666259765625 ,1674.8221435546875 ,1671.78173828125 ,1673.062744140625 ,1385.2088623046875 ,1302.64599609375 ,1376.0538330078125 ,1409.1474609375 ,1376.0538330078125 ,1391.6668701171875 ,1.143841028213501 ,-154.71624755859375 ,-262.1553649902344 ,1684.946044921875 ,1601.7646484375 ,1579.588134765625 ,670.9752807617188 ,387.1172790527344 ,747.9818115234375 ,1693.1881103515625 ,1694.03564453125 ,1693.0804443359375 ,1657.06494140625 ,1659.8006591796875 ,1660.6507568359375 ,1657.06494140625 ,1660.6507568359375 ,1660.91064453125 ,1610.0328369140625 ,1622.0340576171875 ,1617.3553466796875 ,746.6197509765625 ,723.9068603515625 ,790.7344360351562 ,864.3307495117188 ,783.8365478515625 ,887.3312377929688 ,-160.0223388671875 ,-297.3943176269531 ,-223.46041870117188 ,-160.0223388671875 ,-283.53369140625 ,-297.3943176269531 ,848.3939208984375 ,832.3193969726562 ,814.1434326171875 ,848.3939208984375 ,865.5841674804688 ,859.1519165039062 ,848.3939208984375 ,859.1519165039062 ,832.3193969726562 ,848.3939208984375 ,814.1434326171875 ,827.7611083984375 ,-130.08799743652344 ,-133.1193084716797 ,-133.48570251464844 ,814.9298095703125 ,811.11669921875 ,823.284912109375 ,1622.9652099609375 ,1625.169189453125 ,1622.0340576171875 ,1691.272705078125 ,1690.0823974609375 ,1690.7293701171875 ,1691.272705078125 ,1690.7293701171875 ,1692.35009765625 ,1577.014892578125 ,1569.7120361328125 ,1586.283935546875 ,893.1461791992188 ,748.1673583984375 ,774.962646484375 ,806.8987426757812 ,755.9078369140625 ,761.9156494140625 ,1639.492919921875 ,1658.670166015625 ,1623.536376953125 ,724.1598510742188 ,704.5260009765625 ,747.0787353515625 ,852.0985717773438 ,825.994140625 ,822.8524780273438 ,852.0985717773438 ,885.3508911132812 ,818.6195068359375 ,852.0985717773438 ,818.6195068359375 ,825.994140625 ,1687.83935546875 ,1688.9842529296875 ,1690.0823974609375 ,1687.83935546875 ,1690.0823974609375 ,1687.61474609375 ,1534.9771728515625 ,1541.919921875 ,1537.7679443359375 ,-94.73629760742188 ,-97.81755828857422 ,-90.04814910888672 ,-94.73629760742188 ,-103.65386962890625 ,-97.81755828857422 ,962.6599731445312 ,969.8532104492188 ,943.5916137695312 ,1589.6549072265625 ,1589.28662109375 ,1579.202392578125 ,1686.419921875 ,1686.6595458984375 ,1685.5919189453125 ,726.8759765625 ,723.293212890625 ,693.4887084960938 ,1557.295654296875 ,1556.60546875 ,1556.0218505859375 ,1557.295654296875 ,1554.8896484375 ,1556.60546875 ,896.1288452148438 ,885.3508911132812 ,852.0985717773438 ,896.1288452148438 ,899.0311279296875 ,885.3508911132812 ,1673.771728515625 ,1667.962646484375 ,1673.615966796875 ,1596.6580810546875 ,1594.472900390625 ,1599.1964111328125 ,-145.84243774414062 ,-140.41754150390625 ,-137.9761505126953 ,-145.84243774414062 ,-143.90379333496094 ,-140.41754150390625 ,1579.477783203125 ,1575.49267578125 ,1572.422119140625 ,1579.477783203125 ,1584.0416259765625 ,1575.49267578125 ,1575.49267578125 ,1566.3751220703125 ,1572.422119140625 ,1405.2806396484375 ,1420.555419921875 ,1462.50830078125 ,1405.2806396484375 ,1404.30029296875 ,1420.555419921875 ,1591.1419677734375 ,1592.171875 ,1589.919189453125 ,1574.4801025390625 ,1552.2708740234375 ,1410.970458984375 ,1574.4801025390625 ,1410.970458984375 ,1387.4476318359375 ,965.7979125976562 ,1008.1751708984375 ,1237.4595947265625 ,703.1891479492188 ,657.6510620117188 ,687.8463134765625 ,1614.55859375 ,1613.7200927734375 ,1601.72216796875 ,1409.1474609375 ,1391.6668701171875 ,1406.46630859375 ,706.0634765625 ,1007.3907470703125 ,1093.8919677734375 ,393.78424072265625 ,363.066162109375 ,303.5206604003906 ,1648.3623046875 ,1668.6605224609375 ,1642.762939453125 ,1648.3623046875 ,1664.719482421875 ,1668.6605224609375 ,1642.762939453125 ,1668.6605224609375 ,1634.8624267578125 ,704.7988891601562 ,729.2923583984375 ,683.404296875 ,1561.707763671875 ,1571.6982421875 ,1563.536865234375 ,1694.03564453125 ,1693.1881103515625 ,1694.117919921875 ,781.643310546875 ,783.5720825195312 ,775.9713745117188 ,1569.4425048828125 ,1589.3944091796875 ,1585.3182373046875 ,1578 ,1584.3056640625 ,1582.79833984375 ,1578 ,1580.0263671875 ,1584.3056640625 ,1541.8375244140625 ,1546.825439453125 ,1544.3592529296875 ,-109.40483856201172 ,-158.48971557617188 ,-141.19369506835938 ,-37.357818603515625 ,-88.02678680419922 ,-117.57561492919922 ,-117.57561492919922 ,-120.13593292236328 ,-132.05003356933594 ,-117.57561492919922 ,-88.02678680419922 ,-120.13593292236328 ,1632.47265625 ,1634.888916015625 ,1639.4248046875 ,1237.4595947265625 ,1129.8260498046875 ,1289.6263427734375 ,97.57292175292969 ,142.91012573242188 ,155.5832977294922 ,97.57292175292969 ,155.5832977294922 ,225.9130401611328 ,1674.3995361328125 ,1673.563720703125 ,1678.28515625 ,1644.6551513671875 ,1646.9783935546875 ,1637.38037109375 ,1079.9857177734375 ,1120.439208984375 ,1092.355224609375 ,803.9970092773438 ,805.4881591796875 ,796.2474975585938 ,1559.339111328125 ,1566.3751220703125 ,1564.533203125 ,1566.3751220703125 ,1559.339111328125 ,1572.422119140625 ,1566.3751220703125 ,1574.923828125 ,1564.533203125 ,1650.9715576171875 ,1628.5848388671875 ,1618.220947265625 ,1650.9715576171875 ,1633.216552734375 ,1628.5848388671875 ,1645.7232666015625 ,1613.9197998046875 ,1641.5775146484375 ,1685.16943359375 ,1686.6595458984375 ,1684.72509765625 ,-111.2472915649414 ,-97.18619537353516 ,-124.65084075927734 ,-111.2472915649414 ,-137.65219116210938 ,-125.6340103149414 ,-111.2472915649414 ,-124.65084075927734 ,-137.65219116210938 ,-111.2472915649414 ,-125.6340103149414 ,-104.98910522460938 ,-124.65084075927734 ,-127.38860321044922 ,-137.65219116210938 ,1568.649169921875 ,1556.0218505859375 ,1556.784423828125 ,1556.784423828125 ,1556.0218505859375 ,1556.60546875 ,-209.7818145751953 ,387.1172790527344 ,4.928195953369141 ,825.1792602539062 ,833.7752075195312 ,891.51708984375 ,1641.736083984375 ,1505.4681396484375 ,1591.122802734375 ,1690.796875 ,1692.3402099609375 ,1691.265380859375 ,1659.263916015625 ,1652.046875 ,1650.775146484375 ,1006.5462646484375 ,1000.3975830078125 ,1032.4320068359375 ,1006.5462646484375 ,945.8577880859375 ,1000.3975830078125 ,1032.4320068359375 ,1000.3975830078125 ,1014.3856811523438 ,1581.1905517578125 ,1585.8505859375 ,1582.463134765625 ,1665.5714111328125 ,1679.518310546875 ,1662.6783447265625 ,1665.5714111328125 ,1662.6783447265625 ,1651.2210693359375 ,1637.099853515625 ,1627.56640625 ,1632.71142578125 ,1570.540283203125 ,1579.6885986328125 ,1591.2655029296875 ,1579.6885986328125 ,1648.748779296875 ,1591.2655029296875 ,1579.6885986328125 ,1570.540283203125 ,1648.748779296875 ,1642.71826171875 ,1643.6181640625 ,1649.3350830078125 ,1676.1666259765625 ,1672.58154296875 ,1671.78173828125 ,1686.75048828125 ,1872.8701171875 ,1884.81787109375 ,1686.75048828125 ,1884.81787109375 ,1864.595458984375 ,-16.302066802978516 ,-41.81604766845703 ,-56.9789924621582 ,1609.2413330078125 ,1610.650146484375 ,1609.84326171875 ,1649.2877197265625 ,1690.1962890625 ,1636.1689453125 ,1552.2708740234375 ,1477.3577880859375 ,1410.970458984375 ,1614.86376953125 ,1595.8814697265625 ,1635.4149169921875 ,1609.0880126953125 ,1644.015625 ,1652.356201171875 ,1546.7625732421875 ,1540.1556396484375 ,1553.118896484375 ,781.4766845703125 ,716.3633422851562 ,723.293212890625 ,-142.7763671875 ,-137.036376953125 ,-142.95718383789062 ,-142.7763671875 ,-142.61868286132812 ,-137.036376953125 ,-142.7763671875 ,-145.2946014404297 ,-142.61868286132812 ,818.6195068359375 ,885.3508911132812 ,836.4472045898438 ,1616.6317138671875 ,1622.7889404296875 ,1614.55859375 ,747.0787353515625 ,704.5260009765625 ,765.2786865234375 ,765.2786865234375 ,761.124755859375 ,747.0787353515625 ,1631.489013671875 ,1643.0020751953125 ,1629.037841796875 ,1718.588134765625 ,1606.3082275390625 ,1616.56201171875 ,466.0267333984375 ,221.2639923095703 ,192.3759765625 ,1872.8701171875 ,1940.6337890625 ,1884.81787109375 ,1585.578369140625 ,1580.116943359375 ,1592.45556640625 ,-150.59349060058594 ,-137.9761505126953 ,-140.41754150390625 ,848.1756591796875 ,845.933349609375 ,840.743408203125 ,848.1756591796875 ,840.743408203125 ,842.6087646484375 ,848.1756591796875 ,852.4119873046875 ,845.933349609375 ,1242.9195556640625 ,1312.53857421875 ,1348.066650390625 ,747.1206665039062 ,742.4617309570312 ,744.7554931640625 ,1671.8157958984375 ,1662.0677490234375 ,1667.950439453125 ,1671.8157958984375 ,1670.61572265625 ,1662.0677490234375 ,957.6220092773438 ,561.8804931640625 ,883.0206909179688 ,763.2747192382812 ,757.730712890625 ,768.367431640625 ,-123.30195617675781 ,-115.24518585205078 ,-113.69429779052734 ,-113.69429779052734 ,-115.24518585205078 ,-110.93496704101562 ,1633.216552734375 ,1639.336181640625 ,1642.0909423828125 ,1642.0909423828125 ,1630.8304443359375 ,1626.154296875 ,1626.0413818359375 ,1615.714599609375 ,1634.2149658203125 ,1537.8978271484375 ,1549.1029052734375 ,1552.5557861328125 ,1537.8978271484375 ,1548.9249267578125 ,1549.1029052734375 ,1667.3758544921875 ,1671.6033935546875 ,1664.859130859375 ,1667.3758544921875 ,1671.78173828125 ,1671.6033935546875 ,1548.560302734375 ,1545.1953125 ,1549.1029052734375 ,1548.560302734375 ,1549.1029052734375 ,1548.9249267578125 ,1545.1953125 ,1552.5557861328125 ,1549.1029052734375 ,1603.4398193359375 ,1563.18798828125 ,1609.0736083984375 ,1567.5185546875 ,1569.775390625 ,1557.3426513671875 ,1567.5185546875 ,1557.3426513671875 ,1564.0540771484375 ,1567.5185546875 ,1603.6051025390625 ,1569.775390625 ,825.994140625 ,805.0759887695312 ,822.8524780273438 ,1673.563720703125 ,1670.4410400390625 ,1659.01953125 ,1676.1666259765625 ,1678.726318359375 ,1679.3565673828125 ,804.2978515625 ,809.3734130859375 ,797.41650390625 ,1690.9208984375 ,1689.956787109375 ,1689.4713134765625 ,1588.3834228515625 ,1581.4888916015625 ,1569.2679443359375 ,959.7281494140625 ,1146.6402587890625 ,1094.449462890625 ,832.0707397460938 ,890.9190673828125 ,875.2785034179688 ,875.2785034179688 ,844.8190307617188 ,832.0707397460938 ,845.576171875 ,830.006103515625 ,829.1942138671875 ,850.8707275390625 ,853.600830078125 ,855.8199462890625 ,886.61474609375 ,825.1792602539062 ,891.51708984375 ,799.5333251953125 ,835.8551025390625 ,815.1546020507812 ,1563.6204833984375 ,1556.96240234375 ,1553.41455078125 ,1652.3216552734375 ,1644.015625 ,1636.007568359375 ,1634.52197265625 ,1633.0850830078125 ,1633.53369140625 ,1634.52197265625 ,1633.53369140625 ,1636.2884521484375 ,1670.6949462890625 ,1672.0784912109375 ,1671.40869140625 ,1538.50439453125 ,1541.7872314453125 ,1545.1953125 ,1689.956787109375 ,1688.9609375 ,1689.4713134765625 ,1689.956787109375 ,1688.41552734375 ,1688.9609375 ,959.7281494140625 ,620.417236328125 ,957.6220092773438 ,-147.58274841308594 ,-165.97145080566406 ,-142.4543914794922 ,-142.4543914794922 ,-165.97145080566406 ,-166.96328735351562 ,1568.8011474609375 ,1648.748779296875 ,1570.540283203125 ,1210.17138671875 ,1286.781494140625 ,1149.0843505859375 ,1627.56640625 ,1625.2537841796875 ,1632.71142578125 ,1601.7646484375 ,1523.4749755859375 ,1579.588134765625 ,411.1473388671875 ,444.6069030761719 ,458.4006042480469 ,303.5206604003906 ,363.066162109375 ,59.6855583190918 ,191.36724853515625 ,152.2653350830078 ,141.63189697265625 ,1624.47802734375 ,1627.878662109375 ,1636.365966796875 ,1543.2904052734375 ,1545.1953125 ,1548.560302734375 ,1604.80224609375 ,1635.490478515625 ,1614.5419921875 ,1627.56640625 ,1610.5791015625 ,1625.2537841796875 ,-145.84243774414062 ,-147.34451293945312 ,-143.90379333496094 ,1565.482666015625 ,1572.732177734375 ,1575.04296875 ,1565.482666015625 ,1570.904541015625 ,1572.732177734375 ,1552.7763671875 ,1547.5770263671875 ,1541.919921875 ,1682.5885009765625 ,1683.5235595703125 ,1679.8707275390625 ,1679.8707275390625 ,1681.6229248046875 ,1678.726318359375 ,1679.8707275390625 ,1683.5235595703125 ,1681.6229248046875 ,12.87821102142334 ,39.96271514892578 ,63.12164306640625 ,63.12164306640625 ,39.96271514892578 ,102.53659057617188 ,1558.2471923828125 ,1566.70947265625 ,1560.1588134765625 ,248.44900512695312 ,143.64382934570312 ,87.79638671875 ,1604.0233154296875 ,1538.773681640625 ,1522.60986328125 ,1638.5103759765625 ,1636.1795654296875 ,1637.3267822265625 ,1636.1795654296875 ,1639.7213134765625 ,1637.3267822265625 ,1644.7110595703125 ,1635.94482421875 ,1630.0673828125 ,1644.7110595703125 ,1630.0673828125 ,1633.1016845703125 ,1588.199462890625 ,1523.9736328125 ,1543.3046875 ,1657.659912109375 ,1660.94091796875 ,1657.0157470703125 ,1657.659912109375 ,1663.043212890625 ,1660.94091796875 ,827.5490112304688 ,829.766357421875 ,831.5402221679688 ,827.5490112304688 ,831.5402221679688 ,803.837158203125 ,1686.7393798828125 ,1684.94921875 ,1686.605712890625 ,1686.7393798828125 ,1687.181640625 ,1686.4478759765625 ,-138.47950744628906 ,-138.47608947753906 ,-139.9047393798828 ,1651.2080078125 ,1664.1138916015625 ,1669.09912109375 ,1669.4385986328125 ,1652.5123291015625 ,1664.2130126953125 ,1686.7393798828125 ,1686.976318359375 ,1687.181640625 ,1686.7393798828125 ,1682.1060791015625 ,1686.976318359375 ,1687.181640625 ,1688.0482177734375 ,1686.4478759765625 ,1687.181640625 ,1686.976318359375 ,1688.0482177734375 ,341.78338623046875 ,391.55621337890625 ,444.2389221191406 ,341.78338623046875 ,320.3096618652344 ,391.55621337890625 ,391.55621337890625 ,500.4654235839844 ,444.2389221191406 ,444.2389221191406 ,500.4654235839844 ,341.78338623046875 ,4.928195953369141 ,39.237022399902344 ,-209.7818145751953 ,746.0133056640625 ,742.4617309570312 ,753.7611083984375 ,57.19397735595703 ,-84.93722534179688 ,70.94438171386719 ,835.8551025390625 ,865.2728881835938 ,854.4637451171875 ,835.8551025390625 ,826.6268310546875 ,865.2728881835938 ,835.8551025390625 ,854.4637451171875 ,815.1546020507812 ,120.27181243896484 ,151.38206481933594 ,141.63189697265625 ,120.27181243896484 ,141.63189697265625 ,73.47518157958984 ,979.4857177734375 ,961.9600830078125 ,1270.929931640625 ,803.208251953125 ,799.779541015625 ,806.5247192382812 ,1680.8697509765625 ,1678.8447265625 ,1679.267333984375 ,815.1546020507812 ,810.5379028320312 ,821.3425903320312 ,815.1546020507812 ,854.4637451171875 ,810.5379028320312 ,721.634765625 ,703.1891479492188 ,716.8273315429688 ,716.8273315429688 ,723.293212890625 ,721.634765625 ,716.8273315429688 ,693.4887084960938 ,723.293212890625 ,716.8273315429688 ,703.1891479492188 ,693.4887084960938 ,1663.5411376953125 ,1632.47265625 ,1662.08154296875 ,1663.5411376953125 ,1662.08154296875 ,1659.3050537109375 ,1080.477294921875 ,1068.9901123046875 ,1092.355224609375 ,604.1659545898438 ,772.7360229492188 ,793.662109375 ,772.7360229492188 ,604.1659545898438 ,363.066162109375 ,1677.809814453125 ,1674.4515380859375 ,1671.58349609375 ,1556.9329833984375 ,1487.403564453125 ,1505.9176025390625 ,1688.9842529296875 ,1687.83935546875 ,1686.9090576171875 ,1580.0263671875 ,1589.46728515625 ,1590.1669921875 ,865.5841674804688 ,846.8115844726562 ,844.23388671875 ,-46.94858169555664 ,-5.270526885986328 ,-13.013050079345703 ,1523.9736328125 ,1536.750244140625 ,1543.3046875 ,1667.665283203125 ,1669.50390625 ,1669.6793212890625 ,1544.0799560546875 ,1546.3587646484375 ,1538.919189453125 ,-112.6689453125 ,-48.63685607910156 ,-64.88725280761719 ,1646.7174072265625 ,1646.2232666015625 ,1647.802978515625 ,1568.3416748046875 ,1558.3375244140625 ,1553.1898193359375 ,1648.9971923828125 ,1652.7374267578125 ,1659.1036376953125 ,1648.9971923828125 ,1659.1036376953125 ,1658.7738037109375 ,1648.9971923828125 ,1650.792236328125 ,1652.7374267578125 ,1667.3428955078125 ,1667.523681640625 ,1666.2528076171875 ,1693.0804443359375 ,1692.35009765625 ,1690.7293701171875 ,1565.91796875 ,1591.043701171875 ,1589.19580078125 ,1371.5784912109375 ,1433.00927734375 ,1422.2646484375 ,1433.00927734375 ,1454.1854248046875 ,1422.2646484375 ,815.931396484375 ,830.006103515625 ,845.576171875 ,815.931396484375 ,845.576171875 ,851.4752197265625 ,830.006103515625 ,815.931396484375 ,793.8555297851562 ,978.0360717773438 ,974.3580322265625 ,975.6517333984375 ,1686.6595458984375 ,1686.5401611328125 ,1685.5919189453125 ,1603.9329833984375 ,1604.0574951171875 ,1598.0146484375 ,1604.0574951171875 ,1597.8408203125 ,1598.0146484375 ,1312.53857421875 ,1242.9195556640625 ,1264.9102783203125 ,1637.527587890625 ,1624.47802734375 ,1636.365966796875 ,966.7046508789062 ,945.1084594726562 ,974.3580322265625 ,974.3580322265625 ,973.2190551757812 ,966.7046508789062 ,806.8987426757812 ,761.9156494140625 ,740.1326293945312 ,1519.374267578125 ,1522.60986328125 ,1454.7735595703125 ,1454.7735595703125 ,1522.60986328125 ,1469.92626953125 ,1617.2596435546875 ,1610.0328369140625 ,1617.3553466796875 ,1601.6107177734375 ,1648.748779296875 ,1671.5623779296875 ,1654.172607421875 ,1648.9373779296875 ,1648.9278564453125 ,1654.172607421875 ,1653.266357421875 ,1657.106201171875 ,1654.172607421875 ,1648.9278564453125 ,1653.266357421875 ,1663.33984375 ,1653.93603515625 ,1657.52294921875 ,1657.52294921875 ,1653.93603515625 ,1653.1845703125 ,1671.5623779296875 ,1698.6005859375 ,1674.372314453125 ,1628.7613525390625 ,1623.7159423828125 ,1628.96435546875 ,1661.7598876953125 ,1661.43212890625 ,1659.3984375 ,-89.05227661132812 ,-101.7322006225586 ,-90.85780334472656 ,1347.615478515625 ,1358.700927734375 ,1348.066650390625 ,1347.615478515625 ,1418.7108154296875 ,1358.700927734375 ,1358.700927734375 ,1418.7108154296875 ,1394.346435546875 ,6.033566951751709 ,-5.711810111999512 ,19.352371215820312 ,712.0097045898438 ,647.1498413085938 ,722.6234130859375 ,655.33544921875 ,616.7412109375 ,696.59814453125 ,655.33544921875 ,696.59814453125 ,718.9926147460938 ,655.33544921875 ,718.9926147460938 ,826.8889770507812 ,1669.9747314453125 ,1665.4600830078125 ,1671.58349609375 ,1669.9747314453125 ,1660.8375244140625 ,1665.4600830078125 ,1675.3975830078125 ,1670.5738525390625 ,1678.5303955078125 ,1691.998779296875 ,1690.9208984375 ,1692.026123046875 ,1418.7108154296875 ,1420.429931640625 ,1394.346435546875 ,1633.1016845703125 ,1637.7437744140625 ,1642.044677734375 ,1628.96435546875 ,1632.4642333984375 ,1628.7613525390625 ,1365.6441650390625 ,1463.4681396484375 ,1418.7108154296875 ,1365.6441650390625 ,1499.37890625 ,1463.4681396484375 ,1365.6441650390625 ,1395.549560546875 ,1499.37890625 ,774.2960205078125 ,943.1546020507812 ,945.1084594726562 ,-93.75316619873047 ,-90.16954040527344 ,-97.81755828857422 ,-93.75316619873047 ,-92.20603942871094 ,-90.16954040527344 ,1330.0029296875 ,1439.11962890625 ,1455.2423095703125 ,-139.9047393798828 ,-139.95550537109375 ,-141.77560424804688 ,-139.9047393798828 ,-138.47608947753906 ,-139.95550537109375 ,-162.18087768554688 ,-149.2166748046875 ,-160.60240173339844 ,-45.30834197998047 ,-76.51492309570312 ,-61.866416931152344 ,1355.326171875 ,1061.62109375 ,1076.6728515625 ,-194.07723999023438 ,-106.98082733154297 ,-95.96955108642578 ,-194.07723999023438 ,-95.96955108642578 ,-224.1885223388672 ,1585.0457763671875 ,1548.0048828125 ,1595.8602294921875 ,1585.0457763671875 ,1553.195068359375 ,1548.0048828125 ,1553.195068359375 ,1585.0457763671875 ,1607.9425048828125 ,1553.195068359375 ,1607.9425048828125 ,1571.2496337890625 ,1684.3946533203125 ,1683.3270263671875 ,1685.5919189453125 ,1667.91650390625 ,1674.372314453125 ,1648.77978515625 ,1649.9161376953125 ,1661.6192626953125 ,1653.306640625 ,1653.306640625 ,1661.6192626953125 ,1652.7374267578125 ,1662.99072265625 ,1658.734619140625 ,1655.255615234375 ,1655.9959716796875 ,1654.172607421875 ,1657.106201171875 ,1586.4669189453125 ,1573.8131103515625 ,1590.207763671875 ,639.7841796875 ,683.404296875 ,662.4285278320312 ,1601.6107177734375 ,1605.57763671875 ,1591.2655029296875 ,1601.6107177734375 ,1632.3934326171875 ,1605.57763671875 ,762.6683349609375 ,771.46240234375 ,772.681884765625 ,772.681884765625 ,771.46240234375 ,781.9956665039062 ,1673.2763671875 ,1674.104736328125 ,1674.09033203125 ,-195.4857635498047 ,-17.97229766845703 ,36.951839447021484 ,-137.802978515625 ,-127.01480102539062 ,-149.2166748046875 ,-137.802978515625 ,-129.64761352539062 ,-127.01480102539062 ,761.124755859375 ,770.282470703125 ,747.0787353515625 ,1627.227294921875 ,1626.644287109375 ,1615.5350341796875 ,-159.0187530517578 ,-158.5607147216797 ,-208.45709228515625 ,1487.403564453125 ,1512.47705078125 ,1505.9176025390625 ,830.1715087890625 ,852.4590454101562 ,840.743408203125 ,830.1715087890625 ,840.743408203125 ,840.1530151367188 ,830.1715087890625 ,825.4397583007812 ,852.4590454101562 ,363.066162109375 ,-136.6942596435547 ,59.6855583190918 ,-109.44664764404297 ,-110.28050994873047 ,-110.93496704101562 ,-109.44664764404297 ,-103.55646514892578 ,-110.28050994873047 ,-109.44664764404297 ,-100.40309143066406 ,-103.55646514892578 ,-155.69383239746094 ,-156.4678955078125 ,-149.55140686035156 ,793.8865356445312 ,767.950927734375 ,790.1903686523438 ,1895.0982666015625 ,2009.0777587890625 ,2316.001708984375 ,1556.9638671875 ,1564.7724609375 ,1573.859619140625 ,1359.5948486328125 ,1595.7293701171875 ,1412.957763671875 ,1382.652587890625 ,1282.9049072265625 ,1315.80810546875 ,1623.382568359375 ,1612.751220703125 ,1630.4327392578125 ,1573.0107421875 ,1570.4049072265625 ,1569.6328125 ,673.703857421875 ,723.9068603515625 ,706.8468627929688 ,706.8468627929688 ,652.3643798828125 ,673.703857421875 ,673.703857421875 ,652.3643798828125 ,693.88330078125 ,-133.48570251464844 ,-133.1193084716797 ,-137.036376953125 ,787.6688232421875 ,771.5061645507812 ,778.3762817382812 ,1637.0882568359375 ,1637.7437744140625 ,1632.5113525390625 ,1613.9197998046875 ,1646.99853515625 ,1641.5775146484375 ,1543.3221435546875 ,1609.0736083984375 ,1563.18798828125 ,1451.8507080078125 ,1580.21044921875 ,1505.4681396484375 ,1605.6170654296875 ,1600.896484375 ,1605.1339111328125 ,1370.767333984375 ,1382.652587890625 ,1422.00341796875 ,1685.1622314453125 ,1686.605712890625 ,1686.7301025390625 ,-130.52609252929688 ,-129.86874389648438 ,-114.62600708007812 ,-130.52609252929688 ,-142.89480590820312 ,-129.86874389648438 ,-129.86874389648438 ,-136.4071044921875 ,-114.62600708007812 ,-129.86874389648438 ,-142.89480590820312 ,-136.4071044921875 ,1685.16943359375 ,1684.72509765625 ,1684.0565185546875 ,740.9560546875 ,747.0787353515625 ,765.1046752929688 ,1385.2088623046875 ,1376.0538330078125 ,1404.30029296875 ,1385.2088623046875 ,1404.30029296875 ,1405.2806396484375 ,1615.4534912109375 ,1611.3134765625 ,1602.724365234375 ,1611.3134765625 ,1598.9300537109375 ,1602.724365234375 ,1611.3134765625 ,1615.4534912109375 ,1618.9720458984375 ,756.6593627929688 ,454.2554016113281 ,676.4495849609375 ,770.588134765625 ,781.025146484375 ,780.8228759765625 ,1604.0233154296875 ,1606.028076171875 ,1603.0877685546875 ,1541.7872314453125 ,1546.934814453125 ,1545.1953125 ,1545.1953125 ,1546.934814453125 ,1552.5557861328125 ,1522.60986328125 ,1519.374267578125 ,1552.476318359375 ,818.9583740234375 ,834.166015625 ,822.809326171875 ,1644.4151611328125 ,1648.9373779296875 ,1644.5009765625 ,1657.52294921875 ,1653.9622802734375 ,1660.89501953125 ,1657.52294921875 ,1653.1845703125 ,1653.9622802734375 ,1657.52294921875 ,1660.89501953125 ,1664.970703125 ,1674.104736328125 ,1671.6033935546875 ,1672.58154296875 ,1674.104736328125 ,1672.58154296875 ,1675.241943359375 ,723.9068603515625 ,717.6968383789062 ,706.3660278320312 ,-150.2718048095703 ,-153.2115020751953 ,-155.69383239746094 ,793.1922607421875 ,795.3846435546875 ,785.9707641601562 ,891.99853515625 ,918.0545654296875 ,957.0482788085938 ,891.99853515625 ,755.9078369140625 ,918.0545654296875 ,891.99853515625 ,957.0482788085938 ,881.7615966796875 ,1574.923828125 ,1584.0416259765625 ,1596.00439453125 ,84.98744201660156 ,68.51032257080078 ,84.34304809570312 ,184.67359924316406 ,153.8966064453125 ,162.37506103515625 ,1633.53369140625 ,1610.5791015625 ,1637.6385498046875 ,1610.5791015625 ,1627.56640625 ,1637.6385498046875 ,1556.6285400390625 ,1558.1773681640625 ,1556.0794677734375 ,1556.6285400390625 ,1560.1588134765625 ,1558.1773681640625 ,1558.1773681640625 ,1556.60546875 ,1556.0794677734375 ,1558.1773681640625 ,1560.1588134765625 ,1556.784423828125 ,1558.1773681640625 ,1556.784423828125 ,1556.60546875 ,1556.0794677734375 ,1556.60546875 ,1554.2913818359375 ,-170.8797149658203 ,-172.18809509277344 ,-173.44215393066406 ,225.9130401611328 ,155.5832977294922 ,167.67335510253906 ,1482.5047607421875 ,1476.919677734375 ,1467.2125244140625 ,1467.2125244140625 ,1408.2325439453125 ,1475.4910888671875 ,1467.2125244140625 ,1475.4910888671875 ,1482.5047607421875 ,1676.1666259765625 ,1675.3109130859375 ,1672.58154296875 ,1676.1666259765625 ,1679.3565673828125 ,1679.0426025390625 ,1676.1666259765625 ,1679.0426025390625 ,1675.3109130859375 ,1022.6570434570312 ,1007.3656616210938 ,968.173828125 ,968.173828125 ,1007.3656616210938 ,1014.3856811523438 ,968.173828125 ,1014.3856811523438 ,967.2301635742188 ,1686.7301025390625 ,1681.7762451171875 ,1685.1622314453125 ,1070.3936767578125 ,1149.0843505859375 ,1079.9857177734375 ,1623.7159423828125 ,1607.47314453125 ,1628.96435546875 ,1568.649169921875 ,1581.63818359375 ,1578.0010986328125 ,1568.649169921875 ,1580.116943359375 ,1581.63818359375 ,1670.2049560546875 ,1671.58349609375 ,1665.4600830078125 ,1670.2049560546875 ,1667.689453125 ,1680.966064453125 ,1670.2049560546875 ,1665.4600830078125 ,1667.689453125 ,-123.2637939453125 ,-97.0417709350586 ,-87.2468490600586 ,-123.2637939453125 ,-87.2468490600586 ,-135.68988037109375 ,770.282470703125 ,765.1046752929688 ,747.0787353515625 ,1637.3267822265625 ,1645.9932861328125 ,1638.5103759765625 ,-166.96328735351562 ,-166.50289916992188 ,-168.22259521484375 ,1641.736083984375 ,1591.122802734375 ,1613.2799072265625 ,1647.197021484375 ,1639.365234375 ,1637.0882568359375 ,-109.54987335205078 ,-107.85643768310547 ,-110.28050994873047 ,-109.54987335205078 ,-110.28050994873047 ,-103.55646514892578 ,-109.54987335205078 ,-103.55646514892578 ,-110.80560302734375 ,40.29792022705078 ,70.74286651611328 ,74.84351348876953 ,-137.67189025878906 ,-143.0941925048828 ,-139.70440673828125 ,1614.540771484375 ,1613.7200927734375 ,1614.55859375 ,1614.540771484375 ,1614.55859375 ,1622.7889404296875 ,772.7360229492188 ,668.2542114257812 ,804.1401977539062 ,-142.54470825195312 ,-142.1386260986328 ,-140.01162719726562 ,-142.54470825195312 ,-149.0703582763672 ,-142.1386260986328 ,1581.471435546875 ,1570.3974609375 ,1575.79345703125 ,1581.471435546875 ,1575.79345703125 ,1584.786865234375 ,1581.471435546875 ,1584.786865234375 ,1609.0736083984375 ,803.208251953125 ,795.6617431640625 ,799.779541015625 ,1635.490478515625 ,1653.017822265625 ,1618.220947265625 ,1635.490478515625 ,1629.330810546875 ,1653.017822265625 ,1689.8233642578125 ,1690.818603515625 ,1691.309814453125 ,753.95947265625 ,772.115966796875 ,751.0639038085938 ,1239.4842529296875 ,1315.80810546875 ,1282.9049072265625 ,1239.4842529296875 ,1272.394287109375 ,1154.680419921875 ,-97.81755828857422 ,-90.16954040527344 ,-90.04814910888672 ,803.837158203125 ,831.5402221679688 ,833.7054443359375 ,32.23271942138672 ,-19.886470794677734 ,-176.13626098632812 ,32.23271942138672 ,-158.48971557617188 ,-109.40483856201172 ,32.23271942138672 ,-176.13626098632812 ,-158.48971557617188 ,696.59814453125 ,618.6279907226562 ,721.9412841796875 ,1595.2818603515625 ,1616.805419921875 ,1584.786865234375 ,-174.0264892578125 ,-169.80703735351562 ,-106.60688781738281 ,-174.0264892578125 ,-154.95399475097656 ,-169.80703735351562 ,1633.53173828125 ,1622.50927734375 ,1636.100341796875 ,157.5376434326172 ,171.44357299804688 ,142.91012573242188 ,1564.7724609375 ,1577.078125 ,1573.859619140625 ,1667.523681640625 ,1667.3428955078125 ,1668.1595458984375 ,688.91357421875 ,689.94873046875 ,746.0133056640625 ,688.91357421875 ,746.0133056640625 ,753.7611083984375 ,1664.063232421875 ,1673.271484375 ,1668.54248046875 ,778.2691650390625 ,773.9310302734375 ,775.0728759765625 ,2316.001708984375 ,1562.002685546875 ,1606.1458740234375 ,1549.762451171875 ,1494.3138427734375 ,1444.950927734375 ,1556.60546875 ,1554.8896484375 ,1556.1182861328125 ,1657.0269775390625 ,1662.08154296875 ,1649.9718017578125 ,706.8468627929688 ,626.4420776367188 ,652.3643798828125 ,1651.705078125 ,1643.6181640625 ,1645.4742431640625 ,1645.4742431640625 ,1643.6181640625 ,1644.28955078125 ,1645.4742431640625 ,1650.6107177734375 ,1651.705078125 ,842.6087646484375 ,840.743408203125 ,852.4590454101562 ,796.2474975585938 ,795.3846435546875 ,793.1922607421875 ,1672.923583984375 ,1669.6181640625 ,1670.61572265625 ,1581.4888916015625 ,1574.271484375 ,1569.2679443359375 ,1650.4656982421875 ,1648.6241455078125 ,1647.802978515625 ,1643.3873291015625 ,1686.7740478515625 ,1639.727294921875 ,-141.19369506835938 ,-113.69429779052734 ,-119.19314575195312 ,1661.43212890625 ,1653.9564208984375 ,1653.62744140625 ,1661.43212890625 ,1653.62744140625 ,1659.3984375 ,1661.43212890625 ,1653.6058349609375 ,1653.9564208984375 ,1658.7738037109375 ,1659.1036376953125 ,1664.8953857421875 ,-162.89971923828125 ,-167.836669921875 ,-158.23422241210938 ,1601.7562255859375 ,1604.458251953125 ,1604.3963623046875 ,1664.859130859375 ,1671.6033935546875 ,1674.104736328125 ,1462.50830078125 ,1464.3046875 ,1548.0048828125 ,891.51708984375 ,1043.316162109375 ,1065.2171630859375 ,1599.11962890625 ,1597.9581298828125 ,1598.4822998046875 ,816.6506958007812 ,806.130859375 ,804.38037109375 ,816.6506958007812 ,804.38037109375 ,815.479248046875 ,1655.0233154296875 ,1667.689453125 ,1656.337158203125 ,1394.346435546875 ,1431.1864013671875 ,1358.700927734375 ,768.367431640625 ,740.9560546875 ,763.2747192382812 ,1093.7362060546875 ,1173.3082275390625 ,1079.8157958984375 ,1093.7362060546875 ,1151.1861572265625 ,1173.3082275390625 ,1173.3082275390625 ,1272.394287109375 ,1079.8157958984375 ,840.1530151367188 ,816.0027465820312 ,808.4400634765625 ,965.6051025390625 ,1011.173583984375 ,1012.0601196289062 ,1602.2880859375 ,1604.5452880859375 ,1601.2574462890625 ,-154.72377014160156 ,-149.0703582763672 ,-165.09109497070312 ,-165.09109497070312 ,-159.94921875 ,-154.72377014160156 ,1744.6837158203125 ,1734.58935546875 ,1760.213623046875 ,1598.0146484375 ,1597.8408203125 ,1595.5892333984375 ,1348.49267578125 ,1448.8497314453125 ,1403.7037353515625 ,1010.2650756835938 ,1010.923828125 ,992.80419921875 ,845.933349609375 ,840.1530151367188 ,840.743408203125 ,1650.775146484375 ,1652.046875 ,1647.745361328125 ,1652.046875 ,1650.5787353515625 ,1647.745361328125 ,1652.046875 ,1659.263916015625 ,1650.5787353515625 ,1546.939697265625 ,1553.118896484375 ,1537.7679443359375 ,1622.3206787109375 ,1620.9952392578125 ,1635.9215087890625 ,1595.7293701171875 ,1623.0599365234375 ,1446.096435546875 ,1595.7293701171875 ,1446.096435546875 ,1412.957763671875 ,1599.64599609375 ,1600.896484375 ,1601.1868896484375 ,-157.58616638183594 ,-158.7922821044922 ,-158.0950469970703 ,-157.58616638183594 ,-154.53662109375 ,-158.7922821044922 ,1651.2080078125 ,1645.4649658203125 ,1632.63623046875 ,1552.7763671875 ,1561.940673828125 ,1547.5770263671875 ,-93.44713592529297 ,-95.44017791748047 ,-93.75316619873047 ,-93.44713592529297 ,-94.87836456298828 ,-95.44017791748047 ,36.17856216430664 ,-33.623085021972656 ,1.143841028213501 ,36.17856216430664 ,1.143841028213501 ,87.79638671875 ,1123.979736328125 ,1146.6402587890625 ,957.6220092773438 ,1417.4075927734375 ,1406.17626953125 ,1409.03564453125 ,-154.72377014160156 ,-154.27488708496094 ,-140.9107666015625 ,-154.72377014160156 ,-140.9107666015625 ,-142.1386260986328 ,-140.9107666015625 ,-138.11166381835938 ,-139.8701171875 ,-140.9107666015625 ,-139.8701171875 ,-142.1386260986328 ,771.5061645507812 ,778.3938598632812 ,778.3762817382812 ,847.0896606445312 ,822.512939453125 ,979.4857177734375 ,-224.1885223388672 ,-265.82415771484375 ,-206.4029083251953 ,57.19397735595703 ,-43.334495544433594 ,-84.93722534179688 ,57.19397735595703 ,38.04579162597656 ,-43.334495544433594 ,1626.9364013671875 ,1622.3206787109375 ,1640.7991943359375 ,767.950927734375 ,748.1673583984375 ,769.674072265625 ,767.950927734375 ,769.674072265625 ,790.1903686523438 ,1547.5792236328125 ,1544.0389404296875 ,1552.570556640625 ,961.9600830078125 ,1061.1845703125 ,1309.4805908203125 ,1601.2574462890625 ,1604.5452880859375 ,1602.7296142578125 ,1629.9200439453125 ,1635.9215087890625 ,1620.9952392578125 ,1575.0830078125 ,1589.19580078125 ,1606.625 ,1673.271484375 ,1681.7762451171875 ,1668.54248046875 ,1635.9215087890625 ,1629.9200439453125 ,1632.61962890625 ,760.6171875 ,776.2487182617188 ,764.6854248046875 ,722.618408203125 ,706.0634765625 ,699.9414672851562 ,-107.85643768310547 ,-110.93496704101562 ,-110.28050994873047 ,1642.762939453125 ,1630.4520263671875 ,1636.814453125 ,1642.762939453125 ,1636.814453125 ,1648.3623046875 ,1642.762939453125 ,1635.171875 ,1630.4520263671875 ,1630.4520263671875 ,1635.171875 ,1621.4744873046875 ,1630.4520263671875 ,1626.8748779296875 ,1636.814453125 ,1630.4520263671875 ,1607.47314453125 ,1626.8748779296875 ,1630.4520263671875 ,1621.4744873046875 ,1607.47314453125 ,1636.814453125 ,1626.8748779296875 ,1648.3623046875 ,1640.1123046875 ,1638.4283447265625 ,1633.0225830078125 ,1640.1123046875 ,1639.517333984375 ,1638.4283447265625 ,1588.3834228515625 ,1569.2679443359375 ,1582.832275390625 ,918.0545654296875 ,755.9078369140625 ,908.4688720703125 ,-103.55646514892578 ,-104.18303680419922 ,-110.80560302734375 ,1672.82763671875 ,1662.9674072265625 ,1668.54248046875 ,1602.9510498046875 ,1614.930419921875 ,1602.724365234375 ,1565.7703857421875 ,1553.118896484375 ,1563.897216796875 ,1565.7703857421875 ,1546.7625732421875 ,1553.118896484375 ,130.1804656982422 ,141.63189697265625 ,152.2653350830078 ,130.1804656982422 ,73.47518157958984 ,141.63189697265625 ,-288.77471923828125 ,-17.97229766845703 ,-195.4857635498047 ,961.9600830078125 ,893.1461791992188 ,1061.1845703125 ,1597.8408203125 ,1604.0574951171875 ,1591.385986328125 ,957.6220092773438 ,620.417236328125 ,561.8804931640625 ,1760.213623046875 ,1782.79150390625 ,1880.57177734375 ,1626.4022216796875 ,1600.966552734375 ,1592.3297119140625 ,750.1624145507812 ,747.9818115234375 ,387.1172790527344 ,1640.44482421875 ,1634.977783203125 ,1630.4327392578125 ,854.4637451171875 ,865.2728881835938 ,896.8179321289062 ,1560.1588134765625 ,1564.443359375 ,1556.784423828125 ,1560.1588134765625 ,1566.70947265625 ,1564.443359375 ,1577.2099609375 ,1574.43994140625 ,1571.789794921875 ,1561.6275634765625 ,1563.8697509765625 ,1562.057861328125 ,1563.8697509765625 ,1564.533203125 ,1562.057861328125 ,1595.722412109375 ,1599.012451171875 ,1594.6051025390625 ,1043.316162109375 ,891.51708984375 ,833.7752075195312 ,1694.167724609375 ,1695.0233154296875 ,1684.030029296875 ,1694.167724609375 ,1684.030029296875 ,1678.83642578125 ,1557.3426513671875 ,1568.0350341796875 ,1564.0540771484375 ,1653.017822265625 ,1665.584716796875 ,1650.9715576171875 ,1571.35205078125 ,1571.0238037109375 ,1574.9583740234375 ,1676.799072265625 ,1674.104736328125 ,1676.2178955078125 ,1676.799072265625 ,1674.09033203125 ,1674.104736328125 ,809.3734130859375 ,819.2005615234375 ,822.8524780273438 ,-142.8347930908203 ,-140.21238708496094 ,-137.97515869140625 ,852.0985717773438 ,822.8524780273438 ,819.2005615234375 ,1687.4100341796875 ,1685.5765380859375 ,1686.009765625 ,1687.4100341796875 ,1686.009765625 ,1685.6358642578125 ,1681.7762451171875 ,1682.1060791015625 ,1685.1622314453125 ,-297.5017395019531 ,-295.60565185546875 ,-311.4500732421875 ,-311.4500732421875 ,-295.60565185546875 ,-275.2289733886719 ,-311.4500732421875 ,-396.90313720703125 ,-297.5017395019531 ,-311.4500732421875 ,-275.2289733886719 ,-396.90313720703125 ,-49.69411087036133 ,-56.86187744140625 ,-86.79059600830078 ,1654.4324951171875 ,1653.8194580078125 ,1651.813232421875 ,1589.70556640625 ,1592.0350341796875 ,1587.4739990234375 ,1690.0823974609375 ,1688.9842529296875 ,1690.7293701171875 ,1580.7481689453125 ,1583.322509765625 ,1592.0440673828125 ,1579.588134765625 ,1523.4749755859375 ,1684.946044921875 ,1681.7762451171875 ,1682.081298828125 ,1672.82763671875 ,1391.6668701171875 ,1376.0538330078125 ,1355.326171875 ,1574.271484375 ,1559.9676513671875 ,1569.2679443359375 ,690.8013305664062 ,657.6510620117188 ,608.802734375 ,818.6195068359375 ,795.92529296875 ,825.994140625 ,1406.46630859375 ,1391.6668701171875 ,1349.7996826171875 ,1682.1451416015625 ,1680.966064453125 ,1667.689453125 ,1667.689453125 ,1660.8375244140625 ,1656.337158203125 ,1597.7860107421875 ,1596.21337890625 ,1597.0556640625 ,1597.7860107421875 ,1597.0556640625 ,1597.5272216796875 ,1597.7860107421875 ,1597.5272216796875 ,1597.9208984375 ,1659.6895751953125 ,1660.89501953125 ,1653.9622802734375 ,1659.6895751953125 ,1653.9622802734375 ,1632.160400390625 ,1653.9622802734375 ,1653.1845703125 ,1632.160400390625 ,793.496337890625 ,784.9931640625 ,784.7041015625 ,1646.39453125 ,1640.7991943359375 ,1650.5787353515625 ,1646.39453125 ,1650.5787353515625 ,1657.4427490234375 ,1646.39453125 ,1657.4427490234375 ,1651.5751953125 ,1570.3974609375 ,1560.2115478515625 ,1575.79345703125 ,1585.777099609375 ,1593.8929443359375 ,1588.4100341796875 ,1589.718017578125 ,1566.9979248046875 ,1538.6708984375 ,768.367431640625 ,772.416748046875 ,740.9560546875 ,831.5402221679688 ,829.766357421875 ,833.7054443359375 ,1567.3592529296875 ,1566.546630859375 ,1559.339111328125 ,-95.44017791748047 ,-94.87836456298828 ,-102.25055694580078 ,-102.25055694580078 ,-94.87836456298828 ,-93.32140350341797 ,699.9414672851562 ,706.0634765625 ,694.0750732421875 ,706.0634765625 ,717.0455322265625 ,694.0750732421875 ,785.9707641601562 ,792.85107421875 ,783.1329956054688 ,795.55419921875 ,806.5706176757812 ,793.5814208984375 ,795.55419921875 ,804.3980712890625 ,806.5706176757812 ,1649.2877197265625 ,1635.4149169921875 ,1690.1962890625 ,1649.2877197265625 ,1692.1318359375 ,1635.4149169921875 ,846.8115844726562 ,847.5123291015625 ,844.23388671875 ,865.5841674804688 ,844.23388671875 ,859.1519165039062 ,789.9561767578125 ,776.2487182617188 ,781.0104370117188 ,-107.67842864990234 ,-98.61483764648438 ,-103.92625427246094 ,1589.9910888671875 ,1593.12060546875 ,1604.80224609375 ,1589.9910888671875 ,1604.80224609375 ,1595.1080322265625 ,784.7091674804688 ,794.844482421875 ,793.1922607421875 ,1659.9517822265625 ,1660.1500244140625 ,1662.020263671875 ,1659.9517822265625 ,1654.10693359375 ,1655.9959716796875 ,1659.9517822265625 ,1662.020263671875 ,1654.10693359375 ,1655.9959716796875 ,1654.10693359375 ,1654.172607421875 ,1655.774658203125 ,1650.4656982421875 ,1656.624755859375 ,1637.099853515625 ,1637.38037109375 ,1646.9783935546875 ,1591.043701171875 ,1606.625 ,1589.19580078125 ,1650.775146484375 ,1647.745361328125 ,1644.5009765625 ,1650.775146484375 ,1644.5009765625 ,1648.9373779296875 ,746.0133056640625 ,689.94873046875 ,715.9713134765625 ,689.94873046875 ,618.6279907226562 ,656.5256958007812 ,689.94873046875 ,656.5256958007812 ,715.9713134765625 ,1644.015625 ,1652.3216552734375 ,1652.356201171875 ,694.0750732421875 ,717.0455322265625 ,704.5260009765625 ,1422.00341796875 ,1467.2125244140625 ,1455.5369873046875 ,1422.00341796875 ,1455.5369873046875 ,1476.919677734375 ,777.9039916992188 ,814.373046875 ,865.3997802734375 ,866.9893798828125 ,826.8889770507812 ,718.9926147460938 ,1670.61572265625 ,1669.6181640625 ,1664.5697021484375 ,1670.61572265625 ,1664.5697021484375 ,1662.0677490234375 ,1562.0313720703125 ,1556.96240234375 ,1565.5657958984375 ,1640.7991943359375 ,1622.3206787109375 ,1635.9215087890625 ,1681.4715576171875 ,1683.33642578125 ,1683.5225830078125 ,1607.47314453125 ,1621.4744873046875 ,1635.171875 ,1093.7362060546875 ,1104.0047607421875 ,1151.1861572265625 ,1151.1861572265625 ,1272.394287109375 ,1173.3082275390625 ,704.5260009765625 ,696.7554931640625 ,694.0750732421875 ,1606.330322265625 ,1608.087646484375 ,1611.4110107421875 ,769.674072265625 ,754.551025390625 ,790.1903686523438 ,769.674072265625 ,748.1673583984375 ,754.551025390625 ,719.7808227539062 ,798.5071411132812 ,757.3011474609375 ,719.7808227539062 ,723.6242065429688 ,713.3721923828125 ,1554.1483154296875 ,1550.7193603515625 ,1553.8087158203125 ,1596.0208740234375 ,1607.8009033203125 ,1604.0233154296875 ,1669.6590576171875 ,1670.5738525390625 ,1670.9056396484375 ,1669.6590576171875 ,1669.1170654296875 ,1670.5738525390625 ,1669.6590576171875 ,1670.9056396484375 ,1667.6202392578125 ,840.7582397460938 ,816.0027465820312 ,840.1530151367188 ,-88.02678680419922 ,-37.357818603515625 ,-28.75667381286621 ,1620.97802734375 ,1585.0457763671875 ,1595.8602294921875 ,1594.8846435546875 ,1591.385986328125 ,1604.0574951171875 ,1211.4088134765625 ,1264.9102783203125 ,1242.9195556640625 ,-155.86891174316406 ,-154.16233825683594 ,-150.98208618164062 ,-150.98208618164062 ,-149.1376953125 ,-149.96043395996094 ,1536.750244140625 ,1299.4256591796875 ,1230.4781494140625 ,1672.285888671875 ,1666.635498046875 ,1672.3841552734375 ,836.5758666992188 ,862.8421630859375 ,843.5925903320312 ,836.5758666992188 ,862.65185546875 ,862.8421630859375 ,836.5758666992188 ,843.5925903320312 ,816.103271484375 ,1614.86376953125 ,1635.4149169921875 ,1692.1318359375 ,1614.86376953125 ,1692.1318359375 ,1595.8814697265625 ,1146.6402587890625 ,1240.89453125 ,1094.449462890625 ,1563.536865234375 ,1541.4324951171875 ,1561.707763671875 ,1629.330810546875 ,1633.53173828125 ,1649.50341796875 ,1637.0882568359375 ,1639.365234375 ,1639.7213134765625 ,1662.99072265625 ,1654.254150390625 ,1664.3409423828125 ,-103.55646514892578 ,-98.6882095336914 ,-102.38587188720703 ,-103.55646514892578 ,-96.60274505615234 ,-98.6882095336914 ,-103.55646514892578 ,-100.40309143066406 ,-96.60274505615234 ,1693.0804443359375 ,1693.468017578125 ,1692.35009765625 ,1680.6246337890625 ,1680.0238037109375 ,1680.0179443359375 ,-146.486328125 ,-147.45188903808594 ,-147.3275604248047 ,-152.03746032714844 ,-151.143798828125 ,-153.84323120117188 ,819.1377563476562 ,835.6561889648438 ,817.1439819335938 ,819.1377563476562 ,822.2063598632812 ,835.6561889648438 ,819.1377563476562 ,816.6506958007812 ,822.2063598632812 ,817.1439819335938 ,804.2484741210938 ,819.1377563476562 ,1543.3046875 ,2294.779296875 ,1588.199462890625 ,1543.3046875 ,1536.750244140625 ,2294.779296875 ,758.327880859375 ,732.3037109375 ,732.1451416015625 ,143.64382934570312 ,148.8214874267578 ,81.85975646972656 ,1680.6246337890625 ,1680.9556884765625 ,1682.3333740234375 ,1151.1861572265625 ,1154.680419921875 ,1272.394287109375 ,1151.1861572265625 ,1104.0047607421875 ,1131.2088623046875 ,1476.919677734375 ,1455.5369873046875 ,1467.2125244140625 ,-114.91108703613281 ,-61.866416931152344 ,-76.51492309570312 ,1641.852294921875 ,1638.4283447265625 ,1642.7744140625 ,1556.60546875 ,1556.1182861328125 ,1554.2913818359375 ,1572.6234130859375 ,1590.896484375 ,1571.789794921875 ,778.3762817382812 ,746.5462036132812 ,758.327880859375 ,775.156005859375 ,764.6854248046875 ,776.2487182617188 ,775.156005859375 ,786.3716430664062 ,764.6854248046875 ,248.44900512695312 ,87.79638671875 ,320.3096618652344 ,1627.878662109375 ,1608.282958984375 ,1617.68212890625 ,-107.85643768310547 ,-103.92625427246094 ,-98.61483764648438 ,-98.61483764648438 ,-110.93496704101562 ,-107.85643768310547 ,-103.92625427246094 ,-107.85643768310547 ,-109.54987335205078 ,945.8577880859375 ,1006.5462646484375 ,1042.39111328125 ,1299.4256591796875 ,1179.5418701171875 ,1230.4781494140625 ,1635.171875 ,1642.762939453125 ,1610.5791015625 ,1642.762939453125 ,1634.8624267578125 ,1610.5791015625 ,-103.25717163085938 ,-130.15724182128906 ,-131.45046997070312 ,-103.25717163085938 ,-131.45046997070312 ,-131.21571350097656 ,1686.0943603515625 ,1683.382080078125 ,1687.61474609375 ,1686.0943603515625 ,1687.61474609375 ,1687.1873779296875 ,-113.69429779052734 ,-110.93496704101562 ,-98.61483764648438 ,-113.69429779052734 ,-98.61483764648438 ,-88.27867126464844 ,-113.69429779052734 ,-88.27867126464844 ,-119.19314575195312 ,1043.316162109375 ,1312.385986328125 ,1065.2171630859375 ,1467.2125244140625 ,1422.00341796875 ,1408.2325439453125 ,880.638427734375 ,868.5808715820312 ,875.56201171875 ,1639.365234375 ,1637.3267822265625 ,1639.7213134765625 ,1564.2630615234375 ,1594.0908203125 ,1593.8599853515625 ,1564.2630615234375 ,1588.4100341796875 ,1594.0908203125 ,1609.0736083984375 ,1584.786865234375 ,1616.805419921875 ,1633.53369140625 ,1633.0850830078125 ,1632.4642333984375 ,51.839210510253906 ,68.86013793945312 ,55.008338928222656 ,948.989013671875 ,967.2301635742188 ,930.5149536132812 ,1022.5490112304688 ,1094.449462890625 ,1129.8260498046875 ,1022.5490112304688 ,1129.8260498046875 ,1008.1751708984375 ,1008.1751708984375 ,1129.8260498046875 ,1237.4595947265625 ,-86.79059600830078 ,-56.86187744140625 ,-121.91429901123047 ,68.51032257080078 ,64.75064849853516 ,84.34304809570312 ,-130.08799743652344 ,-124.44517517089844 ,-133.1193084716797 ,-133.1193084716797 ,-124.44517517089844 ,-132.05003356933594 ,1382.652587890625 ,1408.2325439453125 ,1422.00341796875 ,1639.727294921875 ,1685.72265625 ,1669.949462890625 ,1639.727294921875 ,1620.97802734375 ,1595.8602294921875 ,1639.727294921875 ,1669.949462890625 ,1620.97802734375 ,1692.50048828125 ,1693.083984375 ,1691.2550048828125 ,1692.50048828125 ,1691.2550048828125 ,1691.4814453125 ,1691.4814453125 ,1690.3802490234375 ,1692.50048828125 ,1691.4814453125 ,1691.2550048828125 ,1690.935791015625 ,1691.4814453125 ,1690.935791015625 ,1690.3802490234375 ,1692.50048828125 ,1692.54150390625 ,1692.796630859375 ,1692.50048828125 ,1690.3802490234375 ,1692.54150390625 ,1554.7178955078125 ,1534.306884765625 ,1506.52294921875 ,1597.7860107421875 ,1597.9208984375 ,1599.64599609375 ,1000.3975830078125 ,945.8577880859375 ,967.2301635742188 ,1000.3975830078125 ,967.2301635742188 ,1014.3856811523438 ,811.11669921875 ,806.5247192382812 ,823.284912109375 ,-8.9946870803833 ,6.620456218719482 ,-64.44239044189453 ,875.2785034179688 ,890.9190673828125 ,884.965576171875 ,1688.9609375 ,1688.41552734375 ,1689.4713134765625 ,988.9864501953125 ,965.7979125976562 ,831.5140991210938 ,1665.4600830078125 ,1660.8375244140625 ,1667.689453125 ,1052.5938720703125 ,1042.39111328125 ,1006.5462646484375 ,1578.3837890625 ,1592.3297119140625 ,1580.6671142578125 ,1578.3837890625 ,1555.0257568359375 ,1592.3297119140625 ,1580.6671142578125 ,1592.3297119140625 ,1585.2662353515625 ,1580.6671142578125 ,1597.1463623046875 ,1578.3837890625 ,1580.6671142578125 ,1592.7901611328125 ,1597.1463623046875 ,1580.6671142578125 ,1585.2662353515625 ,1592.7901611328125 ,1669.6060791015625 ,1678.89990234375 ,1665.25 ,1469.92626953125 ,1643.9481201171875 ,2080.4912109375 ,1643.9481201171875 ,2016.6395263671875 ,2080.4912109375 ,1589.6539306640625 ,1556.5546875 ,1586.283935546875 ,1123.282470703125 ,1104.0047607421875 ,1103.5130615234375 ,1123.282470703125 ,1131.2088623046875 ,1104.0047607421875 ,1123.282470703125 ,1151.1861572265625 ,1131.2088623046875 ,1103.5130615234375 ,1079.087646484375 ,1123.282470703125 ,1103.5130615234375 ,1104.0047607421875 ,1079.087646484375 ,-63.73884963989258 ,-49.75644302368164 ,-60.050437927246094 ,-63.73884963989258 ,-56.8443603515625 ,-49.75644302368164 ,1608.5009765625 ,1623.8583984375 ,1608.689697265625 ,798.400390625 ,792.5782470703125 ,793.496337890625 ,1636.365966796875 ,1627.878662109375 ,1643.3203125 ,-162.89971923828125 ,-148.42178344726562 ,-160.1863555908203 ,-162.89971923828125 ,-158.23422241210938 ,-148.42178344726562 ,-160.1863555908203 ,-148.42178344726562 ,-149.68702697753906 ,806.5706176757812 ,804.3980712890625 ,816.3965454101562 ,1679.5113525390625 ,1681.4793701171875 ,1671.78515625 ,1597.9581298828125 ,1598.7205810546875 ,1600.48583984375 ,1664.5697021484375 ,1652.9178466796875 ,1662.0677490234375 ,1645.921630859375 ,1643.0020751953125 ,1645.1719970703125 ,1598.824462890625 ,1596.295654296875 ,1589.3944091796875 ,1598.824462890625 ,1589.3944091796875 ,1599.285400390625 ,1601.1868896484375 ,1602.9510498046875 ,1599.64599609375 ,691.135009765625 ,692.4459838867188 ,709.1033325195312 ,691.135009765625 ,694.0750732421875 ,692.4459838867188 ,709.1033325195312 ,692.4459838867188 ,704.5575561523438 ,1564.0540771484375 ,1568.0350341796875 ,1566.099365234375 ,1568.0350341796875 ,1572.1949462890625 ,1566.099365234375 ,1600.896484375 ,1597.9208984375 ,1600.8250732421875 ,1600.896484375 ,1599.64599609375 ,1597.9208984375 ,846.4479370117188 ,750.1624145507812 ,843.5925903320312 ,1693.083984375 ,1692.796630859375 ,1692.54150390625 ,157.475830078125 ,153.8966064453125 ,162.90782165527344 ,157.475830078125 ,157.5376434326172 ,153.8966064453125 ,-131.700927734375 ,-149.50289916992188 ,-142.57838439941406 ,-131.700927734375 ,-141.19369506835938 ,-149.50289916992188 ,1043.316162109375 ,833.7752075195312 ,939.5186767578125 ,1258.8929443359375 ,1094.449462890625 ,1282.806396484375 ,1258.8929443359375 ,1282.806396484375 ,1340.64990234375 ,1670.5738525390625 ,1672.3447265625 ,1673.2105712890625 ,1554.757080078125 ,1552.0093994140625 ,1554.8896484375 ,1648.9971923828125 ,1654.421142578125 ,1645.8345947265625 ,1675.984375 ,1679.267333984375 ,1678.8447265625 ,1667.6173095703125 ,1669.1170654296875 ,1667.3428955078125 ,822.809326171875 ,790.0026245117188 ,818.9583740234375 ,-117.45018768310547 ,-115.28341674804688 ,-129.64761352539062 ,248.44900512695312 ,320.3096618652344 ,341.78338623046875 ,1598.4822998046875 ,1599.012451171875 ,1599.4454345703125 ,1686.605712890625 ,1682.1060791015625 ,1686.7393798828125 ,1685.358154296875 ,1686.6390380859375 ,1686.605712890625 ,1690.1962890625 ,1635.4149169921875 ,1718.588134765625 ,1679.3565673828125 ,1680.9556884765625 ,1679.0426025390625 ,-68.52424621582031 ,-67.98887634277344 ,-65.2342300415039 ,-68.52424621582031 ,-78.44538116455078 ,-67.98887634277344 ,-68.52424621582031 ,-74.24273681640625 ,-78.44538116455078 ,785.389404296875 ,783.3544921875 ,772.115966796875 ,1661.6192626953125 ,1675.4527587890625 ,1676.0706787109375 ,1661.6192626953125 ,1676.0706787109375 ,1669.516845703125 ,843.6236572265625 ,822.809326171875 ,843.2396240234375 ,-51.333580017089844 ,-46.14818572998047 ,-43.43236541748047 ,-51.333580017089844 ,-52.834678649902344 ,-46.14818572998047 ,790.1903686523438 ,754.551025390625 ,772.416748046875 ,790.1903686523438 ,772.416748046875 ,782.3931274414062 ,74.84351348876953 ,70.74286651611328 ,70.07876586914062 ,70.07876586914062 ,70.74286651611328 ,58.55487060546875 ,1685.785888671875 ,1686.7301025390625 ,1686.0958251953125 ,626.051025390625 ,673.9083251953125 ,570.5579223632812 ,1639.492919921875 ,1623.536376953125 ,1631.2967529296875 ,1595.2255859375 ,1587.8623046875 ,1601.3533935546875 ,908.4688720703125 ,1042.73974609375 ,1035.0845947265625 ,908.4688720703125 ,1035.0845947265625 ,918.0545654296875 ,1625.2537841796875 ,1642.7744140625 ,1639.517333984375 ,1625.2537841796875 ,1632.2459716796875 ,1642.7744140625 ,1087.777587890625 ,1123.282470703125 ,1079.087646484375 ,778.7622680664062 ,769.0580444335938 ,786.3716430664062 ,1675.666015625 ,1673.9615478515625 ,1675.3382568359375 ,1675.666015625 ,1670.9056396484375 ,1673.9615478515625 ,1548.2794189453125 ,1534.306884765625 ,1554.7178955078125 ,1613.71533203125 ,1600.1275634765625 ,1602.9903564453125 ,1664.719482421875 ,1648.3623046875 ,1632.3934326171875 ,867.532958984375 ,814.373046875 ,890.9190673828125 ,-36.70216751098633 ,-9.448720932006836 ,-66.08543395996094 ,1691.998779296875 ,1692.026123046875 ,1691.950927734375 ,141.63189697265625 ,151.38206481933594 ,191.36724853515625 ,1475.08251953125 ,1481.825927734375 ,1464.3046875 ,-140.01162719726562 ,-142.1386260986328 ,-139.8701171875 ,-133.311767578125 ,-66.08543395996094 ,-112.009033203125 ,162.37506103515625 ,153.8966064453125 ,157.5376434326172 ,1640.7991943359375 ,1646.39453125 ,1639.356201171875 ,-144.49041748046875 ,-145.5254364013672 ,-146.309814453125 ,1571.12646484375 ,1563.6204833984375 ,1565.846923828125 ,1642.7744140625 ,1638.4283447265625 ,1639.517333984375 ,1568.7576904296875 ,1553.41455078125 ,1556.0218505859375 ,1568.7576904296875 ,1565.846923828125 ,1553.41455078125 ,-156.95455932617188 ,-159.6973876953125 ,-164.23593139648438 ,-156.95455932617188 ,-164.23593139648438 ,-160.25048828125 ,-164.23593139648438 ,-162.89971923828125 ,-160.25048828125 ,1651.294921875 ,1650.5126953125 ,1656.624755859375 ,1651.294921875 ,1656.624755859375 ,1650.4656982421875 ,1584.3056640625 ,1585.8505859375 ,1582.79833984375 ,1584.3056640625 ,1587.611083984375 ,1585.8505859375 ,1230.4781494140625 ,1925.99853515625 ,1536.750244140625 ,1536.750244140625 ,1925.99853515625 ,2294.779296875 ,1204.0008544921875 ,1079.8157958984375 ,1272.394287109375 ,1587.4739990234375 ,1592.0350341796875 ,1588.1551513671875 ,-122.8582763671875 ,-117.57561492919922 ,-124.44517517089844 ,6.620456218719482 ,-0.03479800000786781 ,-64.44239044189453 ,6.620456218719482 ,26.925315856933594 ,-0.03479800000786781 ,1602.2880859375 ,1603.0877685546875 ,1606.028076171875 ,1606.028076171875 ,1604.5452880859375 ,1602.2880859375 ,1606.028076171875 ,1604.0233154296875 ,1604.5452880859375 ,1575.79345703125 ,1560.2115478515625 ,1554.7178955078125 ,1061.62109375 ,1142.978759765625 ,1018.4519653320312 ,1061.62109375 ,1302.64599609375 ,1142.978759765625 ,1245.7833251953125 ,1061.1845703125 ,1152.3909912109375 ,1245.7833251953125 ,1606.1458740234375 ,1562.002685546875 ,1245.7833251953125 ,1152.3909912109375 ,1606.1458740234375 ,1245.7833251953125 ,1562.002685546875 ,1061.1845703125 ,1061.1845703125 ,967.1039428710938 ,1152.3909912109375 ,1061.1845703125 ,930.623046875 ,967.1039428710938 ,1690.3802490234375 ,1690.935791015625 ,1689.559814453125 ,1690.3802490234375 ,1689.559814453125 ,1689.0537109375 ,1538.919189453125 ,1546.3587646484375 ,1537.8978271484375 ,1125.035400390625 ,1202.355224609375 ,939.5186767578125 ,1123.282470703125 ,1175.87353515625 ,1151.1861572265625 ,1587.8623046875 ,1571.12646484375 ,1577.8433837890625 ,1650.5126953125 ,1646.2232666015625 ,1649.632568359375 ,781.4766845703125 ,726.8759765625 ,797.5750122070312 ,1602.9903564453125 ,1603.9329833984375 ,1613.71533203125 ,1665.25 ,1678.89990234375 ,1669.150634765625 ,805.8684692382812 ,815.0030517578125 ,797.4121704101562 ,1801.9376220703125 ,1625.0286865234375 ,1822.6085205078125 ,1282.806396484375 ,1347.18408203125 ,1340.64990234375 ,1686.4478759765625 ,1688.1015625 ,1684.94921875 ,1902.2969970703125 ,1934.1468505859375 ,2346.43994140625 ,1647.878662109375 ,1648.9971923828125 ,1645.8345947265625 ,1647.878662109375 ,1650.792236328125 ,1648.9971923828125 ,1647.878662109375 ,1645.8345947265625 ,1640.44482421875 ,1392.0789794921875 ,1416.5341796875 ,1488.171630859375 ,1392.0789794921875 ,1365.138916015625 ,1416.5341796875 ,1392.0789794921875 ,1371.5784912109375 ,1365.138916015625 ,1686.7301025390625 ,1686.605712890625 ,1686.0958251953125 ,1488.171630859375 ,1416.5341796875 ,1487.827392578125 ,772.416748046875 ,754.551025390625 ,740.9560546875 ,1242.9195556640625 ,1315.80810546875 ,1239.4842529296875 ,833.7054443359375 ,829.766357421875 ,840.5704345703125 ,1679.489990234375 ,1734.58935546875 ,1707.3741455078125 ,1679.489990234375 ,1760.213623046875 ,1734.58935546875 ,1679.489990234375 ,1782.79150390625 ,1760.213623046875 ,-142.95718383789062 ,-137.036376953125 ,-138.2955322265625 ,-138.2955322265625 ,-137.036376953125 ,-133.1193084716797 ,1601.7646484375 ,1707.3741455078125 ,1598.2261962890625 ,1601.7646484375 ,1598.2261962890625 ,1523.4749755859375 ,781.025146484375 ,765.1046752929688 ,770.282470703125 ,1626.8748779296875 ,1609.4886474609375 ,1611.38037109375 ,1611.38037109375 ,1632.3934326171875 ,1626.8748779296875 ,1611.38037109375 ,1605.57763671875 ,1632.3934326171875 ,1626.8748779296875 ,1632.3934326171875 ,1648.3623046875 ,775.156005859375 ,786.6719970703125 ,786.3716430664062 ,1623.382568359375 ,1630.4327392578125 ,1627.1104736328125 ,731.4716186523438 ,747.8978881835938 ,739.1574096679688 ,739.1574096679688 ,747.8978881835938 ,759.187255859375 ,1563.536865234375 ,1567.1591796875 ,1541.4324951171875 ,1687.320068359375 ,1690.2166748046875 ,1690.3095703125 ,874.5257568359375 ,872.2061157226562 ,851.3971557617188 ,1140.5811767578125 ,1223.370849609375 ,1200.5262451171875 ,1592.7901611328125 ,1585.2662353515625 ,1592.3297119140625 ,1592.7901611328125 ,1600.966552734375 ,1627.7359619140625 ,1592.7901611328125 ,1592.3297119140625 ,1600.966552734375 ,1627.7359619140625 ,1600.966552734375 ,1626.4022216796875 ,1609.0880126953125 ,1652.356201171875 ,1551.97705078125 ,806.8987426757812 ,908.4688720703125 ,755.9078369140625 ,1657.659912109375 ,1660.7755126953125 ,1664.859130859375 ,1693.468017578125 ,1693.0804443359375 ,1694.043212890625 ,1590.896484375 ,1569.1812744140625 ,1571.789794921875 ,-151.7123565673828 ,-140.76263427734375 ,-143.44833374023438 ,-151.7123565673828 ,-143.44833374023438 ,-152.9228973388672 ,1664.8953857421875 ,1659.1036376953125 ,1661.6192626953125 ,723.6242065429688 ,713.6329956054688 ,713.3721923828125 ,1598.7205810546875 ,1597.9581298828125 ,1599.11962890625 ,1690.796875 ,1688.9949951171875 ,1689.8787841796875 ,1690.796875 ,1689.3079833984375 ,1688.9949951171875 ,1529.5411376953125 ,1561.707763671875 ,1541.4324951171875 ,1659.1036376953125 ,1652.7374267578125 ,1661.6192626953125 ,1687.61474609375 ,1683.382080078125 ,1683.823974609375 ,411.1473388671875 ,458.4006042480469 ,590.23095703125 ,1672.58154296875 ,1671.6033935546875 ,1671.78173828125 ,1596.295654296875 ,1585.3182373046875 ,1589.3944091796875 ,-147.45188903808594 ,-148.8948974609375 ,-147.3275604248047 ,-147.45188903808594 ,-147.2008514404297 ,-148.8948974609375 ,387.1172790527344 ,504.4600830078125 ,400.4861145019531 ,387.1172790527344 ,670.9752807617188 ,504.4600830078125 ,1687.61474609375 ,1690.2166748046875 ,1687.1873779296875 ,1408.2325439453125 ,1403.621826171875 ,1431.1864013671875 ,1408.2325439453125 ,1431.1864013671875 ,1475.4910888671875 ,1537.8978271484375 ,1546.3587646484375 ,1548.9249267578125 ,1690.700439453125 ,1679.518310546875 ,1692.29931640625 ,1654.10693359375 ,1657.24658203125 ,1650.775146484375 ,1654.10693359375 ,1662.020263671875 ,1657.24658203125 ,1681.4715576171875 ,1683.6917724609375 ,1678.9876708984375 ,806.5791015625 ,704.5260009765625 ,717.0455322265625 ,806.5791015625 ,765.2786865234375 ,704.5260009765625 ,-129.64761352539062 ,-115.28341674804688 ,-127.01480102539062 ,-208.45709228515625 ,-232.23538208007812 ,-112.88627624511719 ,1592.876953125 ,1589.9951171875 ,1596.3980712890625 ,1611.3134765625 ,1601.3255615234375 ,1598.9300537109375 ,1699.156982421875 ,1681.109130859375 ,1675.038330078125 ,1699.156982421875 ,1675.038330078125 ,1688.038818359375 ,1699.156982421875 ,1688.038818359375 ,1695.4520263671875 ,-107.82918548583984 ,-102.25055694580078 ,-96.97508239746094 ,-107.82918548583984 ,-96.97508239746094 ,-101.0987777709961 ,-107.82918548583984 ,-101.0987777709961 ,-123.86084747314453 ,1594.8846435546875 ,1604.0574951171875 ,1602.9903564453125 ,1594.8846435546875 ,1602.9903564453125 ,1600.1275634765625 ,1230.4781494140625 ,1006.2012939453125 ,847.0896606445312 ,894.0360717773438 ,875.56201171875 ,874.3985595703125 ,894.0360717773438 ,880.638427734375 ,875.56201171875 ,692.4459838867188 ,694.0750732421875 ,696.7554931640625 ,692.4459838867188 ,696.7554931640625 ,704.5575561523438 ,10.203259468078613 ,-5.270526885986328 ,-7.566917896270752 ,805.8684692382812 ,827.5255126953125 ,815.0030517578125 ,-208.45709228515625 ,-275.2289733886719 ,-232.23538208007812 ,1601.72216796875 ,1596.3980712890625 ,1589.9951171875 ,-96.71883392333984 ,-96.60274505615234 ,-92.52731323242188 ,-96.71883392333984 ,-98.6882095336914 ,-96.60274505615234 ,1670.9378662109375 ,1670.4410400390625 ,1673.563720703125 ,1597.8902587890625 ,1598.4822998046875 ,1598.1248779296875 ,1598.1248779296875 ,1598.4822998046875 ,1597.9581298828125 ,777.9039916992188 ,687.8463134765625 ,791.092529296875 ,791.092529296875 ,814.373046875 ,777.9039916992188 ,1506.75048828125 ,1537.597900390625 ,1381.69482421875 ,1685.72265625 ,1701.5162353515625 ,1669.949462890625 ,1446.096435546875 ,1347.417236328125 ,1412.957763671875 ,-126.61785888671875 ,-137.97515869140625 ,-140.21238708496094 ,1347.18408203125 ,1356.734619140625 ,1422.773193359375 ,1677.669189453125 ,1677.287109375 ,1676.799072265625 ,1175.87353515625 ,1154.680419921875 ,1151.1861572265625 ,1175.87353515625 ,1239.4842529296875 ,1154.680419921875 ,1554.7178955078125 ,1541.4324951171875 ,1567.1591796875 ,804.7008056640625 ,791.092529296875 ,687.8463134765625 ,1494.3138427734375 ,1523.0828857421875 ,1556.9329833984375 ,1674.09033203125 ,1676.799072265625 ,1677.287109375 ,1686.605712890625 ,1687.13037109375 ,1682.1060791015625 ,688.0762329101562 ,696.3478393554688 ,691.62939453125 ,688.0762329101562 ,661.2896728515625 ,672.4046020507812 ,688.0762329101562 ,691.62939453125 ,661.2896728515625 ,1672.3841552734375 ,1672.770751953125 ,1675.5518798828125 ,1680.9556884765625 ,1683.764404296875 ,1682.3333740234375 ,1683.764404296875 ,1682.7386474609375 ,1682.3333740234375 ,-89.18526458740234 ,-81.57925415039062 ,-78.44538116455078 ,1444.950927734375 ,1491.1573486328125 ,1549.762451171875 ,1740.9375 ,1724.7464599609375 ,1822.6085205078125 ,930.5149536132812 ,967.2301635742188 ,945.8577880859375 ,-92.32088470458984 ,-87.42080688476562 ,-90.53404235839844 ,-92.32088470458984 ,-88.46720886230469 ,-87.42080688476562 ,-92.32088470458984 ,-92.52731323242188 ,-88.46720886230469 ,-87.42080688476562 ,-88.46720886230469 ,-78.44538116455078 ,1567.772216796875 ,1558.611572265625 ,1562.6962890625 ,1563.8697509765625 ,1559.339111328125 ,1564.533203125 ,1498.0311279296875 ,1571.2496337890625 ,1592.970947265625 ,1498.0311279296875 ,1592.970947265625 ,1571.0238037109375 ,1644.97119140625 ,1645.4742431640625 ,1646.7701416015625 ,700.0632934570312 ,715.9713134765625 ,656.5256958007812 ,1448.8497314453125 ,1527.3734130859375 ,1535.486572265625 ,1464.3046875 ,1481.825927734375 ,1595.8602294921875 ,1568.649169921875 ,1556.784423828125 ,1564.443359375 ,1568.649169921875 ,1564.443359375 ,1566.70947265625 ,1578 ,1582.79833984375 ,1581.1905517578125 ,859.4566650390625 ,844.9097900390625 ,848.5045776367188 ,1602.3759765625 ,1606.330322265625 ,1611.4110107421875 ,1602.3759765625 ,1611.4110107421875 ,1605.918212890625 ,893.1461791992188 ,930.623046875 ,1061.1845703125 ,893.1461791992188 ,774.962646484375 ,930.623046875 ,1601.47607421875 ,1592.0440673828125 ,1609.6234130859375 ,1621.678955078125 ,1608.689697265625 ,1623.8583984375 ,1621.678955078125 ,1623.8583984375 ,1634.45361328125 ,-22.31652069091797 ,-112.009033203125 ,-66.08543395996094 ,-22.31652069091797 ,-59.35438537597656 ,-112.009033203125 ,-22.31652069091797 ,-66.08543395996094 ,-9.448720932006836 ,806.8790893554688 ,774.2960205078125 ,758.2089233398438 ,712.0097045898438 ,806.8790893554688 ,647.1498413085938 ,1565.561767578125 ,1453.39306640625 ,1569.7120361328125 ,-81.39241027832031 ,-46.53553771972656 ,-21.310529708862305 ,1684.5474853515625 ,1687.61474609375 ,1685.4197998046875 ,796.4855346679688 ,825.1792602539062 ,886.61474609375 ,1602.724365234375 ,1614.930419921875 ,1615.4534912109375 ,1202.355224609375 ,1353.4224853515625 ,1616.56201171875 ,1632.160400390625 ,1653.1845703125 ,1632.9669189453125 ,1636.14453125 ,1665.359130859375 ,1616.805419921875 ,-42.26219940185547 ,-81.39241027832031 ,-21.310529708862305 ,816.0027465820312 ,840.7582397460938 ,816.3965454101562 ,1591.122802734375 ,1505.4681396484375 ,1580.21044921875 ,1591.122802734375 ,1580.21044921875 ,1613.2799072265625 ,1571.35205078125 ,1574.9583740234375 ,1597.5164794921875 ,1808.126708984375 ,1826.67724609375 ,1868.412353515625 ,1894.75439453125 ,1894.6409912109375 ,1897.2440185546875 ,1894.75439453125 ,1897.2440185546875 ,1868.412353515625 ,1649.01171875 ,1602.4049072265625 ,1565.6654052734375 ,778.3762817382812 ,778.3938598632812 ,746.5462036132812 ,1674.4515380859375 ,1677.313720703125 ,1671.58349609375 ,1678.28515625 ,1677.6544189453125 ,1678.89990234375 ,1611.879638671875 ,1592.3297119140625 ,1555.0257568359375 ,-123.85717010498047 ,-93.7981948852539 ,-116.95503997802734 ,1589.3944091796875 ,1593.052978515625 ,1598.30029296875 ,599.6967163085938 ,500.4654235839844 ,391.55621337890625 ,599.6967163085938 ,457.18621826171875 ,558.17333984375 ,599.6967163085938 ,391.55621337890625 ,457.18621826171875 ,-88.46720886230469 ,-96.60274505615234 ,-89.18526458740234 ,-88.46720886230469 ,-92.52731323242188 ,-96.60274505615234 ,1670.451416015625 ,1670.4793701171875 ,1675.3055419921875 ,120.27181243896484 ,81.85975646972656 ,148.8214874267578 ,120.27181243896484 ,148.8214874267578 ,151.38206481933594 ,754.551025390625 ,709.1033325195312 ,704.5575561523438 ,1653.9564208984375 ,1656.4151611328125 ,1653.62744140625 ,1653.9564208984375 ,1651.813232421875 ,1653.8194580078125 ,1653.9564208984375 ,1653.8194580078125 ,1654.3704833984375 ,1653.9564208984375 ,1654.3704833984375 ,1656.4151611328125 ,1656.4151611328125 ,1659.3984375 ,1653.62744140625 ,1468.338623046875 ,1492.576904296875 ,1484.3262939453125 ,1665.5714111328125 ,1651.2210693359375 ,1616.751220703125 ,-141.77560424804688 ,-139.95550537109375 ,-141.76776123046875 ,1363.837646484375 ,1422.773193359375 ,1356.734619140625 ,804.38037109375 ,791.40380859375 ,806.5706176757812 ,1654.172607421875 ,1654.10693359375 ,1650.775146484375 ,1654.172607421875 ,1650.775146484375 ,1648.9373779296875 ,1651.2210693359375 ,1662.6783447265625 ,1634.2149658203125 ,1562.6962890625 ,1575.0830078125 ,1565.9283447265625 ,1372.3671875 ,1406.17626953125 ,1436.84033203125 ,1642.0909423828125 ,1650.9715576171875 ,1662.5382080078125 ,1642.0909423828125 ,1639.336181640625 ,1650.9715576171875 ,1619.4249267578125 ,1620.5557861328125 ,1617.8548583984375 ,1619.4249267578125 ,1617.8548583984375 ,1611.3134765625 ,1249.8555908203125 ,1285.7158203125 ,1324.3756103515625 ,-158.48971557617188 ,-142.57838439941406 ,-149.50289916992188 ,-141.4126739501953 ,-131.34829711914062 ,-147.094482421875 ,-141.4126739501953 ,-147.094482421875 ,-141.97189331054688 ,-141.97189331054688 ,-137.67189025878906 ,-141.4126739501953 ,-141.4126739501953 ,-137.67189025878906 ,-130.15724182128906 ,-141.4126739501953 ,-130.15724182128906 ,-131.34829711914062 ,1649.1888427734375 ,1649.632568359375 ,1646.2232666015625 ,1649.1888427734375 ,1646.2232666015625 ,1645.428466796875 ,1239.4842529296875 ,1175.87353515625 ,1242.9195556640625 ,1687.13037109375 ,1686.605712890625 ,1685.1622314453125 ,1687.13037109375 ,1685.1622314453125 ,1682.1060791015625 ,783.8365478515625 ,755.9078369140625 ,881.7615966796875 ,1592.21435546875 ,1590.207763671875 ,1589.46728515625 ,1590.207763671875 ,1589.48583984375 ,1590.1669921875 ,1590.207763671875 ,1590.1669921875 ,1589.46728515625 ,806.5247192382812 ,818.7212524414062 ,823.284912109375 ,-148.8948974609375 ,-149.6663818359375 ,-150.98208618164062 ,-148.8948974609375 ,-147.2008514404297 ,-149.6663818359375 ,1565.647705078125 ,1575.79345703125 ,1554.7178955078125 ,822.809326171875 ,834.166015625 ,843.2396240234375 ,814.373046875 ,867.532958984375 ,865.3997802734375 ,1687.61474609375 ,1683.823974609375 ,1685.4197998046875 ,846.870849609375 ,839.0542602539062 ,843.5563354492188 ,846.870849609375 ,848.5045776367188 ,839.0542602539062 ,1408.2325439453125 ,1382.652587890625 ,1403.621826171875 ,1302.64599609375 ,1351.838134765625 ,1376.0538330078125 ,1302.64599609375 ,1385.2088623046875 ,1142.978759765625 ,1563.65771484375 ,1556.0623779296875 ,1572.1949462890625 ,-169.49635314941406 ,-209.7818145751953 ,39.237022399902344 ,1682.1060791015625 ,1681.7762451171875 ,1674.0220947265625 ,1672.285888671875 ,1675.341064453125 ,1667.962646484375 ,1174.9976806640625 ,1200.5262451171875 ,1312.3348388671875 ,1104.0047607421875 ,1093.7362060546875 ,1025.4761962890625 ,1678.9876708984375 ,1683.6917724609375 ,1678.28515625 ,1568.0350341796875 ,1557.3426513671875 ,1563.65771484375 ,1645.4742431640625 ,1648.815673828125 ,1650.6107177734375 ,1597.1463623046875 ,1621.914794921875 ,1627.009521484375 ,-262.1553649902344 ,-154.71624755859375 ,-208.8668975830078 ,-117.57561492919922 ,-132.05003356933594 ,-124.44517517089844 ,1651.3546142578125 ,1588.199462890625 ,2294.779296875 ,1079.087646484375 ,1065.7030029296875 ,1025.0396728515625 ,1681.6229248046875 ,1683.5235595703125 ,1680.9556884765625 ,1571.35205078125 ,1597.5164794921875 ,1615.714599609375 ,1902.2969970703125 ,1980.4984130859375 ,1651.383056640625 ,1604.0574951171875 ,1603.9329833984375 ,1602.9903564453125 ,-78.44538116455078 ,-74.24273681640625 ,-87.42080688476562 ,1707.3741455078125 ,1734.58935546875 ,1598.2261962890625 ,726.8759765625 ,812.12744140625 ,797.5750122070312 ,1650.9715576171875 ,1639.336181640625 ,1633.216552734375 ,1650.9715576171875 ,1665.584716796875 ,1662.5382080078125 ,1549.762451171875 ,1622.8790283203125 ,1696.6854248046875 ,1549.762451171875 ,1491.1573486328125 ,1622.8790283203125 ,1647.197021484375 ,1637.0882568359375 ,1636.909912109375 ,1647.197021484375 ,1636.909912109375 ,1645.8345947265625 ,1632.9669189453125 ,1626.4022216796875 ,1632.160400390625 ,1686.734130859375 ,1686.976318359375 ,1683.869873046875 ,1686.734130859375 ,1688.0482177734375 ,1686.976318359375 ,1651.383056640625 ,1925.99853515625 ,1230.4781494140625 ,1651.383056640625 ,1980.4984130859375 ,1925.99853515625 ,-36.65013122558594 ,-41.27777099609375 ,-38.70508575439453 ,-36.65013122558594 ,-38.37532424926758 ,-41.27777099609375 ,1562.002685546875 ,1309.4805908203125 ,1061.1845703125 ,672.4046020507812 ,558.17333984375 ,668.2109985351562 ,1079.9857177734375 ,1211.4088134765625 ,1120.439208984375 ,1079.9857177734375 ,1149.0843505859375 ,1211.4088134765625 ,843.5925903320312 ,757.2192993164062 ,816.103271484375 ,712.0097045898438 ,755.9078369140625 ,783.8365478515625 ,1007.6820678710938 ,1025.0396728515625 ,1065.7030029296875 ,1007.6820678710938 ,1010.923828125 ,1025.0396728515625 ,1614.540771484375 ,1622.7889404296875 ,1622.14599609375 ,1694.03564453125 ,1694.043212890625 ,1693.0804443359375 ,-123.85717010498047 ,-116.95503997802734 ,-146.23471069335938 ,2294.779296875 ,1925.99853515625 ,1980.4984130859375 ,1651.705078125 ,1657.0157470703125 ,1654.254150390625 ,1347.417236328125 ,1234.9974365234375 ,1359.5948486328125 ,1347.417236328125 ,1359.5948486328125 ,1412.957763671875 ,1347.417236328125 ,1446.096435546875 ,1391.05419921875 ,1347.417236328125 ,1391.05419921875 ,1146.396484375 ,1556.5849609375 ,1558.611572265625 ,1556.9703369140625 ,1677.313720703125 ,1669.9747314453125 ,1671.58349609375 ,-145.5254364013672 ,-147.1070098876953 ,-146.309814453125 ,-145.5254364013672 ,-148.0751953125 ,-147.1070098876953 ,1174.9976806640625 ,1312.3348388671875 ,1354.074951171875 ,1174.9976806640625 ,1354.074951171875 ,1315.204833984375 ,668.2109985351562 ,504.4600830078125 ,670.9752807617188 ,668.2109985351562 ,558.17333984375 ,504.4600830078125 ,1667.3428955078125 ,1669.1170654296875 ,1668.1595458984375 ,-89.18526458740234 ,-96.60274505615234 ,-96.3033676147461 ,1587.5968017578125 ,1598.0146484375 ,1595.5892333984375 ,-158.5607147216797 ,-150.95314025878906 ,-154.3759307861328 ,1652.9178466796875 ,1657.8052978515625 ,1662.0677490234375 ,1654.3704833984375 ,1653.708740234375 ,1656.4151611328125 ,1675.341064453125 ,1673.615966796875 ,1667.962646484375 ,39.237022399902344 ,400.4861145019531 ,125.14277648925781 ,39.237022399902344 ,4.928195953369141 ,400.4861145019531 ,826.7001342773438 ,816.6506958007812 ,816.3965454101562 ,816.3965454101562 ,815.479248046875 ,806.5706176757812 ,816.3965454101562 ,816.6506958007812 ,815.479248046875 ,1673.9615478515625 ,1670.9056396484375 ,1670.5738525390625 ,1637.527587890625 ,1642.681396484375 ,1640.646728515625 ,794.5354614257812 ,797.864990234375 ,793.9613037109375 ,1691.2550048828125 ,1693.083984375 ,1691.13720703125 ,1622.3206787109375 ,1625.792724609375 ,1613.4114990234375 ,-151.15257263183594 ,-156.220947265625 ,-160.0223388671875 ,1674.372314453125 ,1698.6005859375 ,1648.77978515625 ,-168.5343017578125 ,-164.67984008789062 ,-158.22862243652344 ,1658.734619140625 ,1661.281982421875 ,1652.7958984375 ,782.7861328125 ,772.51806640625 ,783.3544921875 ,782.7861328125 ,786.1884765625 ,772.51806640625 ,772.51806640625 ,772.115966796875 ,783.3544921875 ,-275.2289733886719 ,-295.60565185546875 ,-232.23538208007812 ,1647.1204833984375 ,1654.3341064453125 ,1648.815673828125 ,1555.0257568359375 ,1578.3837890625 ,1559.1688232421875 ,-115.28341674804688 ,-102.25055694580078 ,-107.82918548583984 ,-115.28341674804688 ,-107.82918548583984 ,-127.01480102539062 ,-115.28341674804688 ,-117.45018768310547 ,-102.72400665283203 ,-115.28341674804688 ,-102.72400665283203 ,-102.25055694580078 ,-127.01480102539062 ,-107.82918548583984 ,-119.80301666259766 ,1613.9197998046875 ,1603.897705078125 ,1590.896484375 ,-131.34829711914062 ,-143.2757110595703 ,-148.68128967285156 ,722.6234130859375 ,647.1498413085938 ,738.90380859375 ,1475.4910888671875 ,1506.52294921875 ,1482.5047607421875 ,1578.0010986328125 ,1577.8433837890625 ,1568.7576904296875 ,1571.2496337890625 ,1607.9425048828125 ,1592.970947265625 ,1592.970947265625 ,1607.9425048828125 ,1616.751220703125 ,687.7828979492188 ,623.9884643554688 ,657.6510620117188 ,657.6510620117188 ,623.9884643554688 ,608.802734375 ,1686.976318359375 ,1682.1060791015625 ,1683.869873046875 ,1555.0257568359375 ,1554.4915771484375 ,1561.6275634765625 ,1428.7633056640625 ,1562.5577392578125 ,1512.47705078125 ,717.6968383789062 ,692.4243774414062 ,706.3660278320312 ,1692.15234375 ,1691.309814453125 ,1692.223876953125 ,1675.5518798828125 ,1674.09033203125 ,1677.287109375 ,744.9285278320312 ,833.7752075195312 ,796.4855346679688 ,1683.869873046875 ,1683.40087890625 ,1686.08740234375 ,1683.869873046875 ,1686.08740234375 ,1686.734130859375 ,1554.7178955078125 ,1560.2115478515625 ,1548.2794189453125 ,1351.378662109375 ,1382.652587890625 ,1315.80810546875 ,1351.378662109375 ,1403.621826171875 ,1382.652587890625 ,1647.745361328125 ,1635.9215087890625 ,1644.5009765625 ,128.33255004882812 ,154.77740478515625 ,130.8192138671875 ,1627.1104736328125 ,1630.0673828125 ,1635.94482421875 ,1204.0008544921875 ,1317.367431640625 ,1477.02099609375 ,1644.28955078125 ,1643.6181640625 ,1642.2862548828125 ,826.8889770507812 ,866.9893798828125 ,996.065185546875 ,1616.56201171875 ,1353.4224853515625 ,1517.98193359375 ,1678.28515625 ,1683.6917724609375 ,1677.6544189453125 ,1898.9945068359375 ,1867.8238525390625 ,1882.818359375 ,1577.8433837890625 ,1571.12646484375 ,1568.7576904296875 ,1677.0140380859375 ,1678.726318359375 ,1673.062744140625 ,1677.0140380859375 ,1673.062744140625 ,1678.15283203125 ,1677.0140380859375 ,1678.15283203125 ,1678.726318359375 ,-74.53084564208984 ,-60.050437927246094 ,-75.78340911865234 ,1532.41796875 ,1540.3974609375 ,1537.4833984375 ,-149.50289916992188 ,-141.19369506835938 ,-158.48971557617188 ,1473.3651123046875 ,1515.3936767578125 ,974.5388793945312 ,1473.3651123046875 ,974.5388793945312 ,1181.88525390625 ,1473.3651123046875 ,1726.457275390625 ,1515.3936767578125 ,1671.40869140625 ,1672.0784912109375 ,1672.3447265625 ,785.5821533203125 ,778.3762817382812 ,771.9223022460938 ,-143.0941925048828 ,-137.67189025878906 ,-141.97189331054688 ,816.3965454101562 ,804.3980712890625 ,816.0027465820312 ,1038.2694091796875 ,1079.087646484375 ,1010.2650756835938 ,1038.2694091796875 ,1087.777587890625 ,1079.087646484375 ,1586.39990234375 ,1588.5467529296875 ,1596.0208740234375 ,1643.3487548828125 ,1641.2344970703125 ,1637.375 ,1691.13720703125 ,1691.6614990234375 ,1691.32421875 ,387.1172790527344 ,400.4861145019531 ,4.928195953369141 ,51.839210510253906 ,55.008338928222656 ,4.923157215118408 ,51.839210510253906 ,10.203259468078613 ,6.033566951751709 ,51.839210510253906 ,4.923157215118408 ,10.203259468078613 ,6.033566951751709 ,10.203259468078613 ,-21.956390380859375 ,6.033566951751709 ,-21.956390380859375 ,-5.711810111999512 ,1623.9122314453125 ,1647.9674072265625 ,1647.4063720703125 ,-121.91429901123047 ,-131.34829711914062 ,-130.15724182128906 ,1448.8497314453125 ,1536.4788818359375 ,1527.3734130859375 ,827.5490112304688 ,778.3938598632812 ,829.766357421875 ,990.3247680664062 ,966.7046508789062 ,973.2190551757812 ,836.3881225585938 ,826.7001342773438 ,840.7582397460938 ,797.864990234375 ,806.130859375 ,793.9613037109375 ,797.864990234375 ,804.38037109375 ,806.130859375 ,1444.950927734375 ,1494.3138427734375 ,1416.5341796875 ,1599.4454345703125 ,1599.012451171875 ,1597.3072509765625 ,1569.4425048828125 ,1589.9951171875 ,1592.876953125 ,706.8468627929688 ,723.9068603515625 ,746.6197509765625 ,191.36724853515625 ,178.16810607910156 ,153.0332794189453 ,191.36724853515625 ,153.0332794189453 ,184.67359924316406 ,191.36724853515625 ,151.38206481933594 ,178.16810607910156 ,1630.8304443359375 ,1642.0909423828125 ,1638.287841796875 ,1625.2537841796875 ,1634.8624267578125 ,1632.2459716796875 ,1625.2537841796875 ,1610.5791015625 ,1634.8624267578125 ,1541.919921875 ,1547.5770263671875 ,1537.7679443359375 ,1555.284912109375 ,1595.8814697265625 ,1580.21044921875 ,1555.284912109375 ,1580.21044921875 ,1454.1854248046875 ,1540.3077392578125 ,1463.4681396484375 ,1499.37890625 ,804.38037109375 ,806.5706176757812 ,815.479248046875 ,1553.118896484375 ,1546.939697265625 ,1563.897216796875 ,1592.6239013671875 ,1381.69482421875 ,1537.597900390625 ,1664.2130126953125 ,1652.5123291015625 ,1656.165283203125 ,2001.811767578125 ,2316.001708984375 ,1606.1458740234375 ,1685.72265625 ,1639.727294921875 ,1686.7740478515625 ,1529.5411376953125 ,1540.3077392578125 ,1561.707763671875 ,1211.4088134765625 ,1149.0843505859375 ,1264.9102783203125 ,-135.68988037109375 ,-148.29736328125 ,-135.0819854736328 ,1669.949462890625 ,1701.8389892578125 ,1692.29931640625 ,1554.2913818359375 ,1556.1182861328125 ,1554.8896484375 ,-154.3759307861328 ,-150.95314025878906 ,-153.44960021972656 ,-58.539974212646484 ,-65.2342300415039 ,-67.98887634277344 ,1679.0426025390625 ,1680.9556884765625 ,1680.6246337890625 ,1679.0426025390625 ,1680.0179443359375 ,1680.0238037109375 ,1679.0426025390625 ,1680.6246337890625 ,1680.0179443359375 ,-172.18809509277344 ,-172.3965606689453 ,-172.63314819335938 ,-172.18809509277344 ,-172.63314819335938 ,-173.44215393066406 ,-154.16233825683594 ,-156.95455932617188 ,-150.98208618164062 ,-8.421085357666016 ,11.090381622314453 ,-2.8962490558624268 ,-8.421085357666016 ,-2.8962490558624268 ,-34.37968444824219 ,-8.421085357666016 ,-34.37968444824219 ,-19.138835906982422 ,758.2089233398438 ,647.1498413085938 ,806.8790893554688 ,774.2960205078125 ,647.1498413085938 ,758.2089233398438 ,866.9893798828125 ,718.9926147460938 ,738.4603881835938 ,738.4603881835938 ,774.2960205078125 ,866.9893798828125 ,604.1659545898438 ,803.7413940429688 ,816.103271484375 ,-112.88627624511719 ,-154.71624755859375 ,-33.623085021972656 ,784.7041015625 ,784.9931640625 ,785.5821533203125 ,784.7041015625 ,785.5821533203125 ,771.9223022460938 ,249.11463928222656 ,167.67335510253906 ,171.44357299804688 ,-120.13593292236328 ,-104.98910522460938 ,-125.6340103149414 ,1561.6275634765625 ,1554.4915771484375 ,1563.8697509765625 ,1648.089111328125 ,1632.47265625 ,1660.21875 ,-131.34829711914062 ,-148.68128967285156 ,-147.094482421875 ,1678.84521484375 ,1675.3109130859375 ,1679.0426025390625 ,-295.60565185546875 ,-297.5017395019531 ,-232.23538208007812 ,1683.33642578125 ,1681.4715576171875 ,1662.9295654296875 ,960.0421752929688 ,1070.3936767578125 ,890.9190673828125 ,1574.923828125 ,1575.49267578125 ,1584.0416259765625 ,721.9412841796875 ,774.2960205078125 ,738.4603881835938 ,-139.70440673828125 ,-142.55540466308594 ,-142.97039794921875 ,1647.4891357421875 ,1652.8292236328125 ,1665.7197265625 ,1647.4891357421875 ,1665.7197265625 ,1665.1942138671875 ,-147.42669677734375 ,-152.9228973388672 ,-143.44833374023438 ,1688.1015625 ,1687.9541015625 ,1684.94921875 ,1660.1500244140625 ,1662.50830078125 ,1662.020263671875 ,1691.6614990234375 ,1692.31298828125 ,1693.0771484375 ,1691.6614990234375 ,1691.13720703125 ,1692.31298828125 ,1691.13720703125 ,1693.083984375 ,1692.31298828125 ,-165.09109497070312 ,-168.31546020507812 ,-162.4461212158203 ,1568.7576904296875 ,1571.12646484375 ,1565.846923828125 ,1654.254150390625 ,1650.708740234375 ,1651.705078125 ,1632.47265625 ,1639.7213134765625 ,1636.1795654296875 ,816.0027465820312 ,804.3980712890625 ,808.4400634765625 ,1381.69482421875 ,1610.6427001953125 ,1473.3651123046875 ,1381.69482421875 ,1473.3651123046875 ,1181.88525390625 ,713.6329956054688 ,716.3633422851562 ,713.3721923828125 ,-88.27867126464844 ,-98.51581573486328 ,-119.19314575195312 ,-93.7981948852539 ,-97.74697875976562 ,-84.37976837158203 ,-232.23538208007812 ,-154.71624755859375 ,-112.88627624511719 ,1656.624755859375 ,1657.146728515625 ,1655.774658203125 ,1656.624755859375 ,1650.5126953125 ,1657.146728515625 ,1666.6029052734375 ,1657.2647705078125 ,1662.61865234375 ,1657.2647705078125 ,1643.2557373046875 ,1662.61865234375 ,712.0097045898438 ,783.8365478515625 ,806.8790893554688 ,1581.1905517578125 ,1582.79833984375 ,1585.8505859375 ,-147.2008514404297 ,-147.1070098876953 ,-149.3259735107422 ,-147.2008514404297 ,-149.3259735107422 ,-149.1376953125 ,-147.2008514404297 ,-146.309814453125 ,-147.1070098876953 ,-149.3259735107422 ,-149.96043395996094 ,-149.1376953125 ,-168.31546020507812 ,-168.3688507080078 ,-162.4461212158203 ,1010.2650756835938 ,1025.0396728515625 ,1010.923828125 ,1574.923828125 ,1566.3751220703125 ,1575.49267578125 ,1701.8389892578125 ,1669.949462890625 ,1704.06396484375 ,1669.949462890625 ,1701.5162353515625 ,1704.06396484375 ,721.9412841796875 ,618.6279907226562 ,688.91357421875 ,721.9412841796875 ,718.9926147460938 ,696.59814453125 ,973.2190551757812 ,1009.9961547851562 ,990.3247680664062 ,-153.44395446777344 ,-162.77415466308594 ,-158.7922821044922 ,-96.97508239746094 ,-102.25055694580078 ,-93.32140350341797 ,1662.61865234375 ,1643.2557373046875 ,1658.1865234375 ,1673.271484375 ,1674.0220947265625 ,1681.7762451171875 ,769.0580444335938 ,764.6854248046875 ,786.3716430664062 ,1635.6124267578125 ,1630.8304443359375 ,1638.287841796875 ,1619.9852294921875 ,1637.7955322265625 ,1646.99853515625 ,1376.0538330078125 ,1351.838134765625 ,1355.326171875 ,1381.69482421875 ,1391.05419921875 ,1506.75048828125 ,-160.1863555908203 ,-160.25048828125 ,-162.89971923828125 ,1662.0677490234375 ,1657.8052978515625 ,1667.950439453125 ,1724.7464599609375 ,1680.8619384765625 ,1819.286376953125 ,1724.7464599609375 ,1819.286376953125 ,1822.6085205078125 ,1559.1688232421875 ,1578.3837890625 ,1567.9937744140625 ,1672.82763671875 ,1668.54248046875 ,1681.7762451171875 ,1574.9583740234375 ,1571.0238037109375 ,1616.751220703125 ,1574.9583740234375 ,1616.751220703125 ,1597.5164794921875 ,1571.0238037109375 ,1592.970947265625 ,1616.751220703125 ,1642.71826171875 ,1642.2862548828125 ,1643.6181640625 ,907.8963012695312 ,942.9981689453125 ,1010.2650756835938 ,907.8963012695312 ,884.965576171875 ,942.9981689453125 ,-119.80301666259766 ,-107.82918548583984 ,-123.86084747314453 ,-119.80301666259766 ,-123.86084747314453 ,-127.01480102539062 ,-123.86084747314453 ,-149.2166748046875 ,-127.01480102539062 ,1556.35205078125 ,1556.96240234375 ,1555.383056640625 ,1556.35205078125 ,1553.41455078125 ,1556.96240234375 ,1555.383056640625 ,1556.96240234375 ,1558.181884765625 ,1575.0830078125 ,1565.91796875 ,1589.19580078125 ,683.404296875 ,743.8383178710938 ,753.0946044921875 ,683.404296875 ,753.0946044921875 ,662.4285278320312 ,1641.2344970703125 ,1643.3487548828125 ,1669.6181640625 ,1641.2344970703125 ,1669.6181640625 ,1670.8839111328125 ,1683.869873046875 ,1678.5303955078125 ,1683.40087890625 ,-0.439193993806839 ,2.2539000511169434 ,-49.69411087036133 ,784.624755859375 ,786.6719970703125 ,779.3375244140625 ,-147.1070098876953 ,-148.0751953125 ,-149.3259735107422 ,-162.77415466308594 ,-158.0950469970703 ,-158.7922821044922 ,1556.0623779296875 ,1565.1370849609375 ,1572.1949462890625 ,1560.262451171875 ,1554.1483154296875 ,1553.8087158203125 ,1560.262451171875 ,1555.195556640625 ,1554.1483154296875 ,873.3203735351562 ,875.56201171875 ,868.5808715820312 ,647.1498413085938 ,774.2960205078125 ,721.9412841796875 ,1694.117919921875 ,1693.1881103515625 ,1694.115234375 ,153.8966064453125 ,184.67359924316406 ,153.0332794189453 ,153.0332794189453 ,148.8214874267578 ,153.8966064453125 ,-166.96328735351562 ,-168.22259521484375 ,-142.4543914794922 ,1598.30029296875 ,1600.6370849609375 ,1599.285400390625 ,1079.087646484375 ,1025.0396728515625 ,1010.2650756835938 ,1589.9951171875 ,1569.4425048828125 ,1570.540283203125 ,1302.64599609375 ,1061.62109375 ,1355.326171875 ,1302.64599609375 ,1355.326171875 ,1351.838134765625 ,1616.751220703125 ,1620.778564453125 ,1665.5714111328125 ,832.3193969726562 ,859.1519165039062 ,854.8204956054688 ,1149.0843505859375 ,1286.781494140625 ,1264.9102783203125 ,-232.23538208007812 ,-262.1553649902344 ,-208.8668975830078 ,793.662109375 ,816.4202880859375 ,604.1659545898438 ,1608.689697265625 ,1621.678955078125 ,1601.7042236328125 ,1690.935791015625 ,1691.2550048828125 ,1689.559814453125 ,1692.54150390625 ,1692.2333984375 ,1693.083984375 ,-74.24273681640625 ,-70.5509262084961 ,-86.68527221679688 ,-74.24273681640625 ,-86.68527221679688 ,-87.42080688476562 ,761.9024047851562 ,799.6619262695312 ,793.8484497070312 ,925.2911987304688 ,966.2996215820312 ,927.310791015625 ,-90.37690734863281 ,-90.53404235839844 ,-78.29945373535156 ,-90.53404235839844 ,-86.68527221679688 ,-78.29945373535156 ,1656.165283203125 ,1652.5123291015625 ,1645.7232666015625 ,7.397647857666016 ,-95.96955108642578 ,-70.44745635986328 ,7.397647857666016 ,-70.44745635986328 ,12.554376602172852 ,-58.539974212646484 ,-60.050437927246094 ,-52.834678649902344 ,-52.834678649902344 ,-60.050437927246094 ,-49.75644302368164 ,-52.834678649902344 ,-49.75644302368164 ,-39.263126373291016 ,1563.65771484375 ,1572.1949462890625 ,1568.0350341796875 ,1230.4781494140625 ,1179.5418701171875 ,1006.2012939453125 ,1864.595458984375 ,1884.81787109375 ,1885.945556640625 ,1582.463134765625 ,1588.7347412109375 ,1580.116943359375 ,1582.463134765625 ,1585.8505859375 ,1588.7347412109375 ,1671.0203857421875 ,1664.07568359375 ,1660.8375244140625 ,662.4285278320312 ,753.0946044921875 ,741.1661987304688 ,1939.4962158203125 ,1885.945556640625 ,1940.6337890625 ,1679.0426025390625 ,1680.0238037109375 ,1678.84521484375 ,-149.6663818359375 ,-149.1376953125 ,-150.98208618164062 ,-149.6663818359375 ,-147.2008514404297 ,-149.1376953125 ,-150.98208618164062 ,-156.95455932617188 ,-148.8948974609375 ,-86.68527221679688 ,-90.53404235839844 ,-87.42080688476562 ,797.3441772460938 ,793.8484497070312 ,799.6619262695312 ,1609.6234130859375 ,1595.1080322265625 ,1618.220947265625 ,1609.6234130859375 ,1618.220947265625 ,1628.5848388671875 ,1686.605712890625 ,1686.6390380859375 ,1686.0958251953125 ,1627.7359619140625 ,1626.4022216796875 ,1628.7493896484375 ,1632.61962890625 ,1644.4151611328125 ,1644.5009765625 ,1632.61962890625 ,1644.5009765625 ,1635.9215087890625 ,1441.8394775390625 ,1403.7037353515625 ,1475.1905517578125 ,1616.751220703125 ,1651.2210693359375 ,1597.5164794921875 ,-43.43236541748047 ,-46.14818572998047 ,-41.27777099609375 ,-41.27777099609375 ,-46.14818572998047 ,-38.70508575439453 ,1653.708740234375 ,1659.3984375 ,1656.4151611328125 ,-106.64468383789062 ,-97.81755828857422 ,-103.65386962890625 ,835.6561889648438 ,822.2063598632812 ,835.016357421875 ,-170.8787078857422 ,-172.63314819335938 ,-172.3965606689453 ,-149.3259735107422 ,-151.68954467773438 ,-149.96043395996094 ,558.17333984375 ,372.5214538574219 ,504.4600830078125 ,558.17333984375 ,457.18621826171875 ,372.5214538574219 ,504.4600830078125 ,372.5214538574219 ,400.4861145019531 ,590.23095703125 ,693.88330078125 ,495.27227783203125 ,1563.6204833984375 ,1553.41455078125 ,1565.846923828125 ,1663.043212890625 ,1657.659912109375 ,1664.859130859375 ,558.17333984375 ,661.2896728515625 ,599.6967163085938 ,558.17333984375 ,672.4046020507812 ,661.2896728515625 ,1595.38623046875 ,1580.116943359375 ,1588.7347412109375 ,1595.38623046875 ,1588.7347412109375 ,1590.464111328125 ,1651.2210693359375 ,1615.714599609375 ,1597.5164794921875 ,171.44357299804688 ,167.67335510253906 ,155.5832977294922 ,171.44357299804688 ,155.5832977294922 ,142.91012573242188 ,1200.5262451171875 ,1223.370849609375 ,1312.3348388671875 ,1693.0140380859375 ,1692.538330078125 ,1692.7640380859375 ,-100.40309143066406 ,-96.3033676147461 ,-96.60274505615234 ,1681.121337890625 ,1678.5303955078125 ,1683.869873046875 ,1681.121337890625 ,1683.869873046875 ,1682.1060791015625 ,1618.220947265625 ,1614.5419921875 ,1635.490478515625 ,1598.30029296875 ,1599.285400390625 ,1589.3944091796875 ,-133.1193084716797 ,-132.05003356933594 ,-138.2955322265625 ,-147.3275604248047 ,-148.8948974609375 ,-156.95455932617188 ,743.8383178710938 ,756.713134765625 ,753.0946044921875 ,-45.30834197998047 ,-44.69572830200195 ,-76.51492309570312 ,1686.0958251953125 ,1686.6390380859375 ,1685.785888671875 ,1645.7117919921875 ,1627.009521484375 ,1621.914794921875 ,1571.6982421875 ,1561.707763671875 ,1573.8131103515625 ,1587.611083984375 ,1589.2406005859375 ,1590.464111328125 ,835.6561889648438 ,844.9097900390625 ,848.6284790039062 ,835.6561889648438 ,835.016357421875 ,844.9097900390625 ,-78.44538116455078 ,-75.78340911865234 ,-67.98887634277344 ,1609.4886474609375 ,1607.47314453125 ,1623.7159423828125 ,-89.18526458740234 ,-78.44538116455078 ,-88.46720886230469 ,-78.44538116455078 ,-81.57925415039062 ,-75.78340911865234 ,1645.8345947265625 ,1654.421142578125 ,1646.78857421875 ,1547.5770263671875 ,1546.939697265625 ,1537.7679443359375 ,1782.79150390625 ,1898.9945068359375 ,1826.67724609375 ,1826.67724609375 ,1898.9945068359375 ,1868.412353515625 ,996.065185546875 ,866.9893798828125 ,965.6051025390625 ,996.065185546875 ,965.6051025390625 ,1012.0601196289062 ,1636.100341796875 ,1645.7232666015625 ,1652.5123291015625 ,1801.9376220703125 ,1630.985595703125 ,1625.0286865234375 ,1506.75048828125 ,1391.05419921875 ,1542.666748046875 ,1726.457275390625 ,1473.3651123046875 ,1610.6427001953125 ,1685.358154296875 ,1685.785888671875 ,1686.6390380859375 ,731.4716186523438 ,729.4252319335938 ,747.8978881835938 ,1354.074951171875 ,1312.3348388671875 ,1500.01318359375 ,1554.4915771484375 ,1559.339111328125 ,1563.8697509765625 ,-208.8668975830078 ,-154.71624755859375 ,-232.23538208007812 ,1672.0784912109375 ,1673.2105712890625 ,1672.3447265625 ,-156.220947265625 ,-145.7958221435547 ,-145.2946014404297 ,1657.0157470703125 ,1660.94091796875 ,1654.254150390625 ,835.016357421875 ,848.5045776367188 ,844.9097900390625 ,835.016357421875 ,839.0542602539062 ,848.5045776367188 ,1782.79150390625 ,1867.8238525390625 ,1898.9945068359375 ,1645.7232666015625 ,1636.100341796875 ,1627.6866455078125 ,1660.94091796875 ,1664.3409423828125 ,1654.254150390625 ,721.9412841796875 ,738.4603881835938 ,718.9926147460938 ,500.4654235839844 ,599.6967163085938 ,616.2135009765625 ,1595.1080322265625 ,1609.6234130859375 ,1592.0440673828125 ,-52.834678649902344 ,-38.70508575439453 ,-46.14818572998047 ,-52.834678649902344 ,-39.263126373291016 ,-38.70508575439453 ,1611.3134765625 ,1617.8548583984375 ,1609.713134765625 ,826.7001342773438 ,816.3965454101562 ,840.7582397460938 ,1593.052978515625 ,1589.3944091796875 ,1569.4425048828125 ,-59.35438537597656 ,-102.61859893798828 ,-112.009033203125 ,1609.4886474609375 ,1626.8748779296875 ,1607.47314453125 ,696.7554931640625 ,704.05419921875 ,704.5575561523438 ,1633.1016845703125 ,1630.0673828125 ,1632.5113525390625 ,1647.745361328125 ,1640.7991943359375 ,1635.9215087890625 ,1692.796630859375 ,1693.083984375 ,1692.50048828125 ,668.2542114257812 ,778.0476684570312 ,804.1401977539062 ,-112.009033203125 ,-102.61859893798828 ,-114.62600708007812 ,811.1006469726562 ,854.8204956054688 ,844.23388671875 ,1683.382080078125 ,1686.0943603515625 ,1682.6153564453125 ,1548.0048828125 ,1464.3046875 ,1595.8602294921875 ,1885.945556640625 ,1884.81787109375 ,1940.6337890625 ,-60.050437927246094 ,-58.539974212646484 ,-75.78340911865234 ,1597.156982421875 ,1602.724365234375 ,1598.9300537109375 ,1597.156982421875 ,1599.64599609375 ,1602.724365234375 ,1602.724365234375 ,1599.64599609375 ,1602.9510498046875 ,1623.0599365234375 ,1542.666748046875 ,1446.096435546875 ,1446.096435546875 ,1542.666748046875 ,1391.05419921875 ,596.9385375976562 ,961.0006713867188 ,561.8804931640625 ,741.1661987304688 ,774.6493530273438 ,676.4495849609375 ,1555.5660400390625 ,1568.3416748046875 ,1543.2904052734375 ,178.16810607910156 ,151.38206481933594 ,153.0332794189453 ,372.5214538574219 ,125.14277648925781 ,400.4861145019531 ,887.4142456054688 ,939.5186767578125 ,833.7752075195312 ,1575.0830078125 ,1562.6962890625 ,1558.611572265625 ,722.6234130859375 ,742.2379760742188 ,755.9078369140625 ,1520.814453125 ,1403.7037353515625 ,1448.8497314453125 ,1520.814453125 ,1475.1905517578125 ,1403.7037353515625 ,1007.6820678710938 ,992.80419921875 ,1010.923828125 ,696.3478393554688 ,599.6967163085938 ,691.62939453125 ,-95.96955108642578 ,-106.98082733154297 ,-70.44745635986328 ,1592.171875 ,1589.2406005859375 ,1589.919189453125 ,1592.171875 ,1594.472900390625 ,1589.2406005859375 ,1594.472900390625 ,1590.464111328125 ,1589.2406005859375 ,1635.171875 ,1610.5791015625 ,1623.8203125 ,1684.946044921875 ,1523.4749755859375 ,1489.4591064453125 ,1489.4591064453125 ,1552.476318359375 ,1519.374267578125 ,1632.9669189453125 ,1627.7359619140625 ,1628.7493896484375 ,1632.47265625 ,1636.1795654296875 ,1634.888916015625 ,854.8204956054688 ,859.1519165039062 ,844.23388671875 ,12.193948745727539 ,-0.03479800000786781 ,51.283111572265625 ,-0.03479800000786781 ,26.925315856933594 ,51.283111572265625 ,661.2896728515625 ,691.62939453125 ,599.6967163085938 ,1632.47265625 ,1649.9718017578125 ,1662.08154296875 ,1678.15283203125 ,1673.062744140625 ,1671.3597412109375 ,-151.51779174804688 ,-151.68954467773438 ,-149.3259735107422 ,1665.1942138671875 ,1665.7197265625 ,1675.47314453125 ,754.551025390625 ,704.5575561523438 ,704.05419921875 ,1600.6370849609375 ,1598.824462890625 ,1599.285400390625 ,818.7212524414062 ,828.9366455078125 ,823.284912109375 ,1637.0882568359375 ,1632.5113525390625 ,1636.909912109375 ,1614.5419921875 ,1618.220947265625 ,1604.80224609375 ,1618.220947265625 ,1595.1080322265625 ,1604.80224609375 ,-132.05003356933594 ,-120.13593292236328 ,-138.2955322265625 ,1634.2149658203125 ,1662.6783447265625 ,1657.7835693359375 ,1667.962646484375 ,1664.8988037109375 ,1662.99072265625 ,1693.083984375 ,1692.7847900390625 ,1692.31298828125 ,1692.7847900390625 ,1693.0771484375 ,1692.31298828125 ,1692.7847900390625 ,1693.083984375 ,1693.3846435546875 ,1693.0771484375 ,1692.7847900390625 ,1693.3846435546875 ,153.0332794189453 ,151.38206481933594 ,148.8214874267578 ,1590.464111328125 ,1588.7347412109375 ,1587.611083984375 ,1587.611083984375 ,1588.7347412109375 ,1585.8505859375 ,-67.98887634277344 ,-75.78340911865234 ,-58.539974212646484 ,12.554376602172852 ,-70.44745635986328 ,-106.98082733154297 ,1626.4022216796875 ,1632.9669189453125 ,1628.7493896484375 ,1649.50341796875 ,1653.017822265625 ,1629.330810546875 ,1644.4151611328125 ,1632.61962890625 ,1632.133544921875 ,1661.43212890625 ,1661.7598876953125 ,1661.525634765625 ,1665.7197265625 ,1652.8292236328125 ,1662.984619140625 ,1694.117919921875 ,1693.7384033203125 ,1694.03564453125 ,1693.0140380859375 ,1692.7640380859375 ,1693.0911865234375 ,1693.0140380859375 ,1693.0911865234375 ,1693.4378662109375 ,1692.1171875 ,1692.0390625 ,1692.2333984375 ,1693.3846435546875 ,1693.083984375 ,1693.6707763671875 ,-9.217521667480469 ,-25.795822143554688 ,-8.705370903015137 ,-15.813745498657227 ,-19.800701141357422 ,-3.8040237426757812 ,-23.751272201538086 ,-3.8040237426757812 ,-19.800701141357422 ,1682.659912109375 ,1658.2060546875 ,1665.25 ,1661.525634765625 ,1641.9266357421875 ,1651.174560546875 ,-15.813745498657227 ,-3.8040237426757812 ,-13.02388858795166 ,-23.751272201538086 ,-48.88777542114258 ,-9.217521667480469 ,-9.217521667480469 ,-23.04074478149414 ,-20.40215301513672 ,1637.8194580078125 ,1661.525634765625 ,1682.659912109375 ,-22.078006744384766 ,-11.213990211486816 ,-3.8040237426757812 ,1682.659912109375 ,1659.3984375 ,1655.2957763671875 ,1653.762939453125 ,1655.2957763671875 ,1659.3984375 ,1656.337158203125 ,1657.83203125 ,1682.659912109375 ,1661.7598876953125 ,1659.3984375 ,1682.659912109375 ,-11.556077003479004 ,-3.8040237426757812 ,-14.807839393615723 ,-50.09689712524414 ,-48.88777542114258 ,-46.299007415771484 ,-23.751272201538086 ,-46.299007415771484 ,-48.88777542114258 ,1657.1636962890625 ,1657.1671142578125 ,1657.165771484375 ,1657.1636962890625 ,1657.1690673828125 ,1657.1671142578125 ,1657.1636962890625 ,1658.8890380859375 ,1657.1690673828125 ,1657.1636962890625 ,1655.9599609375 ,1658.8890380859375 ,1657.1636962890625 ,1657.165771484375 ,1655.9599609375 ,1655.780517578125 ,1658.8890380859375 ,1655.9599609375 ,-11.213990211486816 ,-23.613245010375977 ,-23.89716148376465 ,-21.08757781982422 ,-23.04074478149414 ,-9.217521667480469 ,-11.556077003479004 ,-7.209066390991211 ,-6.139158248901367 ,-11.556077003479004 ,-6.139158248901367 ,-3.8040237426757812 ,-9.217521667480469 ,-3.8040237426757812 ,-23.751272201538086 ,-22.078006744384766 ,-23.613245010375977 ,-11.213990211486816 ,1675.47314453125 ,1637.8194580078125 ,1682.659912109375 ,-29.13590431213379 ,-35.15899658203125 ,-23.751272201538086 ,-35.15899658203125 ,-40.60354232788086 ,-23.751272201538086 ,1682.659912109375 ,1657.1680908203125 ,1658.2060546875 ,1657.1680908203125 ,1682.659912109375 ,1657.165771484375 ,1665.25 ,1658.2060546875 ,1658.8890380859375 ,-17.79994010925293 ,-13.02388858795166 ,-3.8040237426757812 ,-11.556077003479004 ,-9.068727493286133 ,-7.209066390991211 ,1657.83203125 ,1664.07568359375 ,1682.659912109375 ,1637.8194580078125 ,1625.635498046875 ,1612.8060302734375 ,1612.8060302734375 ,1599.342529296875 ,1661.525634765625 ,-11.213990211486816 ,-10.673930168151855 ,-17.79994010925293 ,-13.02388858795166 ,-17.79994010925293 ,-16.721044540405273 ,1682.659912109375 ,1665.25 ,1669.150634765625 ,-3.8040237426757812 ,-11.213990211486816 ,-17.79994010925293 ,1655.9599609375 ,1682.659912109375 ,1655.2957763671875 ,-3.8040237426757812 ,-6.139158248901367 ,-5.106509685516357 ,-20.40215301513672 ,-3.8040237426757812 ,-9.217521667480469 ,-46.299007415771484 ,-23.751272201538086 ,-40.60354232788086 ,1661.525634765625 ,1637.8194580078125 ,1612.8060302734375 ,-11.213990211486816 ,-23.89716148376465 ,-18.62034797668457 ,-21.758371353149414 ,-18.62034797668457 ,-23.89716148376465 ,1655.9599609375 ,1655.2957763671875 ,1655.780517578125 ,1655.9599609375 ,1657.165771484375 ,1682.659912109375 ,-14.041504859924316 ,-3.8040237426757812 ,-7.460494041442871 ,1681.4793701171875 ,1682.659912109375 ,1671.0203857421875 ,1657.1680908203125 ,1657.165771484375 ,1657.1671142578125 ,1657.1680908203125 ,1657.1690673828125 ,1658.2060546875 ,1657.1680908203125 ,1657.1671142578125 ,1657.1690673828125 ,-10.673930168151855 ,-12.453563690185547 ,-17.79994010925293 ,-12.762040138244629 ,-15.813745498657227 ,-13.02388858795166 ,-1.28290855884552 ,-9.217521667480469 ,-8.705370903015137 ,-21.758371353149414 ,-23.89716148376465 ,-23.18262481689453 ,-3.8040237426757812 ,-18.395246505737305 ,-22.078006744384766 ,-14.041504859924316 ,-18.395246505737305 ,-3.8040237426757812 ,-3.124228000640869 ,-3.990647077560425 ,-3.8040237426757812 ,-14.041504859924316 ,-7.460494041442871 ,-10.522645950317383 ,-7.460494041442871 ,-3.8040237426757812 ,-7.093686103820801 ,-7.093686103820801 ,-3.8040237426757812 ,-4.152342319488525 ,-3.8040237426757812 ,-4.114527225494385 ,-4.152342319488525 ,-4.114527225494385 ,-3.8040237426757812 ,-3.990647077560425 ,1653.921875 ,1655.2957763671875 ,1653.762939453125 ,1604.1265869140625 ,1661.525634765625 ,1591.477294921875 ,1661.525634765625 ,1591.340087890625 ,1591.477294921875 ,1591.477294921875 ,1591.340087890625 ,1591.5047607421875 ,1591.340087890625 ,1591.5128173828125 ,1591.5047607421875 ,1591.5128173828125 ,1591.340087890625 ,1599.342529296875 ,1599.342529296875 ,1591.340087890625 ,1661.525634765625 ,1662.7359619140625 ,1665.25 ,1658.8890380859375 ,1665.7197265625 ,1637.8194580078125 ,1675.47314453125 ,1664.07568359375 ,1671.0203857421875 ,1682.659912109375 ,1661.525634765625 ,1633.1319580078125 ,1641.9266357421875 ,1604.1265869140625 ,1633.1319580078125 ,1661.525634765625 ,1653.708740234375 ,1653.762939453125 ,1659.3984375 ,1652.8292236328125 ,1665.7197265625 ,1662.984619140625 ,1665.7197265625 ,1652.8292236328125 ,1637.8194580078125 ,-9.217521667480469 ,-48.88777542114258 ,-40.22665023803711 ,-25.795822143554688 ,-9.217521667480469 ,-40.22665023803711 ,-13.471426010131836 ,-13.02388858795166 ,-16.721044540405273 ,-16.53158187866211 ,-17.79994010925293 ,-12.453563690185547 ,-8.995442390441895 ,-10.673930168151855 ,-11.213990211486816 ,-14.807839393615723 ,-3.8040237426757812 ,-20.40215301513672 ,1653.9100341796875 ,1661.525634765625 ,1651.9105224609375 ,1651.174560546875 ,1641.9266357421875 ,1642.8101806640625 ,1678.3294677734375 ,1681.4793701171875 ,1671.0203857421875 ,1661.7598876953125 ,1682.659912109375 ,1661.525634765625 ,1653.708740234375 ,1654.3704833984375 ,1653.762939453125 ,1682.659912109375 ,1655.0233154296875 ,1656.337158203125 ,1669.150634765625 ,1664.8780517578125 ,1682.659912109375 ,1661.525634765625 ,1651.174560546875 ,1651.9105224609375 ,1658.2060546875 ,1657.1690673828125 ,1658.8890380859375 ,1664.8780517578125 ,1655.0233154296875 ,1682.659912109375] } } + } } From 28b633b93a8459de0d7a792ee4a162bc7aac0398 Mon Sep 17 00:00:00 2001 From: nikolas Date: Tue, 10 Mar 2015 18:35:56 -0400 Subject: [PATCH 291/333] Fix typo in comment: mirorr -> mirror --- examples/webgl_mirror.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/webgl_mirror.html b/examples/webgl_mirror.html index 4d306530785923..86fba1dc97d50d 100644 --- a/examples/webgl_mirror.html +++ b/examples/webgl_mirror.html @@ -86,7 +86,7 @@ var planeGeo = new THREE.PlaneBufferGeometry( 100.1, 100.1 ); - // MIRORR planes + // MIRROR planes groundMirror = new THREE.Mirror( renderer, camera, { clipBias: 0.003, textureWidth: WIDTH, textureHeight: HEIGHT, color: 0x777777 } ); var mirrorMesh = new THREE.Mesh( planeGeo, groundMirror.material ); From 8fc585c6027527f665d2f7b5eeba674b1ed170c9 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 10 Mar 2015 23:47:44 +0000 Subject: [PATCH 292/333] Updated builds. --- build/three.js | 8 ++++---- build/three.min.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/three.js b/build/three.js index 697d74a5176ae7..740c3092f05f7f 100644 --- a/build/three.js +++ b/build/three.js @@ -12475,7 +12475,7 @@ THREE.BufferGeometryLoader.prototype = { var geometry = new THREE.BufferGeometry(); - var attributes = json.attributes; + var attributes = json.data.attributes; for ( var key in attributes ) { @@ -12486,7 +12486,7 @@ THREE.BufferGeometryLoader.prototype = { } - var offsets = json.offsets; + var offsets = json.data.offsets; if ( offsets !== undefined ) { @@ -12494,7 +12494,7 @@ THREE.BufferGeometryLoader.prototype = { } - var boundingSphere = json.boundingSphere; + var boundingSphere = json.data.boundingSphere; if ( boundingSphere !== undefined ) { @@ -12778,7 +12778,7 @@ THREE.ObjectLoader.prototype = { case 'BufferGeometry': - geometry = bufferGeometryLoader.parse( data.data ); + geometry = bufferGeometryLoader.parse( data ); break; diff --git a/build/three.min.js b/build/three.min.js index ffa1a58dc6a230..69802f3a2ddea8 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -274,16 +274,16 @@ v=new THREE.Vector2(v,n),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],t.normal.s c.skinIndices.length+"), and skinWeights ("+c.skinWeights.length+") should match.");c.animation=a.animation;c.animations=a.animations})();(function(b){if(void 0!==a.morphTargets){var d,g,h,k,l,p;d=0;for(g=a.morphTargets.length;d Date: Wed, 11 Mar 2015 13:01:43 +0800 Subject: [PATCH 293/333] Fix JS minification in build.js - uglify-js2 is now uglify-js - shader code is now included for minification - sourcemaps still does not work --- utils/build/build.js | 9 +++++---- utils/build/package.json | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/utils/build/build.js b/utils/build/build.js index ed6f5206df745e..e8ec81f01ba230 100644 --- a/utils/build/build.js +++ b/utils/build/build.js @@ -1,7 +1,7 @@ var fs = require("fs"); var path = require("path"); var argparse = require( "argparse" ); -var uglify = require("uglify-js2"); +var uglify = require("uglify-js"); var spawn = require('child_process').spawn; function main() { @@ -34,7 +34,8 @@ function main() { var buffer = []; var sources = []; - + // TODO - sources are not being used. should remove and make sourcemaps work with uglify + if ( args.amd ){ buffer.push('function ( root, factory ) {\n\n\tif ( typeof define === \'function\' && define.amd ) {\n\n\t\tdefine( [ \'exports\' ], factory );\n\n\t} else if ( typeof exports === \'object\' ) {\n\n\t\tfactory( exports );\n\n\t} else {\n\n\t\tfactory( root );\n\n\t}\n\n}( this, function ( exports ) {\n\n'); }; @@ -79,11 +80,11 @@ function main() { if ( !args.minify ){ - fs.writeFileSync( output,temp, 'utf8' ); + fs.writeFileSync( output, temp, 'utf8' ); } else { - var result = uglify.minify( sources, { outSourceMap: sourcemap } ); + var result = uglify.minify( temp, { outSourceMap: sourcemap, fromString: true } ); fs.writeFileSync( output, '// threejs.org/license\n' + result.code + sourcemapping, 'utf8' ); diff --git a/utils/build/package.json b/utils/build/package.json index c5aa6e818b14ee..b465eb34e4d2d6 100644 --- a/utils/build/package.json +++ b/utils/build/package.json @@ -9,8 +9,8 @@ }, "devDependencies": { - "uglify-js2": "*", - "argparse" : "*" + "uglify-js": "^2.4.17", + "argparse" : "*" }, "repository" : { From 0fd040f4f220b446e91465190ce80fac7df778e6 Mon Sep 17 00:00:00 2001 From: repsac Date: Tue, 10 Mar 2015 22:40:31 -0700 Subject: [PATCH 294/333] Added Preset Dropdown Removed settings cache file Removed logger from addon --- .../blender/addons/io_three/__init__.py | 187 +----------------- 1 file changed, 8 insertions(+), 179 deletions(-) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index b8a05893cb3158..d2e1be407f8c10 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -18,7 +18,6 @@ import os import json -import logging import bpy from bpy_extras.io_utils import ExportHelper @@ -32,17 +31,10 @@ from . import constants -logging.basicConfig( - format='%(levelname)s:THREE:%(message)s', - level=logging.DEBUG) - -SETTINGS_FILE_EXPORT = 'three_settings_export.js' - - bl_info = { 'name': "Three.js Format", - 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks", - 'version': (1, 3, 1), + 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks, rkusa", + 'version': (1, 4, 0), 'blender': (2, 7, 3), 'location': "File > Export", 'description': "Export Three.js formatted JSON files.", @@ -53,6 +45,7 @@ 'category': 'Import-Export' } + def _geometry_types(): """The valid geometry types that are supported by Three.js @@ -257,17 +250,9 @@ def draw(self, context): row = layout.row() row.prop(obj, 'THREE_export', text='Export') -def get_settings_fullpath(): - """ - - :returns: Full path to the settings file (temp directory) - - """ - return os.path.join(bpy.app.tempdir, SETTINGS_FILE_EXPORT) - -def save_settings_export(properties): - """Save the current export settings to disk. +def set_settings(properties): + """Set the export settings to the correct keys. :param properties: :returns: settings @@ -312,166 +297,9 @@ def save_settings_export(properties): constants.INFLUENCES_PER_VERTEX: properties.option_influences } - fname = get_settings_fullpath() - logging.debug("Saving settings to %s", fname) - with open(fname, 'w') as stream: - json.dump(settings, stream) - return settings -def restore_settings_export(properties): - """Restore the settings (if settings file is found on disk) - If not found thend default to paramgers defined in - constants.EXPORT_OPTIONS - - :param properties: - - """ - - settings = {} - - fname = get_settings_fullpath() - if os.path.exists(fname) and os.access(fname, os.R_OK): - logging.debug("Settings cache found %s", fname) - with open(fname, 'r') as fs: - settings = json.load(fs) - else: - logging.debug("No settings file found, using defaults.") - - ## Geometry { - properties.option_vertices = settings.get( - constants.VERTICES, - constants.EXPORT_OPTIONS[constants.VERTICES]) - - properties.option_faces = settings.get( - constants.FACES, - constants.EXPORT_OPTIONS[constants.FACES]) - properties.option_normals = settings.get( - constants.NORMALS, - constants.EXPORT_OPTIONS[constants.NORMALS]) - - properties.option_skinning = settings.get( - constants.SKINNING, - constants.EXPORT_OPTIONS[constants.SKINNING]) - - properties.option_bones = settings.get( - constants.BONES, - constants.EXPORT_OPTIONS[constants.BONES]) - - properties.option_influences = settings.get( - constants.INFLUENCES_PER_VERTEX, - constants.EXPORT_OPTIONS[constants.INFLUENCES_PER_VERTEX]) - - properties.option_geometry_type = settings.get( - constants.GEOMETRY_TYPE, - constants.EXPORT_OPTIONS[constants.GEOMETRY_TYPE]) - ## } - - ## Materials { - properties.option_materials = settings.get( - constants.MATERIALS, - constants.EXPORT_OPTIONS[constants.MATERIALS]) - - properties.option_uv_coords = settings.get( - constants.UVS, - constants.EXPORT_OPTIONS[constants.UVS]) - - properties.option_face_materials = settings.get( - constants.FACE_MATERIALS, - constants.EXPORT_OPTIONS[constants.FACE_MATERIALS]) - - properties.option_maps = settings.get( - constants.MAPS, - constants.EXPORT_OPTIONS[constants.MAPS]) - - properties.option_colors = settings.get( - constants.COLORS, - constants.EXPORT_OPTIONS[constants.COLORS]) - - properties.option_mix_colors = settings.get( - constants.MIX_COLORS, - constants.EXPORT_OPTIONS[constants.MIX_COLORS]) - ## } - - ## Settings { - properties.option_scale = settings.get( - constants.SCALE, - constants.EXPORT_OPTIONS[constants.SCALE]) - - properties.option_round_off = settings.get( - constants.ENABLE_PRECISION, - constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION]) - - properties.option_round_value = settings.get( - constants.PRECISION, - constants.EXPORT_OPTIONS[constants.PRECISION]) - - properties.option_logging = settings.get( - constants.LOGGING, - constants.EXPORT_OPTIONS[constants.LOGGING]) - - properties.option_compression = settings.get( - constants.COMPRESSION, - constants.NONE) - - properties.option_indent = settings.get( - constants.INDENT, - constants.EXPORT_OPTIONS[constants.INDENT]) - - properties.option_copy_textures = settings.get( - constants.COPY_TEXTURES, - constants.EXPORT_OPTIONS[constants.COPY_TEXTURES]) - - properties.option_texture_folder = settings.get( - constants.TEXTURE_FOLDER, - constants.EXPORT_OPTIONS[constants.TEXTURE_FOLDER]) - - properties.option_embed_animation = settings.get( - constants.EMBED_ANIMATION, - constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION]) - ## } - - ## Scene { - properties.option_export_scene = settings.get( - constants.SCENE, - constants.EXPORT_OPTIONS[constants.SCENE]) - - #properties.option_embed_geometry = settings.get( - # constants.EMBED_GEOMETRY, - # constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY]) - - properties.option_lights = settings.get( - constants.LIGHTS, - constants.EXPORT_OPTIONS[constants.LIGHTS]) - - properties.option_cameras = settings.get( - constants.CAMERAS, - constants.EXPORT_OPTIONS[constants.CAMERAS]) - - properties.option_hierarchy = settings.get( - constants.HIERARCHY, - constants.EXPORT_OPTIONS[constants.HIERARCHY]) - ## } - - ## Animation { - properties.option_animation_morph = settings.get( - constants.MORPH_TARGETS, - constants.EXPORT_OPTIONS[constants.MORPH_TARGETS]) - - properties.option_animation_skeletal = settings.get( - constants.ANIMATION, - constants.EXPORT_OPTIONS[constants.ANIMATION]) - - properties.option_frame_step = settings.get( - constants.FRAME_STEP, - constants.EXPORT_OPTIONS[constants.FRAME_STEP]) - - properties.option_frame_index_as_time = settings.get( - constants.FRAME_INDEX_AS_TIME, - constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME]) - ## } - def compression_types(): """Supported compression formats @@ -489,6 +317,7 @@ def compression_types(): return types + def animation_options(): """The supported skeletal animation types @@ -508,6 +337,7 @@ class ExportThree(bpy.types.Operator, ExportHelper): bl_idname = 'export.three' bl_label = 'Export THREE' + bl_options = {'PRESET'} filename_ext = constants.EXTENSION @@ -692,7 +522,6 @@ class ExportThree(bpy.types.Operator, ExportHelper): default=2) def invoke(self, context, event): - restore_settings_export(self.properties) return ExportHelper.invoke(self, context, event) @classmethod @@ -713,7 +542,7 @@ def execute(self, context): if not self.properties.filepath: raise Exception("filename not set") - settings = save_settings_export(self.properties) + settings = set_settings(self.properties) settings['addon_version'] = bl_info['version'] filepath = self.filepath From 96bbf36a5d5261533e252498a7922c5e04ebf6ed Mon Sep 17 00:00:00 2001 From: brason Date: Wed, 11 Mar 2015 12:20:22 +0100 Subject: [PATCH 295/333] Removed dead code Not a big deal, but noticed some unused variables. I assume they can be removed? --- src/renderers/WebGLRenderer.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 8bf5ed92afe555..f63545445de028 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -132,7 +132,6 @@ THREE.WebGLRenderer = function ( parameters ) { // camera matrices cache _projScreenMatrix = new THREE.Matrix4(), - _projScreenMatrixPS = new THREE.Matrix4(), _vector3 = new THREE.Vector3(), @@ -300,11 +299,9 @@ THREE.WebGLRenderer = function ( parameters ) { var _vertexShaderPrecisionHighpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.HIGH_FLOAT ); var _vertexShaderPrecisionMediumpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.MEDIUM_FLOAT ); - var _vertexShaderPrecisionLowpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.LOW_FLOAT ); var _fragmentShaderPrecisionHighpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.HIGH_FLOAT ); var _fragmentShaderPrecisionMediumpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.MEDIUM_FLOAT ); - var _fragmentShaderPrecisionLowpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.LOW_FLOAT ); var getCompressedTextureFormats = ( function () { @@ -1020,8 +1017,6 @@ THREE.WebGLRenderer = function ( parameters ) { geometry.__vertexArray = new Float32Array( nvertices * 3 ); geometry.__colorArray = new Float32Array( nvertices * 3 ); - geometry.__sortArray = []; - geometry.__webglParticleCount = nvertices; initCustomAttributes( object ); @@ -1202,10 +1197,7 @@ THREE.WebGLRenderer = function ( parameters ) { vertexArray = geometry.__vertexArray, colorArray = geometry.__colorArray, - sortArray = geometry.__sortArray, - dirtyVertices = geometry.verticesNeedUpdate, - dirtyElements = geometry.elementsNeedUpdate, dirtyColors = geometry.colorsNeedUpdate, customAttributes = geometry.__webglCustomAttributesList, @@ -1557,7 +1549,6 @@ THREE.WebGLRenderer = function ( parameters ) { offset_skin = 0, offset_morphTarget = 0, offset_custom = 0, - offset_customSrc = 0, value, @@ -1597,8 +1588,6 @@ THREE.WebGLRenderer = function ( parameters ) { obj_uvs = geometry.faceVertexUvs[ 0 ], obj_uvs2 = geometry.faceVertexUvs[ 1 ], - obj_colors = geometry.colors, - obj_skinIndices = geometry.skinIndices, obj_skinWeights = geometry.skinWeights, @@ -2021,7 +2010,6 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! customAttribute.__original.needsUpdate ) continue; offset_custom = 0; - offset_customSrc = 0; if ( customAttribute.size === 1 ) { From 035b586b4f36a567e9cd69a0aba75f2f89e5e8ff Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 11 Mar 2015 16:55:18 +0000 Subject: [PATCH 296/333] Updated builds. --- build/three.js | 12 ------ build/three.min.js | 105 ++++++++++++++++++++++----------------------- 2 files changed, 52 insertions(+), 65 deletions(-) diff --git a/build/three.js b/build/three.js index 740c3092f05f7f..2b67a30a2731f0 100644 --- a/build/three.js +++ b/build/three.js @@ -17904,7 +17904,6 @@ THREE.WebGLRenderer = function ( parameters ) { // camera matrices cache _projScreenMatrix = new THREE.Matrix4(), - _projScreenMatrixPS = new THREE.Matrix4(), _vector3 = new THREE.Vector3(), @@ -18072,11 +18071,9 @@ THREE.WebGLRenderer = function ( parameters ) { var _vertexShaderPrecisionHighpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.HIGH_FLOAT ); var _vertexShaderPrecisionMediumpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.MEDIUM_FLOAT ); - var _vertexShaderPrecisionLowpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.LOW_FLOAT ); var _fragmentShaderPrecisionHighpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.HIGH_FLOAT ); var _fragmentShaderPrecisionMediumpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.MEDIUM_FLOAT ); - var _fragmentShaderPrecisionLowpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.LOW_FLOAT ); var getCompressedTextureFormats = ( function () { @@ -18792,8 +18789,6 @@ THREE.WebGLRenderer = function ( parameters ) { geometry.__vertexArray = new Float32Array( nvertices * 3 ); geometry.__colorArray = new Float32Array( nvertices * 3 ); - geometry.__sortArray = []; - geometry.__webglParticleCount = nvertices; initCustomAttributes( object ); @@ -18974,10 +18969,7 @@ THREE.WebGLRenderer = function ( parameters ) { vertexArray = geometry.__vertexArray, colorArray = geometry.__colorArray, - sortArray = geometry.__sortArray, - dirtyVertices = geometry.verticesNeedUpdate, - dirtyElements = geometry.elementsNeedUpdate, dirtyColors = geometry.colorsNeedUpdate, customAttributes = geometry.__webglCustomAttributesList, @@ -19329,7 +19321,6 @@ THREE.WebGLRenderer = function ( parameters ) { offset_skin = 0, offset_morphTarget = 0, offset_custom = 0, - offset_customSrc = 0, value, @@ -19369,8 +19360,6 @@ THREE.WebGLRenderer = function ( parameters ) { obj_uvs = geometry.faceVertexUvs[ 0 ], obj_uvs2 = geometry.faceVertexUvs[ 1 ], - obj_colors = geometry.colors, - obj_skinIndices = geometry.skinIndices, obj_skinWeights = geometry.skinWeights, @@ -19793,7 +19782,6 @@ THREE.WebGLRenderer = function ( parameters ) { if ( ! customAttribute.__original.needsUpdate ) continue; offset_custom = 0; - offset_customSrc = 0; if ( customAttribute.size === 1 ) { diff --git a/build/three.min.js b/build/three.min.js index 69802f3a2ddea8..a5516349452b00 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -445,14 +445,14 @@ THREE.WebGLRenderer=function(a){function b(a){var b=a.geometry;a=a.material;var m.vertexAttrib2fv(k,a.defaultAttributeValues[h]):3===a.defaultAttributeValues[h].length&&m.vertexAttrib3fv(k,a.defaultAttributeValues[h]))}}W.disableUnusedAttributes()}function e(a,b){return a.object.renderOrder!==b.object.renderOrder?a.object.renderOrder-b.object.renderOrder:a.material.id!==b.material.id?a.material.id-b.material.id:a.z!==b.z?a.z-b.z:a.id-b.id}function f(a,b){return a.object.renderOrder!==b.object.renderOrder?a.object.renderOrder-b.object.renderOrder:a.z!==b.z?b.z-a.z:a.id-b.id}function g(a, b){return b[0]-a[0]}function h(a){if(!1!==a.visible){if(!(a instanceof THREE.Scene||a instanceof THREE.Group)){void 0===a.__webglInit&&(a.__webglInit=!0,a._modelViewMatrix=new THREE.Matrix4,a._normalMatrix=new THREE.Matrix3,a.addEventListener("removed",wb));var c=a.geometry;if(void 0!==c&&void 0===c.__webglInit)if(c.__webglInit=!0,c.addEventListener("dispose",jb),c instanceof THREE.BufferGeometry)B.info.memory.geometries++;else if(a instanceof THREE.Mesh)q(a,c);else if(a instanceof THREE.Line){if(void 0=== c.__webglVertexBuffer){c.__webglVertexBuffer=m.createBuffer();c.__webglColorBuffer=m.createBuffer();c.__webglLineDistanceBuffer=m.createBuffer();B.info.memory.geometries++;var d=c.vertices.length;c.__vertexArray=new Float32Array(3*d);c.__colorArray=new Float32Array(3*d);c.__lineDistanceArray=new Float32Array(1*d);c.__webglLineCount=d;b(a);c.verticesNeedUpdate=!0;c.colorsNeedUpdate=!0;c.lineDistancesNeedUpdate=!0}}else a instanceof THREE.PointCloud&&void 0===c.__webglVertexBuffer&&(c.__webglVertexBuffer= -m.createBuffer(),c.__webglColorBuffer=m.createBuffer(),B.info.memory.geometries++,d=c.vertices.length,c.__vertexArray=new Float32Array(3*d),c.__colorArray=new Float32Array(3*d),c.__sortArray=[],c.__webglParticleCount=d,b(a),c.verticesNeedUpdate=!0,c.colorsNeedUpdate=!0);if(void 0===a.__webglActive)if(a.__webglActive=!0,a instanceof THREE.Mesh)if(c instanceof THREE.BufferGeometry)n(ba,c,a);else{if(c instanceof THREE.Geometry)for(var c=Ua[c.id],d=0,e=c.length;dh&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in r||(q={id:Qb++,faces3:[],materialIndex:u,vertices:0, -numMorphTargets:l,numMorphNormals:p},r[k]=q,t.push(q)));r[k].faces3.push(s);r[k].vertices+=3}f[g]=t;b.groupsNeedUpdate=!1}f=Ua[b.id];g=0;for(d=f.length;gh&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in r||(q={id:Qb++,faces3:[],materialIndex:u,vertices:0,numMorphTargets:l, +numMorphNormals:p},r[k]=q,t.push(q)));r[k].faces3.push(s);r[k].vertices+=3}f[g]=t;b.groupsNeedUpdate=!1}f=Ua[b.id];g=0;for(d=f.length;gb;b++)m.deleteFramebuffer(a.__webglFramebuffer[b]),m.deleteRenderbuffer(a.__webglRenderbuffer[b]);else m.deleteFramebuffer(a.__webglFramebuffer), -m.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},ic=function(a){a=a.target;a.removeEventListener("dispose",ic);hc(a)},nc=function(a){for(var b="__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;ch.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."), -n.length=h.length);h=0;for(l=n.length;hd.numSupportedMorphTargets?(k.sort(g),k.length=d.numSupportedMorphTargets):k.length>d.numSupportedMorphNormals?k.sort(g):0===k.length&&k.push([0,0]);for(var h=0,p=d.numSupportedMorphTargets;hf;f++){a.__webglFramebuffer[f]=m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0, -h,g.__webglTexture,0);G(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:m.createRenderbuffer(),m.bindTexture(m.TEXTURE_2D,a.__webglTexture),A(m.TEXTURE_2D,a,c),m.texImage2D(m.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=m.TEXTURE_2D,m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,d,a.__webglTexture, -0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):G(a.__webglRenderbuffer,a),c&&m.generateMipmap(m.TEXTURE_2D);b?m.bindTexture(m.TEXTURE_CUBE_MAP,null):m.bindTexture(m.TEXTURE_2D,null);m.bindRenderbuffer(m.RENDERBUFFER,null);m.bindFramebuffer(m.FRAMEBUFFER,null)}a? -(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=pb,a=qb,d=ib,e=bb);b!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,b),m.viewport(d,e,c,a),ab=b);Xb=c;fc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); +lc();this.context=m;this.state=W;var Wb=m.getParameter(m.MAX_TEXTURE_IMAGE_UNITS),sc=m.getParameter(m.MAX_VERTEX_TEXTURE_IMAGE_UNITS),tc=m.getParameter(m.MAX_TEXTURE_SIZE),qc=m.getParameter(m.MAX_CUBE_MAP_TEXTURE_SIZE),Vb=0b;b++)m.deleteFramebuffer(a.__webglFramebuffer[b]),m.deleteRenderbuffer(a.__webglRenderbuffer[b]);else m.deleteFramebuffer(a.__webglFramebuffer),m.deleteRenderbuffer(a.__webglRenderbuffer);delete a.__webglFramebuffer;delete a.__webglRenderbuffer}B.info.memory.textures--},ic=function(a){a=a.target;a.removeEventListener("dispose",ic);hc(a)},nc=function(a){for(var b= +"__webglVertexBuffer __webglNormalBuffer __webglTangentBuffer __webglColorBuffer __webglUVBuffer __webglUV2Buffer __webglSkinIndicesBuffer __webglSkinWeightsBuffer __webglFaceBuffer __webglLineBuffer __webglLineDistanceBuffer".split(" "),c=0,d=b.length;ch.length&&(console.warn("THREE.WebGLRenderer: Influences array is bigger than morphTargets array."),n.length=h.length);h=0;for(l=n.length;hd.numSupportedMorphTargets?(k.sort(g),k.length=d.numSupportedMorphTargets):k.length>d.numSupportedMorphNormals?k.sort(g):0===k.length&&k.push([0,0]);for(var h=0,p=d.numSupportedMorphTargets;hf;f++){a.__webglFramebuffer[f]=m.createFramebuffer();a.__webglRenderbuffer[f]=m.createRenderbuffer();m.texImage2D(m.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=m.TEXTURE_CUBE_MAP_POSITIVE_X+f;m.bindFramebuffer(m.FRAMEBUFFER, +a.__webglFramebuffer[f]);m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,h,g.__webglTexture,0);G(a.__webglRenderbuffer[f],a)}c&&m.generateMipmap(m.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=m.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:m.createRenderbuffer(),m.bindTexture(m.TEXTURE_2D,a.__webglTexture),A(m.TEXTURE_2D,a,c),m.texImage2D(m.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=m.TEXTURE_2D,m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer), +m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_STENCIL_ATTACHMENT,m.RENDERBUFFER,a.__webglRenderbuffer):G(a.__webglRenderbuffer,a),c&&m.generateMipmap(m.TEXTURE_2D);b?m.bindTexture(m.TEXTURE_CUBE_MAP,null):m.bindTexture(m.TEXTURE_2D,null);m.bindRenderbuffer(m.RENDERBUFFER, +null);m.bindFramebuffer(m.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=pb,a=qb,d=ib,e=bb);b!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,b),m.viewport(d,e,c,a),ab=b);Xb=c;fc=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(a.__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); else{var g=!1;a.__webglFramebuffer!==ab&&(m.bindFramebuffer(m.FRAMEBUFFER,a.__webglFramebuffer),g=!0);m.checkFramebufferStatus(m.FRAMEBUFFER)===m.FRAMEBUFFER_COMPLETE?m.readPixels(b,c,d,e,m.RGBA,m.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&m.bindFramebuffer(m.FRAMEBUFFER,ab)}};this.initMaterial=function(){THREE.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}; this.addPostPlugin=function(){THREE.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){THREE.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: From 197fc4cb344019710c1e852eca3991d7c410a62a Mon Sep 17 00:00:00 2001 From: WestLangley Date: Wed, 11 Mar 2015 17:02:01 -0400 Subject: [PATCH 297/333] Miscellaneous cleanup --- examples/js/ShaderDeferred.js | 4 ++-- examples/js/shaders/NormalDisplacementShader.js | 4 ++-- src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/js/ShaderDeferred.js b/examples/js/ShaderDeferred.js index db6cf7d0c58463..f0b93d6438c09f 100644 --- a/examples/js/ShaderDeferred.js +++ b/examples/js/ShaderDeferred.js @@ -241,7 +241,7 @@ THREE.ShaderDeferred = { "} else {", - "outgoingLight = mix( outgoingLight.xyz, diffuseColor.xyz * cubeColor.xyz, specularStrength * reflectivity );", + "outgoingLight = mix( outgoingLight, diffuseColor.xyz * cubeColor.xyz, specularStrength * reflectivity );", "}", @@ -270,7 +270,7 @@ THREE.ShaderDeferred = { // diffuse color - "gl_FragColor.x = vec3_to_float( compressionScale * outgoingLight.xyz );", + "gl_FragColor.x = vec3_to_float( compressionScale * outgoingLight );", // specular color diff --git a/examples/js/shaders/NormalDisplacementShader.js b/examples/js/shaders/NormalDisplacementShader.js index 2cd81d05b865cf..cebb8f5f9c0ef3 100644 --- a/examples/js/shaders/NormalDisplacementShader.js +++ b/examples/js/shaders/NormalDisplacementShader.js @@ -387,7 +387,7 @@ THREE.NormalDisplacementShader = { " #ifdef METAL", - " outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse + totalSpecularLight );", + " outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + totalSpecularLight );", " #else", @@ -417,7 +417,7 @@ THREE.NormalDisplacementShader = { " #endif", - " outgoingLight = mix( outgoingLight.xyz, cubeColor.xyz, specularTex.r * reflectivity );", + " outgoingLight = mix( outgoingLight, cubeColor.xyz, specularTex.r * reflectivity );", " }", diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 5c0b6956e95dab..ff829891b75ac6 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -234,7 +234,7 @@ vec3 totalSpecularLight = vec3( 0.0 ); #ifdef METAL - outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * diffuse ) * specular + totalSpecularLight + emissive; + outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) * specular + totalSpecularLight + emissive; #else From 38c2150e69fd92bf35630af6deb1f57b7957ab56 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 11 Mar 2015 21:52:18 +0000 Subject: [PATCH 298/333] Minor code clean up. --- src/core/Object3D.js | 2 +- src/renderers/WebGLRenderer.js | 36 +++++++++++++++++----------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 1709671a3ad847..ea2f8ddc743db0 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -53,7 +53,7 @@ THREE.Object3D = function () { scale: { enumerable: true, value: scale - }, + } } ); this.rotationAutoUpdate = true; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index f63545445de028..789bbe0dd3c37b 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -4755,29 +4755,29 @@ THREE.WebGLRenderer = function ( parameters ) { // If uniforms are marked as clean, they don't need to be loaded to the GPU. - function markUniformsLightsNeedsUpdate ( uniforms, boolean ) { + function markUniformsLightsNeedsUpdate ( uniforms, value ) { - uniforms.ambientLightColor.needsUpdate = boolean; + uniforms.ambientLightColor.needsUpdate = value; - uniforms.directionalLightColor.needsUpdate = boolean; - uniforms.directionalLightDirection.needsUpdate = boolean; + uniforms.directionalLightColor.needsUpdate = value; + uniforms.directionalLightDirection.needsUpdate = value; - uniforms.pointLightColor.needsUpdate = boolean; - uniforms.pointLightPosition.needsUpdate = boolean; - uniforms.pointLightDistance.needsUpdate = boolean; - uniforms.pointLightDecay.needsUpdate = boolean; + uniforms.pointLightColor.needsUpdate = value; + uniforms.pointLightPosition.needsUpdate = value; + uniforms.pointLightDistance.needsUpdate = value; + uniforms.pointLightDecay.needsUpdate = value; - uniforms.spotLightColor.needsUpdate = boolean; - uniforms.spotLightPosition.needsUpdate = boolean; - uniforms.spotLightDistance.needsUpdate = boolean; - uniforms.spotLightDirection.needsUpdate = boolean; - uniforms.spotLightAngleCos.needsUpdate = boolean; - uniforms.spotLightExponent.needsUpdate = boolean; - uniforms.spotLightDecay.needsUpdate = boolean; + uniforms.spotLightColor.needsUpdate = value; + uniforms.spotLightPosition.needsUpdate = value; + uniforms.spotLightDistance.needsUpdate = value; + uniforms.spotLightDirection.needsUpdate = value; + uniforms.spotLightAngleCos.needsUpdate = value; + uniforms.spotLightExponent.needsUpdate = value; + uniforms.spotLightDecay.needsUpdate = value; - uniforms.hemisphereLightSkyColor.needsUpdate = boolean; - uniforms.hemisphereLightGroundColor.needsUpdate = boolean; - uniforms.hemisphereLightDirection.needsUpdate = boolean; + uniforms.hemisphereLightSkyColor.needsUpdate = value; + uniforms.hemisphereLightGroundColor.needsUpdate = value; + uniforms.hemisphereLightDirection.needsUpdate = value; } From 700d9c23c8cef1d89837463fb6c69152231b01d6 Mon Sep 17 00:00:00 2001 From: WestLangley Date: Wed, 11 Mar 2015 17:58:57 -0400 Subject: [PATCH 299/333] Lambert:: calculate incoming light in vertex shader; outgoing light in fragment shader. --- .../ShaderChunk/lights_lambert_pars_vertex.glsl | 3 --- .../shaders/ShaderChunk/lights_lambert_vertex.glsl | 4 ++-- src/renderers/shaders/ShaderLib.js | 11 +++++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl index bbebfac755763c..ee521477b21209 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl @@ -1,6 +1,3 @@ -uniform vec3 diffuse; -uniform vec3 emissive; - uniform vec3 ambientLightColor; #if MAX_DIR_LIGHTS > 0 diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 1fddd3e2aeeef4..864b07ca5bff46 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -187,10 +187,10 @@ for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { #endif -vLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive; +vLightFront += ambientLightColor; #ifdef DOUBLE_SIDED - vLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive; + vLightBack += ambientLightColor; #endif diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 5119fdeeb348a8..09d6acd418557a 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -171,8 +171,11 @@ THREE.ShaderLib = { fragmentShader: [ + "uniform vec3 diffuse;", "uniform float opacity;", + "uniform vec3 emissive;", + "varying vec3 vLightFront;", "#ifdef DOUBLE_SIDED", @@ -195,7 +198,7 @@ THREE.ShaderLib = { "void main() {", " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does - " vec4 diffuseColor = vec4( 1.0, 1.0, 1.0, opacity );", + " vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], @@ -210,13 +213,13 @@ THREE.ShaderLib = { //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;", " if ( gl_FrontFacing )", - " outgoingLight += diffuseColor.rgb * vLightFront;", + " outgoingLight += diffuseColor.rgb * vLightFront + emissive;", " else", - " outgoingLight += diffuseColor.rgb * vLightBack;", + " outgoingLight += diffuseColor.rgb * vLightBack + emissive;", " #else", - " outgoingLight += diffuseColor.rgb * vLightFront;", + " outgoingLight += diffuseColor.rgb * vLightFront + emissive;", " #endif", From 24a55ee5a6a0938afd406cecd581c46516ce355a Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 11 Mar 2015 22:11:14 +0000 Subject: [PATCH 300/333] ShaderLib: Minor code clean up. --- src/renderers/shaders/ShaderLib.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 09d6acd418557a..6ff73d1800c515 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -172,10 +172,10 @@ THREE.ShaderLib = { fragmentShader: [ "uniform vec3 diffuse;", - "uniform float opacity;", - "uniform vec3 emissive;", + "uniform float opacity;", + "varying vec3 vLightFront;", "#ifdef DOUBLE_SIDED", From a0c4d1092de00b998b59ce0b267fb1f621861c2c Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 11 Mar 2015 22:11:35 +0000 Subject: [PATCH 301/333] Updated builds. --- build/three.js | 55 ++++++++++++++++++++++++---------------------- build/three.min.js | 18 +++++++-------- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/build/three.js b/build/three.js index 2b67a30a2731f0..0432e1aab21fb5 100644 --- a/build/three.js +++ b/build/three.js @@ -7457,7 +7457,7 @@ THREE.Object3D = function () { scale: { enumerable: true, value: scale - }, + } } ); this.rotationAutoUpdate = true; @@ -16576,7 +16576,7 @@ THREE.ShaderChunk[ 'alphatest_fragment'] = "#ifdef ALPHATEST\n\n if ( diffuseCol // File:src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl -THREE.ShaderChunk[ 'lights_lambert_vertex'] = "vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n vLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n float dotProduct = dot( transformedNormal, dirVector );\n vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n #endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n float dotProduct = dot( transformedNormal, lVector );\n\n vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n #endif\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float dotProduct = dot( transformedNormal, lVector );\n vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n #endif\n\n }\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n float dotProduct = dot( transformedNormal, lVector );\n\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n #endif\n\n }\n\n#endif\n\nvLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive;\n\n#ifdef DOUBLE_SIDED\n\n vLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive;\n\n#endif\n"; +THREE.ShaderChunk[ 'lights_lambert_vertex'] = "vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n vLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n float dotProduct = dot( transformedNormal, dirVector );\n vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n #endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n float dotProduct = dot( transformedNormal, lVector );\n\n vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n #endif\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float dotProduct = dot( transformedNormal, lVector );\n vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n #ifdef DOUBLE_SIDED\n\n vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n #ifdef WRAP_AROUND\n\n vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n #endif\n\n #endif\n\n #ifdef WRAP_AROUND\n\n vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n #ifdef DOUBLE_SIDED\n\n spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n #endif\n\n #endif\n\n vLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n #endif\n\n }\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n float dotProduct = dot( transformedNormal, lVector );\n\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n #ifdef DOUBLE_SIDED\n\n vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n #endif\n\n }\n\n#endif\n\nvLightFront += ambientLightColor;\n\n#ifdef DOUBLE_SIDED\n\n vLightBack += ambientLightColor;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/map_particle_pars_fragment.glsl @@ -16604,7 +16604,7 @@ THREE.ShaderChunk[ 'lightmap_pars_vertex'] = "#ifdef USE_LIGHTMAP\n\n varying ve // File:src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_fragment'] = "#ifndef FLAT_SHADED\n\n vec3 normal = normalize( vNormal );\n\n #ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n #endif\n\n#else\n\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\nvec3 totalDiffuseLight = vec3( 0.0 );\nvec3 totalSpecularLight = vec3( 0.0 );\n\n#if MAX_POINT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n totalDiffuseLight += hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\n#ifdef METAL\n\n outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * diffuse ) * specular + totalSpecularLight + emissive;\n\n#else\n\n outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive;\n\n#endif\n"; +THREE.ShaderChunk[ 'lights_phong_fragment'] = "#ifndef FLAT_SHADED\n\n vec3 normal = normalize( vNormal );\n\n #ifdef DOUBLE_SIDED\n\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n #endif\n\n#else\n\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n normal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\nvec3 totalDiffuseLight = vec3( 0.0 );\nvec3 totalSpecularLight = vec3( 0.0 );\n\n#if MAX_POINT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float pointDiffuseWeightFull = max( dotProduct, 0.0 );\n float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float pointDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n // specular\n\n vec3 pointHalfVector = normalize( lVector + viewPosition );\n float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n }\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n vec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n lVector = normalize( lVector );\n\n float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n if ( spotEffect > spotLightAngleCos[ i ] ) {\n\n spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n\n #ifdef WRAP_AROUND\n\n float spotDiffuseWeightFull = max( dotProduct, 0.0 );\n float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float spotDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n // specular\n\n vec3 spotHalfVector = normalize( lVector + viewPosition );\n float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n }\n\n }\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, dirVector );\n\n #ifdef WRAP_AROUND\n\n float dirDiffuseWeightFull = max( dotProduct, 0.0 );\n float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n #else\n\n float dirDiffuseWeight = max( dotProduct, 0.0 );\n\n #endif\n\n totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;\n\n // specular\n\n vec3 dirHalfVector = normalize( dirVector + viewPosition );\n float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n /*\n // fresnel term from skin shader\n const float F0 = 0.128;\n\n float base = 1.0 - dot( viewPosition, dirHalfVector );\n float exponential = pow( base, 5.0 );\n\n float fresnel = exponential + F0 * ( 1.0 - exponential );\n */\n\n /*\n // fresnel term from fresnel shader\n const float mFresnelBias = 0.08;\n const float mFresnelScale = 0.3;\n const float mFresnelPower = 5.0;\n\n float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n */\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n }\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n // diffuse\n\n float dotProduct = dot( normal, lVector );\n float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n totalDiffuseLight += hemiColor;\n\n // specular (sky light)\n\n vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n // specular (ground light)\n\n vec3 lVectorGround = -lVector;\n\n vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n float dotProductGround = dot( normal, lVectorGround );\n\n float specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n }\n\n#endif\n\n#ifdef METAL\n\n outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) * specular + totalSpecularLight + emissive;\n\n#else\n\n outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl @@ -16680,7 +16680,7 @@ THREE.ShaderChunk[ 'color_pars_vertex'] = "#ifdef USE_COLOR\n\n varying vec3 vCo // File:src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl -THREE.ShaderChunk[ 'lights_lambert_pars_vertex'] = "uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n uniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n uniform vec3 wrapRGB;\n\n#endif\n"; +THREE.ShaderChunk[ 'lights_lambert_pars_vertex'] = "uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n uniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n uniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n uniform vec3 wrapRGB;\n\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/map_pars_vertex.glsl @@ -17129,6 +17129,9 @@ THREE.ShaderLib = { fragmentShader: [ + "uniform vec3 diffuse;", + "uniform vec3 emissive;", + "uniform float opacity;", "varying vec3 vLightFront;", @@ -17153,7 +17156,7 @@ THREE.ShaderLib = { "void main() {", " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does - " vec4 diffuseColor = vec4( 1.0, 1.0, 1.0, opacity );", + " vec4 diffuseColor = vec4( diffuse, opacity );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], @@ -17168,13 +17171,13 @@ THREE.ShaderLib = { //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;", " if ( gl_FrontFacing )", - " outgoingLight += diffuseColor.rgb * vLightFront;", + " outgoingLight += diffuseColor.rgb * vLightFront + emissive;", " else", - " outgoingLight += diffuseColor.rgb * vLightBack;", + " outgoingLight += diffuseColor.rgb * vLightBack + emissive;", " #else", - " outgoingLight += diffuseColor.rgb * vLightFront;", + " outgoingLight += diffuseColor.rgb * vLightFront + emissive;", " #endif", @@ -22527,29 +22530,29 @@ THREE.WebGLRenderer = function ( parameters ) { // If uniforms are marked as clean, they don't need to be loaded to the GPU. - function markUniformsLightsNeedsUpdate ( uniforms, boolean ) { + function markUniformsLightsNeedsUpdate ( uniforms, value ) { - uniforms.ambientLightColor.needsUpdate = boolean; + uniforms.ambientLightColor.needsUpdate = value; - uniforms.directionalLightColor.needsUpdate = boolean; - uniforms.directionalLightDirection.needsUpdate = boolean; + uniforms.directionalLightColor.needsUpdate = value; + uniforms.directionalLightDirection.needsUpdate = value; - uniforms.pointLightColor.needsUpdate = boolean; - uniforms.pointLightPosition.needsUpdate = boolean; - uniforms.pointLightDistance.needsUpdate = boolean; - uniforms.pointLightDecay.needsUpdate = boolean; + uniforms.pointLightColor.needsUpdate = value; + uniforms.pointLightPosition.needsUpdate = value; + uniforms.pointLightDistance.needsUpdate = value; + uniforms.pointLightDecay.needsUpdate = value; - uniforms.spotLightColor.needsUpdate = boolean; - uniforms.spotLightPosition.needsUpdate = boolean; - uniforms.spotLightDistance.needsUpdate = boolean; - uniforms.spotLightDirection.needsUpdate = boolean; - uniforms.spotLightAngleCos.needsUpdate = boolean; - uniforms.spotLightExponent.needsUpdate = boolean; - uniforms.spotLightDecay.needsUpdate = boolean; + uniforms.spotLightColor.needsUpdate = value; + uniforms.spotLightPosition.needsUpdate = value; + uniforms.spotLightDistance.needsUpdate = value; + uniforms.spotLightDirection.needsUpdate = value; + uniforms.spotLightAngleCos.needsUpdate = value; + uniforms.spotLightExponent.needsUpdate = value; + uniforms.spotLightDecay.needsUpdate = value; - uniforms.hemisphereLightSkyColor.needsUpdate = boolean; - uniforms.hemisphereLightGroundColor.needsUpdate = boolean; - uniforms.hemisphereLightDirection.needsUpdate = boolean; + uniforms.hemisphereLightSkyColor.needsUpdate = value; + uniforms.hemisphereLightGroundColor.needsUpdate = value; + uniforms.hemisphereLightDirection.needsUpdate = value; } diff --git a/build/three.min.js b/build/three.min.js index a5516349452b00..f5f1878b4ba64f 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -385,17 +385,17 @@ THREE.LensFlare.prototype.add=function(a,b,c,d,e,f){void 0===b&&(b=-1);void 0=== THREE.LensFlare.prototype.updateLensFlares=function(){var a,b=this.lensFlares.length,c,d=2*-this.positionScreen.x,e=2*-this.positionScreen.y;for(a=0;a 0.0 ) {\n\t return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent );\n\t}\n\treturn 1.0;\n}\n\nvec3 inputToLinear( in vec3 a ) {\n#ifdef GAMMA_INPUT\n\treturn pow( a, vec3( float( GAMMA_FACTOR ) ) );\n#else\n\treturn a;\n#endif\n}\nvec3 linearToOutput( in vec3 a ) {\n#ifdef GAMMA_OUTPUT\n\treturn pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );\n#else\n\treturn a;\n#endif\n}\n"; -THREE.ShaderChunk.alphatest_fragment="#ifdef ALPHATEST\n\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n\n#endif\n";THREE.ShaderChunk.lights_lambert_vertex="vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\tfloat dotProduct = dot( transformedNormal, dirVector );\n\tvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t#endif\n\n\t#endif\n\n\t#ifdef WRAP_AROUND\n\n\t\tvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\tdirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tdirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n\t\t#endif\n\n\t#endif\n\n\tvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n\t#endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\tpointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tpointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\tvLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n\t\t#endif\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\t\tlVector = normalize( lVector );\n\n\t\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\t\t\tvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\t\tvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\t\tspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n\t\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\t\tspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\tvLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n\t\t\t#endif\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\t\tfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n\t\tvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n\t\t#endif\n\n\t}\n\n#endif\n\nvLightFront = vLightFront * diffuse + diffuse * ambientLightColor + emissive;\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vLightBack * diffuse + diffuse * ambientLightColor + emissive;\n\n#endif\n"; +THREE.ShaderChunk.alphatest_fragment="#ifdef ALPHATEST\n\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n\n#endif\n";THREE.ShaderChunk.lights_lambert_vertex="vLightFront = vec3( 0.0 );\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack = vec3( 0.0 );\n\n#endif\n\ntransformedNormal = normalize( transformedNormal );\n\n#if MAX_DIR_LIGHTS > 0\n\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\tfloat dotProduct = dot( transformedNormal, dirVector );\n\tvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t#endif\n\n\t#endif\n\n\t#ifdef WRAP_AROUND\n\n\t\tvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\tdirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tdirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n\n\t\t#endif\n\n\t#endif\n\n\tvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n\n\t#endif\n\n}\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\tpointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tpointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n\n\t\t\t#endif\n\n\t\t#endif\n\n\t\tvLightFront += pointLightColor[ i ] * pointLightWeighting * attenuation;\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += pointLightColor[ i ] * pointLightWeightingBack * attenuation;\n\n\t\t#endif\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz - mvPosition.xyz;\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\t\tlVector = normalize( lVector );\n\n\t\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\t\t\tvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n\n\t\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\t\tvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\n\t\t\t\tspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n\n\t\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\t\tspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t\tvLightFront += spotLightColor[ i ] * spotLightWeighting * attenuation * spotEffect;\n\n\t\t\t#ifdef DOUBLE_SIDED\n\n\t\t\t\tvLightBack += spotLightColor[ i ] * spotLightWeightingBack * attenuation * spotEffect;\n\n\t\t\t#endif\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\tfloat dotProduct = dot( transformedNormal, lVector );\n\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\t\tfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\n\n\t\tvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\t#ifdef DOUBLE_SIDED\n\n\t\t\tvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n\n\t\t#endif\n\n\t}\n\n#endif\n\nvLightFront += ambientLightColor;\n\n#ifdef DOUBLE_SIDED\n\n\tvLightBack += ambientLightColor;\n\n#endif\n"; THREE.ShaderChunk.map_particle_pars_fragment="#ifdef USE_MAP\n\n\tuniform vec4 offsetRepeat;\n\tuniform sampler2D map;\n\n#endif\n";THREE.ShaderChunk.default_vertex="#ifdef USE_SKINNING\n\n\tvec4 mvPosition = modelViewMatrix * skinned;\n\n#elif defined( USE_MORPHTARGETS )\n\n\tvec4 mvPosition = modelViewMatrix * vec4( morphed, 1.0 );\n\n#else\n\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\n#endif\n\ngl_Position = projectionMatrix * mvPosition;\n"; THREE.ShaderChunk.map_pars_fragment="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\n#endif\n\n#ifdef USE_MAP\n\n\tuniform sampler2D map;\n\n#endif";THREE.ShaderChunk.skinnormal_vertex="#ifdef USE_SKINNING\n\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\n\t#ifdef USE_MORPHNORMALS\n\n\tvec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );\n\n\t#else\n\n\tvec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );\n\n\t#endif\n\n#endif\n"; -THREE.ShaderChunk.logdepthbuf_pars_vertex="#ifdef USE_LOGDEPTHBUF\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n\tuniform float logDepthBufFC;\n\n#endif";THREE.ShaderChunk.lightmap_pars_vertex="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\n#endif";THREE.ShaderChunk.lights_phong_fragment="#ifndef FLAT_SHADED\n\n\tvec3 normal = normalize( vNormal );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n\t#endif\n\n#else\n\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\nvec3 totalDiffuseLight = vec3( 0.0 );\nvec3 totalSpecularLight = vec3( 0.0 );\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\ttotalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n\t\t\t\t// specular\n\n\t\tvec3 pointHalfVector = normalize( lVector + viewPosition );\n\t\tfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n\t\tfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\t// diffuse\n\n\t\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\t\tfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\t\tvec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n\t\t\t#else\n\n\t\t\t\tfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t\t#endif\n\n\t\t\ttotalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n\t\t\t// specular\n\n\t\t\tvec3 spotHalfVector = normalize( lVector + viewPosition );\n\t\t\tfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n\t\t\tfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n\t\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n\t\t\ttotalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\t\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, dirVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\ttotalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;\n\n\t\t// specular\n\n\t\tvec3 dirHalfVector = normalize( dirVector + viewPosition );\n\t\tfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n\t\tfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n\t\t/*\n\t\t// fresnel term from skin shader\n\t\tconst float F0 = 0.128;\n\n\t\tfloat base = 1.0 - dot( viewPosition, dirHalfVector );\n\t\tfloat exponential = pow( base, 5.0 );\n\n\t\tfloat fresnel = exponential + F0 * ( 1.0 - exponential );\n\t\t*/\n\n\t\t/*\n\t\t// fresnel term from fresnel shader\n\t\tconst float mFresnelBias = 0.08;\n\t\tconst float mFresnelScale = 0.3;\n\t\tconst float mFresnelPower = 5.0;\n\n\t\tfloat fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n\t\t*/\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t// \t\tdirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n\t\tvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\ttotalDiffuseLight += hemiColor;\n\n\t\t// specular (sky light)\n\n\t\tvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n\t\tfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n\t\tfloat hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n\t\t// specular (ground light)\n\n\t\tvec3 lVectorGround = -lVector;\n\n\t\tvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n\t\tfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n\t\tfloat hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n\t\tfloat dotProductGround = dot( normal, lVectorGround );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n\t\tvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n\t}\n\n#endif\n\n#ifdef METAL\n\n\toutgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * diffuse ) * specular + totalSpecularLight + emissive;\n\n#else\n\n\toutgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive;\n\n#endif\n"; +THREE.ShaderChunk.logdepthbuf_pars_vertex="#ifdef USE_LOGDEPTHBUF\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvarying float vFragDepth;\n\n\t#endif\n\n\tuniform float logDepthBufFC;\n\n#endif";THREE.ShaderChunk.lightmap_pars_vertex="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\n#endif";THREE.ShaderChunk.lights_phong_fragment="#ifndef FLAT_SHADED\n\n\tvec3 normal = normalize( vNormal );\n\n\t#ifdef DOUBLE_SIDED\n\n\t\tnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\n\t#endif\n\n#else\n\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n\n#endif\n\nvec3 viewPosition = normalize( vViewPosition );\n\n#ifdef USE_NORMALMAP\n\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\n#elif defined( USE_BUMPMAP )\n\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n\n#endif\n\nvec3 totalDiffuseLight = vec3( 0.0 );\nvec3 totalSpecularLight = vec3( 0.0 );\n\n#if MAX_POINT_LIGHTS > 0\n\n\tfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\ttotalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation;\n\n\t\t\t\t// specular\n\n\t\tvec3 pointHalfVector = normalize( lVector + viewPosition );\n\t\tfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\n\t\tfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;\n\n\t}\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n\n\t\tvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\n\t\tvec3 lVector = lPosition.xyz + vViewPosition.xyz;\n\n\t\tfloat attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );\n\n\t\tlVector = normalize( lVector );\n\n\t\tfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\n\n\t\tif ( spotEffect > spotLightAngleCos[ i ] ) {\n\n\t\t\tspotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );\n\n\t\t\t// diffuse\n\n\t\t\tfloat dotProduct = dot( normal, lVector );\n\n\t\t\t#ifdef WRAP_AROUND\n\n\t\t\t\tfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\t\tfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\t\tvec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n\n\t\t\t#else\n\n\t\t\t\tfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t\t#endif\n\n\t\t\ttotalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;\n\n\t\t\t// specular\n\n\t\t\tvec3 spotHalfVector = normalize( lVector + viewPosition );\n\t\t\tfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\n\t\t\tfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n\n\t\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );\n\t\t\ttotalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;\n\n\t\t}\n\n\t}\n\n#endif\n\n#if MAX_DIR_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\n\n\t\tvec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, dirVector );\n\n\t\t#ifdef WRAP_AROUND\n\n\t\t\tfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\n\t\t\tfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\n\n\t\t\tvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n\n\t\t#else\n\n\t\t\tfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n\n\t\t#endif\n\n\t\ttotalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;\n\n\t\t// specular\n\n\t\tvec3 dirHalfVector = normalize( dirVector + viewPosition );\n\t\tfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\n\t\tfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n\n\t\t/*\n\t\t// fresnel term from skin shader\n\t\tconst float F0 = 0.128;\n\n\t\tfloat base = 1.0 - dot( viewPosition, dirHalfVector );\n\t\tfloat exponential = pow( base, 5.0 );\n\n\t\tfloat fresnel = exponential + F0 * ( 1.0 - exponential );\n\t\t*/\n\n\t\t/*\n\t\t// fresnel term from fresnel shader\n\t\tconst float mFresnelBias = 0.08;\n\t\tconst float mFresnelScale = 0.3;\n\t\tconst float mFresnelPower = 5.0;\n\n\t\tfloat fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );\n\t\t*/\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\t// \t\tdirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;\n\n\t\tvec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n\n\n\t}\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\n\n\t\tvec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );\n\n\t\t// diffuse\n\n\t\tfloat dotProduct = dot( normal, lVector );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\n\n\t\tvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n\n\t\ttotalDiffuseLight += hemiColor;\n\n\t\t// specular (sky light)\n\n\t\tvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\n\t\tfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\n\t\tfloat hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );\n\n\t\t// specular (ground light)\n\n\t\tvec3 lVectorGround = -lVector;\n\n\t\tvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\n\t\tfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\n\t\tfloat hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 );\n\n\t\tfloat dotProductGround = dot( normal, lVectorGround );\n\n\t\tfloat specularNormalization = ( shininess + 2.0 ) / 8.0;\n\n\t\tvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );\n\t\tvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );\n\t\ttotalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n\n\t}\n\n#endif\n\n#ifdef METAL\n\n\toutgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) * specular + totalSpecularLight + emissive;\n\n#else\n\n\toutgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive;\n\n#endif\n"; THREE.ShaderChunk.fog_pars_fragment="#ifdef USE_FOG\n\n\tuniform vec3 fogColor;\n\n\t#ifdef FOG_EXP2\n\n\t\tuniform float fogDensity;\n\n\t#else\n\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n\n#endif";THREE.ShaderChunk.morphnormal_vertex="#ifdef USE_MORPHNORMALS\n\n\tvec3 morphedNormal = vec3( 0.0 );\n\n\tmorphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tmorphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tmorphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tmorphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n\n\tmorphedNormal += normal;\n\n#endif"; THREE.ShaderChunk.envmap_pars_fragment="#ifdef USE_ENVMAP\n\n\tuniform float reflectivity;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tuniform float refractionRatio;\n\n\t#else\n\n\t\tvarying vec3 vReflect;\n\n\t#endif\n\n#endif\n";THREE.ShaderChunk.logdepthbuf_fragment="#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n\n#endif"; THREE.ShaderChunk.normalmap_pars_fragment="#ifdef USE_NORMALMAP\n\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\n\t// Per-Pixel Tangent Space Normal Mapping\n\t// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html\n\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\n\t}\n\n#endif\n"; THREE.ShaderChunk.lights_phong_pars_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvarying vec3 vWorldPosition;\n\n#endif\n";THREE.ShaderChunk.lightmap_pars_fragment="#ifdef USE_LIGHTMAP\n\n\tvarying vec2 vUv2;\n\tuniform sampler2D lightMap;\n\n#endif";THREE.ShaderChunk.shadowmap_vertex="#ifdef USE_SHADOWMAP\n\n\tfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n\n\t\tvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n\n\t}\n\n#endif"; THREE.ShaderChunk.lights_phong_vertex="#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )\n\n\tvWorldPosition = worldPosition.xyz;\n\n#endif";THREE.ShaderChunk.map_fragment="#ifdef USE_MAP\n\n\tvec4 texelColor = texture2D( map, vUv );\n\n\ttexelColor.xyz = inputToLinear( texelColor.xyz );\n\n\tdiffuseColor *= texelColor;\n\n#endif";THREE.ShaderChunk.lightmap_vertex="#ifdef USE_LIGHTMAP\n\n\tvUv2 = uv2;\n\n#endif";THREE.ShaderChunk.map_particle_fragment="#ifdef USE_MAP\n\n\tdiffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\n#endif\n"; THREE.ShaderChunk.color_pars_fragment="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif\n";THREE.ShaderChunk.color_vertex="#ifdef USE_COLOR\n\n\tvColor.xyz = inputToLinear( color.xyz );\n\n#endif";THREE.ShaderChunk.skinning_vertex="#ifdef USE_SKINNING\n\n\t#ifdef USE_MORPHTARGETS\n\n\tvec4 skinVertex = bindMatrix * vec4( morphed, 1.0 );\n\n\t#else\n\n\tvec4 skinVertex = bindMatrix * vec4( position, 1.0 );\n\n\t#endif\n\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\tskinned = bindMatrixInverse * skinned;\n\n#endif\n"; -THREE.ShaderChunk.envmap_pars_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvarying vec3 vReflect;\n\n\tuniform float refractionRatio;\n\n#endif\n";THREE.ShaderChunk.linear_to_gamma_fragment="\n\toutgoingLight = linearToOutput( outgoingLight );\n";THREE.ShaderChunk.color_pars_vertex="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif";THREE.ShaderChunk.lights_lambert_pars_vertex="uniform vec3 diffuse;\nuniform vec3 emissive;\n\nuniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n"; +THREE.ShaderChunk.envmap_pars_vertex="#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )\n\n\tvarying vec3 vReflect;\n\n\tuniform float refractionRatio;\n\n#endif\n";THREE.ShaderChunk.linear_to_gamma_fragment="\n\toutgoingLight = linearToOutput( outgoingLight );\n";THREE.ShaderChunk.color_pars_vertex="#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif";THREE.ShaderChunk.lights_lambert_pars_vertex="uniform vec3 ambientLightColor;\n\n#if MAX_DIR_LIGHTS > 0\n\n\tuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\n\tuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n\n#endif\n\n#if MAX_HEMI_LIGHTS > 0\n\n\tuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\n\tuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n\n#endif\n\n#if MAX_POINT_LIGHTS > 0\n\n\tuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n\tuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n\tuniform float pointLightDecay[ MAX_POINT_LIGHTS ];\n\n#endif\n\n#if MAX_SPOT_LIGHTS > 0\n\n\tuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\n\tuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n\tuniform float spotLightDecay[ MAX_SPOT_LIGHTS ];\n\n#endif\n\n#ifdef WRAP_AROUND\n\n\tuniform vec3 wrapRGB;\n\n#endif\n"; THREE.ShaderChunk.map_pars_vertex="#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP )\n\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n\n#endif\n";THREE.ShaderChunk.envmap_fragment="#ifdef USE_ENVMAP\n\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\n\t\t// Transforming Normal Vectors with the Inverse Transformation\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\n\t\t#else\n\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\n\t\t#endif\n\n\t#else\n\n\t\tvec3 reflectVec = vReflect;\n\n\t#endif\n\n\t#ifdef DOUBLE_SIDED\n\t\tfloat flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n\t#else\n\t\tfloat flipNormal = 1.0;\n\t#endif\n\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#endif\n\n\tenvColor.xyz = inputToLinear( envColor.xyz );\n\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\n\t#endif\n\n#endif\n"; THREE.ShaderChunk.specularmap_pars_fragment="#ifdef USE_SPECULARMAP\n\n\tuniform sampler2D specularMap;\n\n#endif";THREE.ShaderChunk.logdepthbuf_vertex="#ifdef USE_LOGDEPTHBUF\n\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\n#else\n\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\n\t#endif\n\n#endif";THREE.ShaderChunk.morphtarget_pars_vertex="#ifdef USE_MORPHTARGETS\n\n\t#ifndef USE_MORPHNORMALS\n\n\tuniform float morphTargetInfluences[ 8 ];\n\n\t#else\n\n\tuniform float morphTargetInfluences[ 4 ];\n\n\t#endif\n\n#endif"; THREE.ShaderChunk.specularmap_fragment="float specularStrength;\n\n#ifdef USE_SPECULARMAP\n\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n\n#else\n\n\tspecularStrength = 1.0;\n\n#endif";THREE.ShaderChunk.fog_fragment="#ifdef USE_FOG\n\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\n\t#else\n\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\n\t#endif\n\n\t#ifdef FOG_EXP2\n\n\t\tfloat fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 );\n\t\tfogFactor = whiteCompliment( fogFactor );\n\n\t#else\n\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n\n\t#endif\n\t\n\toutgoingLight = mix( outgoingLight, fogColor, fogFactor );\n\n#endif"; @@ -419,12 +419,12 @@ THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,"\toutgoingLight = diffuseColor.rgb;",THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")}, lambert:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",value:new THREE.Color(0)},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_lambert_pars_vertex, THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex, -THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_lambert_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment, -THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( 1.0, 1.0, 1.0, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment, -"\t#ifdef DOUBLE_SIDED\n\t\tif ( gl_FrontFacing )\n\t\t\toutgoingLight += diffuseColor.rgb * vLightFront;\n\t\telse\n\t\t\toutgoingLight += diffuseColor.rgb * vLightBack;\n\t#else\n\t\toutgoingLight += diffuseColor.rgb * vLightFront;\n\t#endif",THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},phong:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common, -THREE.UniformsLib.bump,THREE.UniformsLib.normalmap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",value:new THREE.Color(0)},specular:{type:"c",value:new THREE.Color(1118481)},shininess:{type:"f",value:30},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex, -THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_phong_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex, -"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"\tvViewPosition = -mvPosition.xyz;",THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_phong_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["#define PHONG\nuniform vec3 diffuse;\nuniform float opacity;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;", +THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_lambert_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment, +THREE.ShaderChunk.lightmap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment, +THREE.ShaderChunk.specularmap_fragment,"\t#ifdef DOUBLE_SIDED\n\t\tif ( gl_FrontFacing )\n\t\t\toutgoingLight += diffuseColor.rgb * vLightFront + emissive;\n\t\telse\n\t\t\toutgoingLight += diffuseColor.rgb * vLightBack + emissive;\n\t#else\n\t\toutgoingLight += diffuseColor.rgb * vLightFront + emissive;\n\t#endif",THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")}, +phong:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.bump,THREE.UniformsLib.normalmap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",value:new THREE.Color(0)},specular:{type:"c",value:new THREE.Color(1118481)},shininess:{type:"f",value:30},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif",THREE.ShaderChunk.common, +THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_phong_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex, +THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"\tvViewPosition = -mvPosition.xyz;",THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_phong_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["#define PHONG\nuniform vec3 diffuse;\nuniform float opacity;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;", THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.lights_phong_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.bumpmap_pars_fragment,THREE.ShaderChunk.normalmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment, "void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.lights_phong_fragment,THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment, THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},particle_basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.particle,THREE.UniformsLib.shadowmap]),vertexShader:["uniform float size;\nuniform float scale;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.color_vertex,"\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / length( mvPosition.xyz ) );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\tgl_Position = projectionMatrix * mvPosition;", From 33722d6432102b378fbd4a738359a7846b027863 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Wed, 11 Mar 2015 22:28:44 +0000 Subject: [PATCH 302/333] ShaderLib: More tidying. --- src/renderers/shaders/ShaderLib.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 6ff73d1800c515..d1e735d0a852a5 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -173,7 +173,6 @@ THREE.ShaderLib = { "uniform vec3 diffuse;", "uniform vec3 emissive;", - "uniform float opacity;", "varying vec3 vLightFront;", @@ -320,11 +319,10 @@ THREE.ShaderLib = { "#define PHONG", "uniform vec3 diffuse;", - "uniform float opacity;", - "uniform vec3 emissive;", "uniform vec3 specular;", "uniform float shininess;", + "uniform float opacity;", THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "color_pars_fragment" ], From aefaf417504d66b4e699cc428b57acf3ecb77e2f Mon Sep 17 00:00:00 2001 From: Joshua Koo Date: Thu, 12 Mar 2015 10:26:14 +0800 Subject: [PATCH 303/333] Make js build script work with sourcemaps - sourcemaps now work with build.js - sourcemaps also point to glsl shader files - enable sourcemaps by default - display uglify-js unused variable warnings --- utils/build/build.js | 73 +++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/utils/build/build.js b/utils/build/build.js index e8ec81f01ba230..9974610636aed7 100644 --- a/utils/build/build.js +++ b/utils/build/build.js @@ -14,7 +14,7 @@ function main() { parser.addArgument( ['--amd'], { action: 'storeTrue', defaultValue: false } ); parser.addArgument( ['--minify'], { action: 'storeTrue', defaultValue: false } ); parser.addArgument( ['--output'], { defaultValue: '../../build/three.js' } ); - parser.addArgument( ['--sourcemaps'], { action: 'storeTrue', defaultValue: false } ); + parser.addArgument( ['--sourcemaps'], { action: 'storeTrue', defaultValue: true } ); var args = parser.parseArgs(); @@ -28,13 +28,12 @@ function main() { if ( args.sourcemaps ){ sourcemap = output + '.map'; - sourcemapping = '\n//@ sourceMappingURL=' + sourcemap; + sourcemapping = '\n//# sourceMappingURL=three.min.js.map'; } var buffer = []; - var sources = []; - // TODO - sources are not being used. should remove and make sourcemaps work with uglify + var sources = []; // used for source maps with minification if ( args.amd ){ buffer.push('function ( root, factory ) {\n\n\tif ( typeof define === \'function\' && define.amd ) {\n\n\t\tdefine( [ \'exports\' ], factory );\n\n\t} else if ( typeof exports === \'object\' ) {\n\n\t\tfactory( exports );\n\n\t} else {\n\n\t\tfactory( root );\n\n\t}\n\n}( this, function ( exports ) {\n\n'); @@ -56,18 +55,15 @@ function main() { if( file.indexOf( '.glsl') >= 0 ) { - buffer.push( 'THREE.ShaderChunk[ \'' + path.basename( file, '.glsl' ) + '\' ] =') - buffer.push( JSON.stringify( contents ) ); - buffer.push( ';\n\n' ); - - } else { - - sources.push( file ); - buffer.push( contents ); - buffer.push( '\n' ); + contents = 'THREE.ShaderChunk[ \'' + + path.basename( file, '.glsl' ) + '\' ] =' + + JSON.stringify( contents ) + ';\n'; } + sources.push( { file: file, contents: contents } ); + buffer.push( contents ); + buffer.push( '\n' ); } } @@ -84,13 +80,56 @@ function main() { } else { - var result = uglify.minify( temp, { outSourceMap: sourcemap, fromString: true } ); - - fs.writeFileSync( output, '// threejs.org/license\n' + result.code + sourcemapping, 'utf8' ); + var LICENSE = "threejs.org/license"; + + // Parsing + + var toplevel = null; + + toplevel = uglify.parse( '// ' + LICENSE + '\n' ); + + sources.forEach( function( source ) { + + toplevel = uglify.parse( source.contents, { + filename: source.file, + toplevel: toplevel + } ); + + } ); + + // Compression + + toplevel.figure_out_scope(); + var compressor = uglify.Compressor( {} ); + var compressed_ast = toplevel.transform( compressor ); + + // Mangling + + compressed_ast.figure_out_scope(); + compressed_ast.compute_char_frequency(); + compressed_ast.mangle_names(); + + // Output + + var source_map_options = { + file: 'three.min.js', + root: 'src' + }; + + var source_map = uglify.SourceMap( source_map_options ) + var stream = uglify.OutputStream( { + source_map: source_map, + comments: new RegExp( LICENSE ) + } ); + + compressed_ast.print( stream ); + var code = stream.toString(); + + fs.writeFileSync( output, code + sourcemapping, 'utf8' ); if ( args.sourcemaps ) { - fs.writeFileSync( sourcemap, result.map, 'utf8' ); + fs.writeFileSync( sourcemap, source_map.toString(), 'utf8' ); } From 0b625f7c636816be90df80acec6b8acad60e928f Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Mar 2015 09:57:10 +0000 Subject: [PATCH 304/333] EdgesHelper: Setting default threshold to 1. See #6125. --- src/extras/helpers/EdgesHelper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extras/helpers/EdgesHelper.js b/src/extras/helpers/EdgesHelper.js index 733f105152eab8..8356d21ea5add8 100644 --- a/src/extras/helpers/EdgesHelper.js +++ b/src/extras/helpers/EdgesHelper.js @@ -11,7 +11,7 @@ THREE.EdgesHelper = function ( object, hex, thresholdAngle ) { var color = ( hex !== undefined ) ? hex : 0xffffff; - thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 0.1; + thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1; var thresholdDot = Math.cos( THREE.Math.degToRad( thresholdAngle ) ); From 22163e461a2e0860dba4c83f267a9a3fa201c80d Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Mar 2015 10:15:33 +0000 Subject: [PATCH 305/333] ShaderLib: Fixed dashed. See #5805. --- src/renderers/shaders/ShaderLib.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index d1e735d0a852a5..1cdc41b72aa5af 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -292,7 +292,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "skinnormal_vertex" ], THREE.ShaderChunk[ "defaultnormal_vertex" ], - "#ifndef FLAT_SHADED", + "#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED " vNormal = normalize( transformedNormal );", @@ -513,6 +513,9 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "color_fragment" ], + + " outgoingLight = diffuseColor.rgb;", // simple shader + THREE.ShaderChunk[ "fog_fragment" ], " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects From abfd5aea6e1c6c352f86d433c8634e0353a427c7 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Mar 2015 10:16:22 +0000 Subject: [PATCH 306/333] Updated builds. --- build/three.js | 22 ++++++++++++++++------ build/three.min.js | 27 ++++++++++++++------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/build/three.js b/build/three.js index 0432e1aab21fb5..7502a8bb792d99 100644 --- a/build/three.js +++ b/build/three.js @@ -17131,7 +17131,6 @@ THREE.ShaderLib = { "uniform vec3 diffuse;", "uniform vec3 emissive;", - "uniform float opacity;", "varying vec3 vLightFront;", @@ -17251,7 +17250,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "skinnormal_vertex" ], THREE.ShaderChunk[ "defaultnormal_vertex" ], - "#ifndef FLAT_SHADED", + "#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED " vNormal = normalize( transformedNormal );", @@ -17278,11 +17277,10 @@ THREE.ShaderLib = { "#define PHONG", "uniform vec3 diffuse;", - "uniform float opacity;", - "uniform vec3 emissive;", "uniform vec3 specular;", "uniform float shininess;", + "uniform float opacity;", THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "color_pars_fragment" ], @@ -17473,6 +17471,9 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "color_fragment" ], + + " outgoingLight = diffuseColor.rgb;", // simple shader + THREE.ShaderChunk[ "fog_fragment" ], " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects @@ -33816,11 +33817,20 @@ THREE.DirectionalLightHelper.prototype.update = function () { /** * @author WestLangley / http://github.com/WestLangley + * @param object THREE.Mesh whose geometry will be used + * @param hex line color + * @param thresholdAngle the minimim angle (in degrees), + * between the face normals of adjacent faces, + * that is required to render an edge. A value of 10 means + * an edge is only rendered if the angle is at least 10 degrees. */ -THREE.EdgesHelper = function ( object, hex ) { +THREE.EdgesHelper = function ( object, hex, thresholdAngle ) { var color = ( hex !== undefined ) ? hex : 0xffffff; + thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1; + + var thresholdDot = Math.cos( THREE.Math.degToRad( thresholdAngle ) ); var edge = [ 0, 0 ], hash = {}; var sortFunction = function ( a, b ) { return a - b }; @@ -33883,7 +33893,7 @@ THREE.EdgesHelper = function ( object, hex ) { var h = hash[ key ]; - if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) < 0.9999 ) { // hardwired const OK + if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) { var vertex = vertices[ h.vert1 ]; coords[ index ++ ] = vertex.x; diff --git a/build/three.min.js b/build/three.min.js index f5f1878b4ba64f..57cca79b413dab 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -424,21 +424,21 @@ THREE.ShaderChunk.lightmap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment, THREE.ShaderChunk.specularmap_fragment,"\t#ifdef DOUBLE_SIDED\n\t\tif ( gl_FrontFacing )\n\t\t\toutgoingLight += diffuseColor.rgb * vLightFront + emissive;\n\t\telse\n\t\t\toutgoingLight += diffuseColor.rgb * vLightBack + emissive;\n\t#else\n\t\toutgoingLight += diffuseColor.rgb * vLightFront + emissive;\n\t#endif",THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")}, phong:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.bump,THREE.UniformsLib.normalmap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",value:new THREE.Color(0)},specular:{type:"c",value:new THREE.Color(1118481)},shininess:{type:"f",value:30},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif",THREE.ShaderChunk.common, THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_phong_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex, -THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"\tvViewPosition = -mvPosition.xyz;",THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_phong_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["#define PHONG\nuniform vec3 diffuse;\nuniform float opacity;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;", +THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"\tvViewPosition = -mvPosition.xyz;",THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_phong_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;", THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.lights_phong_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.bumpmap_pars_fragment,THREE.ShaderChunk.normalmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment, "void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.lights_phong_fragment,THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment, THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},particle_basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.particle,THREE.UniformsLib.shadowmap]),vertexShader:["uniform float size;\nuniform float scale;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.color_vertex,"\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / length( mvPosition.xyz ) );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\tgl_Position = projectionMatrix * mvPosition;", THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 psColor;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_particle_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( psColor, opacity );", THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_particle_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphatest_fragment,"\toutgoingLight = diffuseColor.rgb;",THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},dashed:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,{scale:{type:"f",value:1},dashSize:{type:"f",value:1},totalSize:{type:"f",value:2}}]), vertexShader:["uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.color_vertex,"\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;", -THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},depth:{uniforms:{mNear:{type:"f", -value:1},mFar:{type:"f",value:2E3},opacity:{type:"f",value:1}},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float mNear;\nuniform float mFar;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {",THREE.ShaderChunk.logdepthbuf_fragment, -"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\tfloat color = 1.0 - smoothstep( mNear, mFar, depth );\n\tgl_FragColor = vec4( vec3( color ), opacity );\n}"].join("\n")},normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvNormal = normalize( normalMatrix * normal );", -THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;", -THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );", -THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},equirect:{uniforms:{tEquirect:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;", -THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\nvec3 direction = normalize( vWorldPosition );\nvec2 sampleUV;\nsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\nsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\ngl_FragColor = texture2D( tEquirect, sampleUV );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex, -THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"vec4 pack_depth( const in float depth ) {\n\tconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );\n\tres -= res.xxyz * bit_mask;\n\treturn res;\n}\nvoid main() {", +THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.color_fragment,"\toutgoingLight = diffuseColor.rgb;",THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")}, +depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3},opacity:{type:"f",value:1}},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float mNear;\nuniform float mFar;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment, +"void main() {",THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\tfloat color = 1.0 - smoothstep( mNear, mFar, depth );\n\tgl_FragColor = vec4( vec3( color ), opacity );\n}"].join("\n")},normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex, +"void main() {\n\tvNormal = normalize( normalMatrix * normal );",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},cube:{uniforms:{tCube:{type:"t",value:null}, +tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment, +"void main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},equirect:{uniforms:{tEquirect:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", +THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\nvec3 direction = normalize( vWorldPosition );\nvec2 sampleUV;\nsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\nsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\ngl_FragColor = texture2D( tEquirect, sampleUV );",THREE.ShaderChunk.logdepthbuf_fragment, +"}"].join("\n")},depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"vec4 pack_depth( const in float depth ) {\n\tconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );\n\tres -= res.xxyz * bit_mask;\n\treturn res;\n}\nvoid main() {", THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );\n\t#else\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n\t#endif\n}"].join("\n")}}; THREE.WebGLRenderer=function(a){function b(a){var b=a.geometry;a=a.material;var c=b.vertices.length;if(a.attributes){void 0===b.__webglCustomAttributesList&&(b.__webglCustomAttributesList=[]);for(var d in a.attributes){var e=a.attributes[d];if(!e.__webglInitialized||e.createUniqueBuffers){e.__webglInitialized=!0;var f=1;"v2"===e.type?f=2:"v3"===e.type?f=3:"v4"===e.type?f=4:"c"===e.type&&(f=3);e.size=f;e.array=new Float32Array(c*f);e.buffer=m.createBuffer();e.buffer.belongsToAttribute=d;e.needsUpdate= !0}b.__webglCustomAttributesList.push(e)}}}function c(a,b){return a.material instanceof THREE.MeshFaceMaterial?a.material.materials[b.materialIndex]:a.material}function d(a,b,c,d){c=c.attributes;var e=b.attributes;b=b.attributesKeys;for(var f=0,g=b.length;fs;s++){d[0]=t[g[s]];d[1]=t[g[(s+1)%3]];d.sort(f);var r=d.toString();void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1], -face1:q,face2:void 0},p++):e[r].face2=q}d=new Float32Array(6*p);f=0;for(r in e)if(g=e[r],void 0===g.face2||.9999>k[g.face1].normal.dot(k[g.face2].normal))p=l[g.vert1],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z,p=l[g.vert2],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype); -THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper;THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=new THREE.Geometry;c=0;for(var e=this.object.geometry.faces.length;cs;s++){d[0]=t[g[s]];d[1]=t[g[(s+1)%3]];d.sort(f);var r=d.toString(); +void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1],face1:q,face2:void 0},p++):e[r].face2=q}d=new Float32Array(6*p);f=0;for(r in e)if(g=e[r],void 0===g.face2||k[g.face1].normal.dot(k[g.face2].normal)<=c)p=l[g.vert1],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z,p=l[g.vert2],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:b}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1}; +THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype);THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper; +THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=new THREE.Geometry;c=0;for(var e=this.object.geometry.faces.length;c Date: Wed, 11 Mar 2015 17:35:53 +0100 Subject: [PATCH 307/333] Blender: add button to save settings to .blend file --- .../blender/addons/io_three/__init__.py | 179 ++++++++++++++++++ .../blender/addons/io_three/constants.py | 1 + 2 files changed, 180 insertions(+) diff --git a/utils/exporters/blender/addons/io_three/__init__.py b/utils/exporters/blender/addons/io_three/__init__.py index d2e1be407f8c10..db277ec82b7146 100644 --- a/utils/exporters/blender/addons/io_three/__init__.py +++ b/utils/exporters/blender/addons/io_three/__init__.py @@ -18,6 +18,7 @@ import os import json +import logging import bpy from bpy_extras.io_utils import ExportHelper @@ -31,6 +32,10 @@ from . import constants +logging.basicConfig( + format='%(levelname)s:THREE:%(message)s', + level=logging.DEBUG) + bl_info = { 'name': "Three.js Format", 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks, rkusa", @@ -250,6 +255,160 @@ def draw(self, context): row = layout.row() row.prop(obj, 'THREE_export', text='Export') +class ThreeExportSettings(bpy.types.Operator): + """Save the current export settings (gets saved in .blend)""" + bl_label = "Save Settings" + bl_idname = "scene.three_export_settings_set" + + def execute(self, context): + cycles = context.scene.cycles + cycles.use_samples_final = True + + context.scene[constants.EXPORT_SETTINGS_KEY] = set_settings(context.active_operator.properties) + + self.report({"INFO"}, "Three Export Settings Saved") + + return {"FINISHED"} + +def restore_export_settings(properties, settings): + """Restore the settings + + :param properties: + + """ + + ## Geometry { + properties.option_vertices = settings.get( + constants.VERTICES, + constants.EXPORT_OPTIONS[constants.VERTICES]) + + properties.option_faces = settings.get( + constants.FACES, + constants.EXPORT_OPTIONS[constants.FACES]) + properties.option_normals = settings.get( + constants.NORMALS, + constants.EXPORT_OPTIONS[constants.NORMALS]) + + properties.option_skinning = settings.get( + constants.SKINNING, + constants.EXPORT_OPTIONS[constants.SKINNING]) + + properties.option_bones = settings.get( + constants.BONES, + constants.EXPORT_OPTIONS[constants.BONES]) + + properties.option_influences = settings.get( + constants.INFLUENCES_PER_VERTEX, + constants.EXPORT_OPTIONS[constants.INFLUENCES_PER_VERTEX]) + + properties.option_geometry_type = settings.get( + constants.GEOMETRY_TYPE, + constants.EXPORT_OPTIONS[constants.GEOMETRY_TYPE]) + ## } + + ## Materials { + properties.option_materials = settings.get( + constants.MATERIALS, + constants.EXPORT_OPTIONS[constants.MATERIALS]) + + properties.option_uv_coords = settings.get( + constants.UVS, + constants.EXPORT_OPTIONS[constants.UVS]) + + properties.option_face_materials = settings.get( + constants.FACE_MATERIALS, + constants.EXPORT_OPTIONS[constants.FACE_MATERIALS]) + + properties.option_maps = settings.get( + constants.MAPS, + constants.EXPORT_OPTIONS[constants.MAPS]) + + properties.option_colors = settings.get( + constants.COLORS, + constants.EXPORT_OPTIONS[constants.COLORS]) + + properties.option_mix_colors = settings.get( + constants.MIX_COLORS, + constants.EXPORT_OPTIONS[constants.MIX_COLORS]) + ## } + + ## Settings { + properties.option_scale = settings.get( + constants.SCALE, + constants.EXPORT_OPTIONS[constants.SCALE]) + + properties.option_round_off = settings.get( + constants.ENABLE_PRECISION, + constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION]) + + properties.option_round_value = settings.get( + constants.PRECISION, + constants.EXPORT_OPTIONS[constants.PRECISION]) + + properties.option_logging = settings.get( + constants.LOGGING, + constants.EXPORT_OPTIONS[constants.LOGGING]) + + properties.option_compression = settings.get( + constants.COMPRESSION, + constants.NONE) + + properties.option_indent = settings.get( + constants.INDENT, + constants.EXPORT_OPTIONS[constants.INDENT]) + + properties.option_copy_textures = settings.get( + constants.COPY_TEXTURES, + constants.EXPORT_OPTIONS[constants.COPY_TEXTURES]) + + properties.option_texture_folder = settings.get( + constants.TEXTURE_FOLDER, + constants.EXPORT_OPTIONS[constants.TEXTURE_FOLDER]) + + properties.option_embed_animation = settings.get( + constants.EMBED_ANIMATION, + constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION]) + ## } + + ## Scene { + properties.option_export_scene = settings.get( + constants.SCENE, + constants.EXPORT_OPTIONS[constants.SCENE]) + + #properties.option_embed_geometry = settings.get( + # constants.EMBED_GEOMETRY, + # constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY]) + + properties.option_lights = settings.get( + constants.LIGHTS, + constants.EXPORT_OPTIONS[constants.LIGHTS]) + + properties.option_cameras = settings.get( + constants.CAMERAS, + constants.EXPORT_OPTIONS[constants.CAMERAS]) + + properties.option_hierarchy = settings.get( + constants.HIERARCHY, + constants.EXPORT_OPTIONS[constants.HIERARCHY]) + ## } + + ## Animation { + properties.option_animation_morph = settings.get( + constants.MORPH_TARGETS, + constants.EXPORT_OPTIONS[constants.MORPH_TARGETS]) + + properties.option_animation_skeletal = settings.get( + constants.ANIMATION, + constants.EXPORT_OPTIONS[constants.ANIMATION]) + + properties.option_frame_step = settings.get( + constants.FRAME_STEP, + constants.EXPORT_OPTIONS[constants.FRAME_STEP]) + + properties.option_frame_index_as_time = settings.get( + constants.FRAME_INDEX_AS_TIME, + constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME]) + ## } def set_settings(properties): """Set the export settings to the correct keys. @@ -522,6 +681,17 @@ class ExportThree(bpy.types.Operator, ExportHelper): default=2) def invoke(self, context, event): + settings = context.scene.get(constants.EXPORT_SETTINGS_KEY) + if settings: + try: + restore_export_settings(self.properties, settings) + except AttributeError as e: + logging.error("Loading export settings failed:") + logging.exception(e) + logging.debug("Removed corrupted settings") + + del context.scene[constants.EXPORT_SETTINGS_KEY] + return ExportHelper.invoke(self, context, event) @classmethod @@ -694,6 +864,15 @@ def draw(self, context): row.prop(self.properties, 'option_indent') ## } + ## Operators { + has_settings = context.scene.get(constants.EXPORT_SETTINGS_KEY, False) + row = layout.row() + row.operator( + ThreeExportSettings.bl_idname, + ThreeExportSettings.bl_label, + icon="%s" % "PINNED" if has_settings else "UNPINNED") + ## } + def menu_func_export(self, context): diff --git a/utils/exporters/blender/addons/io_three/constants.py b/utils/exporters/blender/addons/io_three/constants.py index caa3d88ed6100c..9b55916c9fff06 100644 --- a/utils/exporters/blender/addons/io_three/constants.py +++ b/utils/exporters/blender/addons/io_three/constants.py @@ -329,3 +329,4 @@ DOUBLE_SIDED = 'doubleSided' +EXPORT_SETTINGS_KEY = 'threeExportSettings' From 34024452d4fc9105a823f9132772eeb902659f31 Mon Sep 17 00:00:00 2001 From: brason Date: Thu, 12 Mar 2015 16:23:31 +0100 Subject: [PATCH 308/333] Removed unused variables. --- src/core/BufferGeometry.js | 4 ++-- src/core/Geometry.js | 11 ++++----- src/core/Object3D.js | 2 -- src/extras/FontUtils.js | 14 +++++------ src/extras/core/Path.js | 1 - src/extras/geometries/ExtrudeGeometry.js | 10 +------- src/extras/geometries/ParametricGeometry.js | 1 - src/extras/geometries/PolyhedronGeometry.js | 3 +-- src/extras/geometries/ShapeGeometry.js | 3 +-- src/extras/geometries/TubeGeometry.js | 8 ++----- src/extras/helpers/VertexNormalsHelper.js | 2 -- src/extras/helpers/VertexTangentsHelper.js | 2 -- src/extras/objects/MorphBlendMesh.js | 1 - src/loaders/JSONLoader.js | 7 ++---- src/math/Matrix3.js | 2 +- src/math/Matrix4.js | 2 +- src/math/Spline.js | 2 +- src/objects/Mesh.js | 2 +- src/objects/MorphAnimMesh.js | 1 - src/renderers/WebGLRenderer.js | 24 ++++++++----------- .../webgl/plugins/ShadowMapPlugin.js | 2 +- 21 files changed, 35 insertions(+), 69 deletions(-) diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index 14bfe1a97cd0e1..3c24d135c433e0 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -679,12 +679,12 @@ THREE.BufferGeometry.prototype = { if ( indexBufferSize === undefined ) size = 65535; //WebGL limits type of index buffer values to 16-bit. - var s = Date.now(); + //var s = Date.now(); var indices = this.attributes.index.array; var vertices = this.attributes.position.array; - var verticesCount = ( vertices.length / 3 ); + //var verticesCount = ( vertices.length / 3 ); var facesCount = ( indices.length / 3 ); /* diff --git a/src/core/Geometry.js b/src/core/Geometry.js index 55ec6acbc22ed9..256d6c48157c96 100644 --- a/src/core/Geometry.js +++ b/src/core/Geometry.js @@ -241,9 +241,8 @@ THREE.Geometry.prototype = { // vertex normals weighted by triangle areas // http://www.iquilezles.org/www/articles/normals/normals.htm - var vA, vB, vC, vD; - var cb = new THREE.Vector3(), ab = new THREE.Vector3(), - db = new THREE.Vector3(), dc = new THREE.Vector3(), bc = new THREE.Vector3(); + var vA, vB, vC; + var cb = new THREE.Vector3(), ab = new THREE.Vector3(); for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { @@ -417,7 +416,7 @@ THREE.Geometry.prototype = { // based on http://www.terathon.com/code/tangent.html // tangents go to vertices - var f, fl, v, vl, i, il, vertexIndex, + var f, fl, v, vl, i, vertexIndex, face, uv, vA, vB, vC, uvA, uvB, uvC, x1, x2, y1, y2, z1, z2, s1, s2, t1, t2, r, t, test, @@ -699,8 +698,8 @@ THREE.Geometry.prototype = { var v, key; var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001 var precision = Math.pow( 10, precisionPoints ); - var i,il, face; - var indices, k, j, jl, u; + var i, il, face; + var indices, j, jl; for ( i = 0, il = this.vertices.length; i < il; i ++ ) { diff --git a/src/core/Object3D.js b/src/core/Object3D.js index ea2f8ddc743db0..e28dd71f342172 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -19,8 +19,6 @@ THREE.Object3D = function () { this.up = THREE.Object3D.DefaultUp.clone(); - var scope = this; - var position = new THREE.Vector3(); var rotation = new THREE.Euler(); var quaternion = new THREE.Quaternion(); diff --git a/src/extras/FontUtils.js b/src/extras/FontUtils.js index 244cc2b04b951f..64efa1727b0c10 100644 --- a/src/extras/FontUtils.js +++ b/src/extras/FontUtils.js @@ -56,7 +56,7 @@ THREE.FontUtils = { ThreeFont.faces[ family ][ data.cssFontWeight ] = ThreeFont.faces[ family ][ data.cssFontWeight ] || {}; ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data; - var face = ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data; + ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data; return data; @@ -64,11 +64,9 @@ THREE.FontUtils = { drawText: function ( text ) { - var characterPts = [], allPts = []; - // RenderText - var i, p, + var i, face = this.getFace(), scale = this.size / face.resolution, offset = 0, @@ -180,8 +178,8 @@ THREE.FontUtils = { for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) { var t = i2 / divisions; - var tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx ); - var ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy ); + THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx ); + THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy ); } } @@ -211,8 +209,8 @@ THREE.FontUtils = { for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) { var t = i2 / divisions; - var tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx ); - var ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy ); + THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx ); + THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy ); } diff --git a/src/extras/core/Path.js b/src/extras/core/Path.js index c56c3ea7e84f62..a5ab82f82318cd 100644 --- a/src/extras/core/Path.js +++ b/src/extras/core/Path.js @@ -633,7 +633,6 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) { betterShapeHoles[sIdx] = []; } for (var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - var sh = newShapes[sIdx]; var sho = newShapeHoles[sIdx]; for (var hIdx = 0; hIdx < sho.length; hIdx ++ ) { var ho = sho[hIdx]; diff --git a/src/extras/geometries/ExtrudeGeometry.js b/src/extras/geometries/ExtrudeGeometry.js index 207e7f60b66596..59d9e58f470bbb 100644 --- a/src/extras/geometries/ExtrudeGeometry.js +++ b/src/extras/geometries/ExtrudeGeometry.js @@ -123,7 +123,6 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var ahole, h, hl; // looping of holes var scope = this; - var bevelPoints = []; var shapesOffset = this.vertices.length; @@ -182,14 +181,11 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var b, bs, t, z, vert, vlen = vertices.length, - face, flen = faces.length, - cont, clen = contour.length; + face, flen = faces.length; // Find directions for point movement - var RAD_TO_DEGREES = 180 / Math.PI; - function getBevelVec( inPt, inPrev, inNext ) { @@ -292,10 +288,6 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { // (j)---(i)---(k) // console.log('i,j,k', i, j , k) - var pt_i = contour[ i ]; - var pt_j = contour[ j ]; - var pt_k = contour[ k ]; - contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); } diff --git a/src/extras/geometries/ParametricGeometry.js b/src/extras/geometries/ParametricGeometry.js index f31abaa8fdeeac..83d0bf514b7aff 100644 --- a/src/extras/geometries/ParametricGeometry.js +++ b/src/extras/geometries/ParametricGeometry.js @@ -26,7 +26,6 @@ THREE.ParametricGeometry = function ( func, slices, stacks ) { var i, j, p; var u, v; - var stackCount = stacks + 1; var sliceCount = slices + 1; for ( i = 0; i <= stacks; i ++ ) { diff --git a/src/extras/geometries/PolyhedronGeometry.js b/src/extras/geometries/PolyhedronGeometry.js index 32cdd56898c8ad..4affb75b344543 100644 --- a/src/extras/geometries/PolyhedronGeometry.js +++ b/src/extras/geometries/PolyhedronGeometry.js @@ -28,7 +28,7 @@ THREE.PolyhedronGeometry = function ( vertices, indices, radius, detail ) { } - var midpoints = [], p = this.vertices; + var p = this.vertices; var faces = []; @@ -136,7 +136,6 @@ THREE.PolyhedronGeometry = function ( vertices, indices, radius, detail ) { function subdivide( face, detail ) { var cols = Math.pow(2, detail); - var cells = Math.pow(4, detail); var a = prepare( that.vertices[ face.a ] ); var b = prepare( that.vertices[ face.b ] ); var c = prepare( that.vertices[ face.c ] ); diff --git a/src/extras/geometries/ShapeGeometry.js b/src/extras/geometries/ShapeGeometry.js index d3ac6ad9b84f21..1cd1c0111e02f7 100644 --- a/src/extras/geometries/ShapeGeometry.js +++ b/src/extras/geometries/ShapeGeometry.js @@ -59,7 +59,7 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) { // - var i, l, hole, s; + var i, l, hole; var shapesOffset = this.vertices.length; var shapePoints = shape.extractPoints( curveSegments ); @@ -108,7 +108,6 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) { var vert, vlen = vertices.length; var face, flen = faces.length; - var cont, clen = contour.length; for ( i = 0; i < vlen; i ++ ) { diff --git a/src/extras/geometries/TubeGeometry.js b/src/extras/geometries/TubeGeometry.js index 6874642ffde786..4b11c56d252e40 100644 --- a/src/extras/geometries/TubeGeometry.js +++ b/src/extras/geometries/TubeGeometry.js @@ -42,8 +42,6 @@ THREE.TubeGeometry = function ( path, segments, radius, radialSegments, closed, numpoints = segments + 1, - x, y, z, - tx, ty, tz, u, v, r, cx, cy, @@ -154,9 +152,7 @@ THREE.TubeGeometry.SinusoidalTaper = function ( u ) { // For computing of Frenet frames, exposing the tangents, normals and binormals the spline THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { - var tangent = new THREE.Vector3(), - normal = new THREE.Vector3(), - binormal = new THREE.Vector3(), + var normal = new THREE.Vector3(), tangents = [], normals = [], @@ -171,7 +167,7 @@ THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { smallest, tx, ty, tz, - i, u, v; + i, u; // expose internals diff --git a/src/extras/helpers/VertexNormalsHelper.js b/src/extras/helpers/VertexNormalsHelper.js index f8c8551773e321..64481b870fa718 100644 --- a/src/extras/helpers/VertexNormalsHelper.js +++ b/src/extras/helpers/VertexNormalsHelper.js @@ -15,8 +15,6 @@ THREE.VertexNormalsHelper = function ( object, size, hex, linewidth ) { var geometry = new THREE.Geometry(); - var vertices = object.geometry.vertices; - var faces = object.geometry.faces; for ( var i = 0, l = faces.length; i < l; i ++ ) { diff --git a/src/extras/helpers/VertexTangentsHelper.js b/src/extras/helpers/VertexTangentsHelper.js index 0403963b0a82d8..4852f9c457299c 100644 --- a/src/extras/helpers/VertexTangentsHelper.js +++ b/src/extras/helpers/VertexTangentsHelper.js @@ -15,8 +15,6 @@ THREE.VertexTangentsHelper = function ( object, size, hex, linewidth ) { var geometry = new THREE.Geometry(); - var vertices = object.geometry.vertices; - var faces = object.geometry.faces; for ( var i = 0, l = faces.length; i < l; i ++ ) { diff --git a/src/extras/objects/MorphBlendMesh.js b/src/extras/objects/MorphBlendMesh.js index 9068259ae3817c..f40ac4becab6db 100644 --- a/src/extras/objects/MorphBlendMesh.js +++ b/src/extras/objects/MorphBlendMesh.js @@ -76,7 +76,6 @@ THREE.MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) { if ( chunks && chunks.length > 1 ) { var name = chunks[ 1 ]; - var num = chunks[ 2 ]; if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity }; diff --git a/src/loaders/JSONLoader.js b/src/loaders/JSONLoader.js index de58c9c5ab7f8d..4b4212e0d3d0d7 100644 --- a/src/loaders/JSONLoader.js +++ b/src/loaders/JSONLoader.js @@ -16,8 +16,6 @@ THREE.JSONLoader.prototype.constructor = THREE.JSONLoader; THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) { - var scope = this; - // todo: unify load API to for easier SceneLoader use texturePath = texturePath && ( typeof texturePath === 'string' ) ? texturePath : this.extractUrlBase( url ); @@ -112,8 +110,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { - var scope = this, - geometry = new THREE.Geometry(), + var geometry = new THREE.Geometry(), scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0; parseModel( scale ); @@ -145,7 +142,7 @@ THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor, - vertex, face, faceA, faceB, color, hex, normal, + vertex, face, faceA, faceB, hex, normal, uvLayer, uv, u, v, diff --git a/src/math/Matrix3.js b/src/math/Matrix3.js index e83957b0e8ae7e..f62ca7036d67aa 100644 --- a/src/math/Matrix3.js +++ b/src/math/Matrix3.js @@ -91,7 +91,7 @@ THREE.Matrix3.prototype = { if ( offset === undefined ) offset = 0; if ( length === undefined ) length = array.length; - for ( var i = 0, j = offset, il; i < length; i += 3, j += 3 ) { + for ( var i = 0, j = offset; i < length; i += 3, j += 3 ) { v1.x = array[ j ]; v1.y = array[ j + 1 ]; diff --git a/src/math/Matrix4.js b/src/math/Matrix4.js index 45a35fb81fe64c..73975d92119234 100644 --- a/src/math/Matrix4.js +++ b/src/math/Matrix4.js @@ -470,7 +470,7 @@ THREE.Matrix4.prototype = { if ( offset === undefined ) offset = 0; if ( length === undefined ) length = array.length; - for ( var i = 0, j = offset, il; i < length; i += 3, j += 3 ) { + for ( var i = 0, j = offset; i < length; i += 3, j += 3 ) { v1.x = array[ j ]; v1.y = array[ j + 1 ]; diff --git a/src/math/Spline.js b/src/math/Spline.js index 6ff994e5b6b362..4ec2d7fb690d30 100644 --- a/src/math/Spline.js +++ b/src/math/Spline.js @@ -125,7 +125,7 @@ THREE.Spline = function ( points ) { var i, j, index, indexCurrent, indexNext, - linearDistance, realDistance, + realDistance, sampling, position, newpoints = [], tmpVec = new THREE.Vector3(), diff --git a/src/objects/Mesh.js b/src/objects/Mesh.js index 7467affca904a2..cab0a902eb8588 100644 --- a/src/objects/Mesh.js +++ b/src/objects/Mesh.js @@ -220,7 +220,7 @@ THREE.Mesh.prototype.raycast = ( function () { var isFaceMaterial = this.material instanceof THREE.MeshFaceMaterial; var objectMaterials = isFaceMaterial === true ? this.material.materials : null; - var a, b, c, d; + var a, b, c; var precision = raycaster.precision; var vertices = geometry.vertices; diff --git a/src/objects/MorphAnimMesh.js b/src/objects/MorphAnimMesh.js index 08d26bc3007814..60936c5c8ef416 100644 --- a/src/objects/MorphAnimMesh.js +++ b/src/objects/MorphAnimMesh.js @@ -70,7 +70,6 @@ THREE.MorphAnimMesh.prototype.parseAnimations = function () { if ( parts && parts.length > 1 ) { var label = parts[ 1 ]; - var num = parts[ 2 ]; if ( ! animations[ label ] ) animations[ label ] = { start: Infinity, end: - Infinity }; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 789bbe0dd3c37b..3bef270862fc01 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1186,7 +1186,7 @@ THREE.WebGLRenderer = function ( parameters ) { function setParticleBuffers ( geometry, hint, object ) { - var v, c, vertex, offset, index, color, + var v, c, vertex, offset, color, vertices = geometry.vertices, vl = vertices.length, @@ -1202,7 +1202,7 @@ THREE.WebGLRenderer = function ( parameters ) { customAttributes = geometry.__webglCustomAttributesList, i, il, - a, ca, cal, value, + ca, cal, value, customAttribute; if ( dirtyVertices ) { @@ -1361,7 +1361,7 @@ THREE.WebGLRenderer = function ( parameters ) { customAttributes = geometry.__webglCustomAttributesList, i, il, - a, ca, cal, value, + ca, cal, value, customAttribute; if ( dirtyVertices ) { @@ -1521,20 +1521,17 @@ THREE.WebGLRenderer = function ( parameters ) { var needsFaceNormals = materialNeedsFaceNormals( material ); var f, fl, fi, face, - vertexNormals, faceNormal, normal, + vertexNormals, faceNormal, vertexColors, faceColor, vertexTangents, - uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4, + uv, uv2, v1, v2, v3, t1, t2, t3, n1, n2, n3, c1, c2, c3, - sw1, sw2, sw3, sw4, - si1, si2, si3, si4, - sa1, sa2, sa3, sa4, - sb1, sb2, sb3, sb4, - m, ml, i, il, + sw1, sw2, sw3, + si1, si2, si3, + i, il, vn, uvi, uv2i, vk, vkl, vka, nka, chf, faceVertexNormals, - a, vertexIndex = 0, @@ -5196,11 +5193,10 @@ THREE.WebGLRenderer = function ( parameters ) { function setupLights ( lights ) { - var l, ll, light, n, + var l, ll, light, r = 0, g = 0, b = 0, color, skyColor, groundColor, - intensity, intensitySq, - position, + intensity, distance, zlights = _lights, diff --git a/src/renderers/webgl/plugins/ShadowMapPlugin.js b/src/renderers/webgl/plugins/ShadowMapPlugin.js index 88e18a92379e23..a5b8e25eaea57a 100644 --- a/src/renderers/webgl/plugins/ShadowMapPlugin.js +++ b/src/renderers/webgl/plugins/ShadowMapPlugin.js @@ -63,7 +63,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje var i, il, j, jl, n, shadowMap, shadowMatrix, shadowCamera, - program, buffer, material, + buffer, material, webglObject, object, light, lights = [], From 34f066a2edbfc5cb3b6342e8ecde583b584a3732 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Mar 2015 17:34:08 +0000 Subject: [PATCH 309/333] Docs: Fixed Matrix4.decompose. See #6229. --- docs/api/math/Matrix4.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/api/math/Matrix4.html b/docs/api/math/Matrix4.html index 9b494e103ecf82..72ee6b3d08a307 100644 --- a/docs/api/math/Matrix4.html +++ b/docs/api/math/Matrix4.html @@ -165,8 +165,7 @@

    [method:Matrix4 compose]( [page:Vector3 translation], [page:Quaternion quate

    [method:Array decompose]( [page:Vector3 translation], [page:Quaternion quaternion], [page:Vector3 scale] )

    - Decomposes this matrix into the *translation*, *quaternion* and *scale* components.
    - If parameters are not passed, new instances will be created. + Decomposes this matrix into the *translation*, *quaternion* and *scale* components.

    [method:Matrix4 makeTranslation]( [page:Float x], [page:Float y], [page:Float z] ) [page:Matrix4 this]

    From c76300c38c1da75f4736e289f6c4b3d9aaaf86d2 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Thu, 12 Mar 2015 18:38:33 +0000 Subject: [PATCH 310/333] Updated builds. --- build/three.js | 104 +++++++++++++++------------------------------ build/three.min.js | 23 +++++----- 2 files changed, 46 insertions(+), 81 deletions(-) diff --git a/build/three.js b/build/three.js index 7502a8bb792d99..d2044478b595fa 100644 --- a/build/three.js +++ b/build/three.js @@ -4284,7 +4284,7 @@ THREE.Matrix3.prototype = { if ( offset === undefined ) offset = 0; if ( length === undefined ) length = array.length; - for ( var i = 0, j = offset, il; i < length; i += 3, j += 3 ) { + for ( var i = 0, j = offset; i < length; i += 3, j += 3 ) { v1.x = array[ j ]; v1.y = array[ j + 1 ]; @@ -4938,7 +4938,7 @@ THREE.Matrix4.prototype = { if ( offset === undefined ) offset = 0; if ( length === undefined ) length = array.length; - for ( var i = 0, j = offset, il; i < length; i += 3, j += 3 ) { + for ( var i = 0, j = offset; i < length; i += 3, j += 3 ) { v1.x = array[ j ]; v1.y = array[ j + 1 ]; @@ -6842,7 +6842,7 @@ THREE.Spline = function ( points ) { var i, j, index, indexCurrent, indexNext, - linearDistance, realDistance, + realDistance, sampling, position, newpoints = [], tmpVec = new THREE.Vector3(), @@ -7423,8 +7423,6 @@ THREE.Object3D = function () { this.up = THREE.Object3D.DefaultUp.clone(); - var scope = this; - var position = new THREE.Vector3(); var rotation = new THREE.Euler(); var quaternion = new THREE.Quaternion(); @@ -9152,12 +9150,12 @@ THREE.BufferGeometry.prototype = { if ( indexBufferSize === undefined ) size = 65535; //WebGL limits type of index buffer values to 16-bit. - var s = Date.now(); + //var s = Date.now(); var indices = this.attributes.index.array; var vertices = this.attributes.position.array; - var verticesCount = ( vertices.length / 3 ); + //var verticesCount = ( vertices.length / 3 ); var facesCount = ( indices.length / 3 ); /* @@ -9688,9 +9686,8 @@ THREE.Geometry.prototype = { // vertex normals weighted by triangle areas // http://www.iquilezles.org/www/articles/normals/normals.htm - var vA, vB, vC, vD; - var cb = new THREE.Vector3(), ab = new THREE.Vector3(), - db = new THREE.Vector3(), dc = new THREE.Vector3(), bc = new THREE.Vector3(); + var vA, vB, vC; + var cb = new THREE.Vector3(), ab = new THREE.Vector3(); for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { @@ -9864,7 +9861,7 @@ THREE.Geometry.prototype = { // based on http://www.terathon.com/code/tangent.html // tangents go to vertices - var f, fl, v, vl, i, il, vertexIndex, + var f, fl, v, vl, i, vertexIndex, face, uv, vA, vB, vC, uvA, uvB, uvC, x1, x2, y1, y2, z1, z2, s1, s2, t1, t2, r, t, test, @@ -10146,8 +10143,8 @@ THREE.Geometry.prototype = { var v, key; var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001 var precision = Math.pow( 10, precisionPoints ); - var i,il, face; - var indices, k, j, jl, u; + var i, il, face; + var indices, j, jl; for ( i = 0, il = this.vertices.length; i < il; i ++ ) { @@ -11856,8 +11853,6 @@ THREE.JSONLoader.prototype.constructor = THREE.JSONLoader; THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) { - var scope = this; - // todo: unify load API to for easier SceneLoader use texturePath = texturePath && ( typeof texturePath === 'string' ) ? texturePath : this.extractUrlBase( url ); @@ -11952,8 +11947,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { - var scope = this, - geometry = new THREE.Geometry(), + var geometry = new THREE.Geometry(), scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0; parseModel( scale ); @@ -11985,7 +11979,7 @@ THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor, - vertex, face, faceA, faceB, color, hex, normal, + vertex, face, faceA, faceB, hex, normal, uvLayer, uv, u, v, @@ -15487,7 +15481,7 @@ THREE.Mesh.prototype.raycast = ( function () { var isFaceMaterial = this.material instanceof THREE.MeshFaceMaterial; var objectMaterials = isFaceMaterial === true ? this.material.materials : null; - var a, b, c, d; + var a, b, c; var precision = raycaster.precision; var vertices = geometry.vertices; @@ -16043,7 +16037,6 @@ THREE.MorphAnimMesh.prototype.parseAnimations = function () { if ( parts && parts.length > 1 ) { var label = parts[ 1 ]; - var num = parts[ 2 ]; if ( ! animations[ label ] ) animations[ label ] = { start: Infinity, end: - Infinity }; @@ -18962,7 +18955,7 @@ THREE.WebGLRenderer = function ( parameters ) { function setParticleBuffers ( geometry, hint, object ) { - var v, c, vertex, offset, index, color, + var v, c, vertex, offset, color, vertices = geometry.vertices, vl = vertices.length, @@ -18978,7 +18971,7 @@ THREE.WebGLRenderer = function ( parameters ) { customAttributes = geometry.__webglCustomAttributesList, i, il, - a, ca, cal, value, + ca, cal, value, customAttribute; if ( dirtyVertices ) { @@ -19137,7 +19130,7 @@ THREE.WebGLRenderer = function ( parameters ) { customAttributes = geometry.__webglCustomAttributesList, i, il, - a, ca, cal, value, + ca, cal, value, customAttribute; if ( dirtyVertices ) { @@ -19297,20 +19290,17 @@ THREE.WebGLRenderer = function ( parameters ) { var needsFaceNormals = materialNeedsFaceNormals( material ); var f, fl, fi, face, - vertexNormals, faceNormal, normal, + vertexNormals, faceNormal, vertexColors, faceColor, vertexTangents, - uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4, + uv, uv2, v1, v2, v3, t1, t2, t3, n1, n2, n3, c1, c2, c3, - sw1, sw2, sw3, sw4, - si1, si2, si3, si4, - sa1, sa2, sa3, sa4, - sb1, sb2, sb3, sb4, - m, ml, i, il, + sw1, sw2, sw3, + si1, si2, si3, + i, il, vn, uvi, uv2i, vk, vkl, vka, nka, chf, faceVertexNormals, - a, vertexIndex = 0, @@ -22972,11 +22962,10 @@ THREE.WebGLRenderer = function ( parameters ) { function setupLights ( lights ) { - var l, ll, light, n, + var l, ll, light, r = 0, g = 0, b = 0, color, skyColor, groundColor, - intensity, intensitySq, - position, + intensity, distance, zlights = _lights, @@ -25504,7 +25493,7 @@ THREE.ShadowMapPlugin = function ( _renderer, _lights, _webglObjects, _webglObje var i, il, j, jl, n, shadowMap, shadowMatrix, shadowCamera, - program, buffer, material, + buffer, material, webglObject, object, light, lights = [], @@ -26692,7 +26681,7 @@ THREE.FontUtils = { ThreeFont.faces[ family ][ data.cssFontWeight ] = ThreeFont.faces[ family ][ data.cssFontWeight ] || {}; ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data; - var face = ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data; + ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data; return data; @@ -26700,11 +26689,9 @@ THREE.FontUtils = { drawText: function ( text ) { - var characterPts = [], allPts = []; - // RenderText - var i, p, + var i, face = this.getFace(), scale = this.size / face.resolution, offset = 0, @@ -26816,8 +26803,8 @@ THREE.FontUtils = { for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) { var t = i2 / divisions; - var tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx ); - var ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy ); + THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx ); + THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy ); } } @@ -26847,8 +26834,8 @@ THREE.FontUtils = { for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) { var t = i2 / divisions; - var tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx ); - var ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy ); + THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx ); + THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy ); } @@ -28611,7 +28598,6 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) { betterShapeHoles[sIdx] = []; } for (var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - var sh = newShapes[sIdx]; var sho = newShapeHoles[sIdx]; for (var hIdx = 0; hIdx < sho.length; hIdx ++ ) { var ho = sho[hIdx]; @@ -31080,7 +31066,6 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var ahole, h, hl; // looping of holes var scope = this; - var bevelPoints = []; var shapesOffset = this.vertices.length; @@ -31139,14 +31124,11 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { var b, bs, t, z, vert, vlen = vertices.length, - face, flen = faces.length, - cont, clen = contour.length; + face, flen = faces.length; // Find directions for point movement - var RAD_TO_DEGREES = 180 / Math.PI; - function getBevelVec( inPt, inPrev, inNext ) { @@ -31249,10 +31231,6 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { // (j)---(i)---(k) // console.log('i,j,k', i, j , k) - var pt_i = contour[ i ]; - var pt_j = contour[ j ]; - var pt_k = contour[ k ]; - contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); } @@ -31693,7 +31671,7 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) { // - var i, l, hole, s; + var i, l, hole; var shapesOffset = this.vertices.length; var shapePoints = shape.extractPoints( curveSegments ); @@ -31742,7 +31720,6 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) { var vert, vlen = vertices.length; var face, flen = faces.length; - var cont, clen = contour.length; for ( i = 0; i < vlen; i ++ ) { @@ -32515,8 +32492,6 @@ THREE.TubeGeometry = function ( path, segments, radius, radialSegments, closed, numpoints = segments + 1, - x, y, z, - tx, ty, tz, u, v, r, cx, cy, @@ -32627,9 +32602,7 @@ THREE.TubeGeometry.SinusoidalTaper = function ( u ) { // For computing of Frenet frames, exposing the tangents, normals and binormals the spline THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { - var tangent = new THREE.Vector3(), - normal = new THREE.Vector3(), - binormal = new THREE.Vector3(), + var normal = new THREE.Vector3(), tangents = [], normals = [], @@ -32644,7 +32617,7 @@ THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { smallest, tx, ty, tz, - i, u, v; + i, u; // expose internals @@ -32802,7 +32775,7 @@ THREE.PolyhedronGeometry = function ( vertices, indices, radius, detail ) { } - var midpoints = [], p = this.vertices; + var p = this.vertices; var faces = []; @@ -32910,7 +32883,6 @@ THREE.PolyhedronGeometry = function ( vertices, indices, radius, detail ) { function subdivide( face, detail ) { var cols = Math.pow(2, detail); - var cells = Math.pow(4, detail); var a = prepare( that.vertices[ face.a ] ); var b = prepare( that.vertices[ face.b ] ); var c = prepare( that.vertices[ face.c ] ); @@ -33198,7 +33170,6 @@ THREE.ParametricGeometry = function ( func, slices, stacks ) { var i, j, p; var u, v; - var stackCount = stacks + 1; var sliceCount = slices + 1; for ( i = 0; i <= stacks; i ++ ) { @@ -34361,8 +34332,6 @@ THREE.VertexNormalsHelper = function ( object, size, hex, linewidth ) { var geometry = new THREE.Geometry(); - var vertices = object.geometry.vertices; - var faces = object.geometry.faces; for ( var i = 0, l = faces.length; i < l; i ++ ) { @@ -34464,8 +34433,6 @@ THREE.VertexTangentsHelper = function ( object, size, hex, linewidth ) { var geometry = new THREE.Geometry(); - var vertices = object.geometry.vertices; - var faces = object.geometry.faces; for ( var i = 0, l = faces.length; i < l; i ++ ) { @@ -34822,7 +34789,6 @@ THREE.MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) { if ( chunks && chunks.length > 1 ) { var name = chunks[ 1 ]; - var num = chunks[ 2 ]; if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity }; diff --git a/build/three.min.js b/build/three.min.js index 57cca79b413dab..b6fdcef89978a7 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -197,7 +197,7 @@ p=new THREE.Vector3,q=new THREE.Vector3,n=new THREE.Vector3;if(a.index)for(var t u.x-s.x;F=r.y-s.y;z=u.y-s.y;I=1/(E*z-G*F);U.set((z*v-F*x)*I,(z*D-F*w)*I,(z*y-F*A)*I);M.set((E*x-G*v)*I,(E*w-G*D)*I,(E*A-G*y)*I);k[a].add(U);k[b].add(U);k[c].add(U);l[a].add(M);l[b].add(M);l[c].add(M)}function b(a){ha.fromArray(e,3*a);O.copy(ha);ba=k[a];oa.copy(ba);oa.sub(ha.multiplyScalar(ha.dot(ba))).normalize();ja.crossVectors(O,ba);qa=ja.dot(l[a]);ca=0>qa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal|| void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array,e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.", a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x, w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5, -a.y));return a.clone()}THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,l=0,p=a.length;lt&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));l=0;for(p=this.vertices.length;lc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5,a.y));return a.clone()} +THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,l=0,p=a.length;lt&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));l=0;for(p=this.vertices.length;l Date: Fri, 13 Mar 2015 17:54:06 +0800 Subject: [PATCH 311/333] Add function for setting volume --- src/extras/audio/Audio.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/extras/audio/Audio.js b/src/extras/audio/Audio.js index dee9d006f1d82f..54e24594d1a412 100644 --- a/src/extras/audio/Audio.js +++ b/src/extras/audio/Audio.js @@ -64,6 +64,12 @@ THREE.Audio.prototype.setRolloffFactor = function ( value ) { }; +THREE.Audio.prototype.setVolume = function ( value ) { + + this.gain.gain.value = value; + +}; + THREE.Audio.prototype.updateMatrixWorld = ( function () { var position = new THREE.Vector3(); From 7c2d4e2e222e47f135c2d7b8d56b1f9315311c18 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Fri, 13 Mar 2015 10:28:37 +0000 Subject: [PATCH 312/333] Updated builds. --- build/three.js | 6 ++++++ build/three.min.js | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/build/three.js b/build/three.js index d2044478b595fa..5f0be51db15f30 100644 --- a/build/three.js +++ b/build/three.js @@ -27160,6 +27160,12 @@ THREE.Audio.prototype.setRolloffFactor = function ( value ) { }; +THREE.Audio.prototype.setVolume = function ( value ) { + + this.gain.gain.value = value; + +}; + THREE.Audio.prototype.updateMatrixWorld = ( function () { var position = new THREE.Vector3(); diff --git a/build/three.min.js b/build/three.min.js index b6fdcef89978a7..22827aef02419a 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -641,7 +641,8 @@ u=void 0,v=void 0,x=void 0,D=void 0,w=void 0,t=a[g[k]].x,s=a[g[k]].y,r=a[g[l]].x !0}}if(n){f.push([a[g[k]],a[g[l]],a[g[p]]]);h.push([g[k],g[l],g[p]]);k=l;for(p=l+1;p Date: Fri, 13 Mar 2015 17:58:51 +0800 Subject: [PATCH 313/333] Add functions for controlling audio (play/pause/stop) --- src/extras/audio/Audio.js | 50 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/extras/audio/Audio.js b/src/extras/audio/Audio.js index dee9d006f1d82f..bb7b34098ed222 100644 --- a/src/extras/audio/Audio.js +++ b/src/extras/audio/Audio.js @@ -17,12 +17,15 @@ THREE.Audio = function ( listener ) { this.panner = this.context.createPanner(); this.panner.connect( this.gain ); + this.startTime = 0; + this.isPlaying = false; + }; THREE.Audio.prototype = Object.create( THREE.Object3D.prototype ); THREE.Audio.prototype.constructor = THREE.Audio; -THREE.Audio.prototype.load = function ( file ) { +THREE.Audio.prototype.load = function ( file, playImmediately ) { var scope = this; @@ -34,8 +37,8 @@ THREE.Audio.prototype.load = function ( file ) { scope.context.decodeAudioData( this.response, function ( buffer ) { scope.source.buffer = buffer; - scope.source.connect( scope.panner ); - scope.source.start( 0 ); + + if( playImmediately !== false ) scope.play(); } ); @@ -46,6 +49,47 @@ THREE.Audio.prototype.load = function ( file ) { }; +THREE.Audio.prototype.play = function () { + + if ( ! this.isPlaying ) { + + var source = this.context.createBufferSource(); + + source.buffer = this.source.buffer; + source.loop = this.source.loop; + source.connect( this.panner ); + source.start( 0, this.startTime ); + + this.isPlaying = true; + + this.source = source; + + } + + else { + + console.warn("Audio is already playing.") + + } + +}; + +THREE.Audio.prototype.pause = function () { + + this.source.stop(); + this.startTime = this.context.currentTime; + this.isPlaying = false; + +}; + +THREE.Audio.prototype.stop = function () { + + this.source.stop(); + this.startTime = 0; + this.isPlaying = false; + +}; + THREE.Audio.prototype.setLoop = function ( value ) { this.source.loop = value; From eda6cd1e0eb4efd1aebfe4205d453993eb2f48b9 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 14 Mar 2015 00:56:00 +0000 Subject: [PATCH 314/333] Geometry.fromBufferGeometry(): Support drawcalls/offsets. See #5864. --- src/core/BufferGeometry.js | 3 ++- src/core/Geometry.js | 28 ++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index 3c24d135c433e0..a7354cfa1c2a9b 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -764,7 +764,8 @@ THREE.BufferGeometry.prototype = { /* Move all attribute values to map to the new computed indices , also expand the vertice stack to match our new vertexPtr. */ this.reorderBuffers( sortedIndices, revVertexMap, vertexPtr ); - this.offsets = offsets; + this.offsets = offsets; // TODO: Deprecate + this.drawcalls = offsets; /* var orderTime = Date.now(); diff --git a/src/core/Geometry.js b/src/core/Geometry.js index 256d6c48157c96..3a571c39c2927a 100644 --- a/src/core/Geometry.js +++ b/src/core/Geometry.js @@ -154,9 +154,33 @@ THREE.Geometry.prototype = { if ( indices !== undefined ) { - for ( var i = 0; i < indices.length; i += 3 ) { + var drawcalls = geometry.drawcalls; - addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); + if ( drawcalls.length > 0 ) { + + for ( var i = 0; i < drawcalls.length; i ++ ) { + + var drawcall = drawcalls[ i ]; + + var start = drawcall.start; + var count = drawcall.count; + var index = drawcall.index; + + for ( var j = start, jl = start + count; j < jl; j += 3 ) { + + addFace( index + indices[ j ], index + indices[ j + 1 ], index + indices[ j + 2 ] ); + + } + + } + + } else { + + for ( var i = 0; i < indices.length; i += 3 ) { + + addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); + + } } From f9db112bca6d410075a22e48583373f8992be59c Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 14 Mar 2015 00:56:16 +0000 Subject: [PATCH 315/333] BufferGeometry: Clean up. --- src/core/BufferGeometry.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index a7354cfa1c2a9b..256873ef8cdf20 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -667,24 +667,18 @@ THREE.BufferGeometry.prototype = { }, /* - computeOffsets - Compute the draw offset for large models by chunking the index buffer into chunks of 65k addressable vertices. - This method will effectively rewrite the index buffer and remap all attributes to match the new indices. - WARNING: This method will also expand the vertex count to prevent sprawled triangles across draw offsets. - indexBufferSize - Defaults to 65535, but allows for larger or smaller chunks. + Compute the draw offset for large models by chunking the index buffer into chunks of 65k addressable vertices. + This method will effectively rewrite the index buffer and remap all attributes to match the new indices. + WARNING: This method will also expand the vertex count to prevent sprawled triangles across draw offsets. + size - Defaults to 65535, but allows for larger or smaller chunks. */ - computeOffsets: function ( indexBufferSize ) { + computeOffsets: function ( size ) { - var size = indexBufferSize; - if ( indexBufferSize === undefined ) - size = 65535; //WebGL limits type of index buffer values to 16-bit. - - //var s = Date.now(); + if ( size === undefined ) size = 65535; // WebGL limits type of index buffer values to 16-bit. var indices = this.attributes.index.array; var vertices = this.attributes.position.array; - //var verticesCount = ( vertices.length / 3 ); var facesCount = ( indices.length / 3 ); /* From 3d6eefce52fb962c65afb9f90d828ffd6431cd5f Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 14 Mar 2015 00:56:58 +0000 Subject: [PATCH 316/333] Updated builds. --- build/three.js | 49 +++++++--- build/three.min.js | 236 ++++++++++++++++++++++----------------------- 2 files changed, 152 insertions(+), 133 deletions(-) diff --git a/build/three.js b/build/three.js index 5f0be51db15f30..e42a23033ff383 100644 --- a/build/three.js +++ b/build/three.js @@ -9138,24 +9138,18 @@ THREE.BufferGeometry.prototype = { }, /* - computeOffsets - Compute the draw offset for large models by chunking the index buffer into chunks of 65k addressable vertices. - This method will effectively rewrite the index buffer and remap all attributes to match the new indices. - WARNING: This method will also expand the vertex count to prevent sprawled triangles across draw offsets. - indexBufferSize - Defaults to 65535, but allows for larger or smaller chunks. + Compute the draw offset for large models by chunking the index buffer into chunks of 65k addressable vertices. + This method will effectively rewrite the index buffer and remap all attributes to match the new indices. + WARNING: This method will also expand the vertex count to prevent sprawled triangles across draw offsets. + size - Defaults to 65535, but allows for larger or smaller chunks. */ - computeOffsets: function ( indexBufferSize ) { + computeOffsets: function ( size ) { - var size = indexBufferSize; - if ( indexBufferSize === undefined ) - size = 65535; //WebGL limits type of index buffer values to 16-bit. - - //var s = Date.now(); + if ( size === undefined ) size = 65535; // WebGL limits type of index buffer values to 16-bit. var indices = this.attributes.index.array; var vertices = this.attributes.position.array; - //var verticesCount = ( vertices.length / 3 ); var facesCount = ( indices.length / 3 ); /* @@ -9235,7 +9229,8 @@ THREE.BufferGeometry.prototype = { /* Move all attribute values to map to the new computed indices , also expand the vertice stack to match our new vertexPtr. */ this.reorderBuffers( sortedIndices, revVertexMap, vertexPtr ); - this.offsets = offsets; + this.offsets = offsets; // TODO: Deprecate + this.drawcalls = offsets; /* var orderTime = Date.now(); @@ -9599,9 +9594,33 @@ THREE.Geometry.prototype = { if ( indices !== undefined ) { - for ( var i = 0; i < indices.length; i += 3 ) { + var drawcalls = geometry.drawcalls; + + if ( drawcalls.length > 0 ) { + + for ( var i = 0; i < drawcalls.length; i ++ ) { + + var drawcall = drawcalls[ i ]; + + var start = drawcall.start; + var count = drawcall.count; + var index = drawcall.index; + + for ( var j = start, jl = start + count; j < jl; j += 3 ) { + + addFace( index + indices[ j ], index + indices[ j + 1 ], index + indices[ j + 2 ] ); + + } + + } + + } else { + + for ( var i = 0; i < indices.length; i += 3 ) { - addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); + addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); + + } } diff --git a/build/three.min.js b/build/three.min.js index 22827aef02419a..f436da92264df1 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -94,21 +94,21 @@ a;b[1]*=a;b[4]*=a;b[7]*=a;b[2]*=a;b[5]*=a;b[8]*=a;return this},determinant:funct c=c[0]*d[0]+c[1]*d[3]+c[2]*d[6];if(0===c){if(b)throw Error("Matrix3.getInverse(): can't invert matrix, determinant is 0");THREE.warn("Matrix3.getInverse(): can't invert matrix, determinant is 0");this.identity();return this}this.multiplyScalar(1/c);return this},transpose:function(){var a,b=this.elements;a=b[1];b[1]=b[3];b[3]=a;a=b[2];b[2]=b[6];b[6]=a;a=b[5];b[5]=b[7];b[7]=a;return this},flattenToArrayOffset:function(a,b){var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4]; a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];return a},getNormalMatrix:function(a){this.getInverse(a).transpose();return this},transposeIntoArray:function(a){var b=this.elements;a[0]=b[0];a[1]=b[3];a[2]=b[6];a[3]=b[1];a[4]=b[4];a[5]=b[7];a[6]=b[2];a[7]=b[5];a[8]=b[8];return this},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]]},clone:function(){return(new THREE.Matrix3).fromArray(this.elements)}}; THREE.Matrix4=function(){this.elements=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);0this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=a||new THREE.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius); return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius},clone:function(){return(new THREE.Sphere).copy(this)}}; THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]}; -THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],l=c[7],p=c[8],q=c[9],n=c[10],t=c[11],s=c[12],r=c[13],u=c[14],c=c[15];b[0].setComponents(f-a,l-g,t-p,c-s).normalize();b[1].setComponents(f+ -a,l+g,t+p,c+s).normalize();b[2].setComponents(f+d,l+h,t+q,c+r).normalize();b[3].setComponents(f-d,l-h,t-q,c-r).normalize();b[4].setComponents(f-e,l-k,t-n,c-u).normalize();b[5].setComponents(f+e,l+k,t+n,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes, +THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],l=c[7],p=c[8],q=c[9],n=c[10],t=c[11],r=c[12],s=c[13],u=c[14],c=c[15];b[0].setComponents(f-a,l-g,t-p,c-r).normalize();b[1].setComponents(f+ +a,l+g,t+p,c+r).normalize();b[2].setComponents(f+d,l+h,t+q,c+s).normalize();b[3].setComponents(f-d,l-h,t-q,c-s).normalize();b[4].setComponents(f-e,l-k,t-n,c-u).normalize();b[5].setComponents(f+e,l+k,t+n,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes, c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)e;e++){var f=d[e];a.x=0g&&0>f)return!1}return!0}}(), containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d, @@ -187,18 +187,18 @@ THREE.DynamicBufferAttribute.prototype.clone=function(){return new THREE.Dynamic THREE.BufferGeometry.prototype={constructor:THREE.BufferGeometry,addAttribute:function(a,b,c){!1===b instanceof THREE.BufferAttribute?(THREE.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),this.attributes[a]={array:b,itemSize:c}):(this.attributes[a]=b,this.attributesKeys=Object.keys(this.attributes))},getAttribute:function(a){return this.attributes[a]},addDrawCall:function(a,b,c){this.drawcalls.push({start:a,count:b,index:void 0!==c?c:0})},applyMatrix:function(a){var b= this.attributes.position;void 0!==b&&(a.applyToVector3Array(b.array),b.needsUpdate=!0);b=this.attributes.normal;void 0!==b&&((new THREE.Matrix3).getNormalMatrix(a).applyToVector3Array(b.array),b.needsUpdate=!0);null!==this.boundingBox&&this.computeBoundingBox();null!==this.boundingSphere&&this.computeBoundingSphere()},center:function(){this.computeBoundingBox();var a=this.boundingBox.center().negate();this.applyMatrix((new THREE.Matrix4).setPosition(a));return a},fromGeometry:function(a,b){b=b||{vertexColors:THREE.NoColors}; var c=a.vertices,d=a.faces,e=a.faceVertexUvs,f=b.vertexColors,g=0qa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal|| +p=new THREE.Vector3,q=new THREE.Vector3,n=new THREE.Vector3;if(a.index)for(var t=a.index.array,r=0qa?-1:1;h[4*a]=oa.x;h[4*a+1]=oa.y;h[4*a+2]=oa.z;h[4*a+3]=ca}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal|| void 0===this.attributes.uv)THREE.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.attributes.index.array,d=this.attributes.position.array,e=this.attributes.normal.array,f=this.attributes.uv.array,g=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*g),4));for(var h=this.attributes.tangent.array,k=[],l=[],p=0;pr;r++)s=a[3*c+r],-1==n[s]?(q[2*r]=s,q[2*r+1]=-1,p++):n[s]k.index+b)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)r=q[p+1],-1p;p+=2)s=q[p],r=q[p+1],-1===r&&(r=g++),n[s]=r,t[r]=s,e[f++]=r-k.index,k.count++}this.reorderBuffers(e,t,g);return this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.", +l[p]=new THREE.Vector3;var q=new THREE.Vector3,n=new THREE.Vector3,t=new THREE.Vector3,r=new THREE.Vector2,s=new THREE.Vector2,u=new THREE.Vector2,v,x,D,w,y,A,E,G,F,z,I,U=new THREE.Vector3,M=new THREE.Vector3,H,L,P,N,R;0===this.drawcalls.length&&this.addDrawCall(0,c.length,0);var V=this.drawcalls,p=0;for(L=V.length;p +s;s++)r=b[3*c+s],-1==n[r]?(q[2*s]=r,q[2*s+1]=-1,p++):n[r]k.index+a)for(k={start:f,count:0,index:g},h.push(k),p=0;6>p;p+=2)s=q[p+1],-1p;p+=2)r=q[p],s=q[p+1],-1===s&&(s=g++),n[r]=s,t[s]=r,e[f++]=s-k.index,k.count++}this.reorderBuffers(e,t,g);return this.drawcalls=this.offsets=h},merge:function(a,b){if(!1===a instanceof THREE.BufferGeometry)THREE.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.", a);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;hd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x, -w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f= -a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;cd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;ca.opacity&&(h.transparent=!0);void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide);void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe); void 0!==a.vertexColors&&("face"===a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=e(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=e(a.colorSpecular));a.colorEmissive&&(h.emissive=e(a.colorEmissive));void 0!==a.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),a.opacity=a.transparency);void 0!==a.opacity&&(h.opacity=a.opacity);a.specularCoef&&(h.shininess= a.specularCoef);a.mapDiffuse&&b&&d(h,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&d(h,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&d(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&d(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&d(h,"specularMap", @@ -266,10 +266,10 @@ a}};THREE.JSONLoader=function(a){THREE.Loader.call(this,a);this.withCredentials= THREE.JSONLoader.prototype.loadAjaxJSON=function(a,b,c,d,e){var f=new XMLHttpRequest,g=0;f.onreadystatechange=function(){if(f.readyState===f.DONE)if(200===f.status||0===f.status){if(f.responseText){var h=JSON.parse(f.responseText);if(void 0!==h.metadata&&4<=h.metadata.version){console.error('THREE.JSONLoader: "'+b+'" should be loaded with THREE.ObjectLoader instead.');return}if(void 0!==h.metadata&&"scene"===h.metadata.type){THREE.error('THREE.JSONLoader: "'+b+'" seems to be a Scene. Use THREE.SceneLoader instead.'); return}h=a.parse(h,d);c(h.geometry,h.materials)}else THREE.error('THREE.JSONLoader: "'+b+'" seems to be unreachable or the file is empty.');a.onLoadComplete()}else THREE.error("THREE.JSONLoader: Couldn't load \""+b+'" ('+f.status+")");else f.readyState===f.LOADING?e&&(0===g&&(g=f.getResponseHeader("Content-Length")),e({total:g,loaded:f.responseText.length})):f.readyState===f.HEADERS_RECEIVED&&void 0!==e&&(g=f.getResponseHeader("Content-Length"))};f.open("GET",b,!0);f.withCredentials=this.withCredentials; f.send(null)}; -THREE.JSONLoader.prototype.parse=function(a,b){var c=new THREE.Geometry,d=void 0!==a.scale?1/a.scale:1;(function(b){var d,g,h,k,l,p,q,n,t,s,r,u,v,x=a.faces;p=a.vertices;var D=a.normals,w=a.colors,y=0;if(void 0!==a.uvs){for(d=0;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1],v=new THREE.Vector2(v,n),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],t.normal.set(D[q++],D[q++],D[q]),r.normal.copy(t.normal));if(s)for(d=0;4>d;d++)q=3*x[k++],s=new THREE.Vector3(D[q++], -D[q++],D[q]),2!==d&&t.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);p&&(p=x[k++],p=w[p],t.color.setHex(p),r.color.setHex(p));if(b)for(d=0;4>d;d++)p=x[k++],p=w[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&r.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(r)}else{t=new THREE.Face3;t.a=x[k++];t.b=x[k++];t.c=x[k++];h&&(h=x[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1], -v=new THREE.Vector2(v,n),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],t.normal.set(D[q++],D[q++],D[q]));if(s)for(d=0;3>d;d++)q=3*x[k++],s=new THREE.Vector3(D[q++],D[q++],D[q]),t.vertexNormals.push(s);p&&(p=x[k++],t.color.setHex(w[p]));if(b)for(d=0;3>d;d++)p=x[k++],t.vertexColors.push(new THREE.Color(w[p]));c.faces.push(t)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1],v=new THREE.Vector2(v,n),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],t.normal.set(D[q++],D[q++],D[q]),s.normal.copy(t.normal));if(r)for(d=0;4>d;d++)q=3*x[k++],r=new THREE.Vector3(D[q++], +D[q++],D[q]),2!==d&&t.vertexNormals.push(r),0!==d&&s.vertexNormals.push(r);p&&(p=x[k++],p=w[p],t.color.setHex(p),s.color.setHex(p));if(b)for(d=0;4>d;d++)p=x[k++],p=w[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&s.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(s)}else{t=new THREE.Face3;t.a=x[k++];t.b=x[k++];t.c=x[k++];h&&(h=x[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1], +v=new THREE.Vector2(v,n),c.faceVertexUvs[d][h].push(v);q&&(q=3*x[k++],t.normal.set(D[q++],D[q++],D[q]));if(r)for(d=0;3>d;d++)q=3*x[k++],r=new THREE.Vector3(D[q++],D[q++],D[q]),t.vertexNormals.push(r);p&&(p=x[k++],t.color.setHex(w[p]));if(b)for(d=0;3>d;d++)p=x[k++],t.vertexColors.push(new THREE.Color(w[p]));c.faces.push(t)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;df||(D=b.origin.distanceTo(p),Dd.far||e.push({distance:D,point:l.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:r,face:null,faceIndex:null, +THREE.BufferGeometry){var n=g.attributes;if(void 0!==n.index){var t=n.index.array,n=n.position.array,r=g.offsets;0===r.length&&(r=[{start:0,count:t.length,index:0}]);for(var s=0;sf||(D=b.origin.distanceTo(p),Dd.far||e.push({distance:D,point:l.clone().applyMatrix4(this.matrixWorld),index:g,offsetIndex:s,face:null,faceIndex:null, object:this}))}}else for(n=n.position.array,g=0;gf||(D=b.origin.distanceTo(p),Dd.far||e.push({distance:D,point:l.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(h=g.vertices,k=h.length,g=0;gf||(D=b.origin.distanceTo(p),Dd.far||e.push({distance:D,point:l.clone().applyMatrix4(this.matrixWorld), index:g,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(a){void 0===a&&(a=new THREE.Line(this.geometry,this.material,this.mode));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype); THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0g.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(r=p.position.array,s=k=0,w=r.length;k -g.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(s=this.material instanceof THREE.MeshFaceMaterial,r=!0===s?this.material.materials:null,t=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this})}}}else for(s=p.position.array,r=k=0,w=s.length;k +g.far||h.push({distance:A,point:y,face:new THREE.Face3(p,q,n,THREE.Triangle.normal(d,e,f)),faceIndex:null,object:this}))}}else if(k instanceof THREE.Geometry)for(r=this.material instanceof THREE.MeshFaceMaterial,s=!0===r?this.material.materials:null,t=g.precision,u=k.vertices,v=0,x=k.faces.length;vg.far||h.push({distance:A,point:y,face:D,faceIndex:v,object:this}))}}}();THREE.Mesh.prototype.clone=function(a,b){void 0===a&&(a=new THREE.Mesh(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a,b);return a};THREE.Bone=function(a){THREE.Object3D.call(this);this.type="Bone";this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone; THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(this.boneTextureHeight=this.boneTextureWidth=a=256h&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in r||(q={id:Qb++,faces3:[],materialIndex:u,vertices:0,numMorphTargets:l, -numMorphNormals:p},r[k]=q,t.push(q)));r[k].faces3.push(s);r[k].vertices+=3}f[g]=t;b.groupsNeedUpdate=!1}f=Ua[b.id];g=0;for(d=f.length;gh&&(e[u].counter+=1,k=e[u].hash+"_"+e[u].counter,k in s||(q={id:Qb++,faces3:[],materialIndex:u,vertices:0,numMorphTargets:l, +numMorphNormals:p},s[k]=q,t.push(q)));s[k].faces3.push(r);s[k].vertices+=3}f[g]=t;b.groupsNeedUpdate=!1}f=Ua[b.id];g=0;for(d=f.length;g -H;H++)I=z[H],I.copy(F[H]),I.unproject(G),I.applyMatrix4(E.matrixWorldInverse),I.xt.x&&(t.x=I.x),I.yt.y&&(t.y=I.y),I.zt.z&&(t.z=I.z);E.left=n.x;E.right=t.x;E.top=t.y;E.bottom=n.y;E.updateProjectionMatrix()}E=A.shadowMap;F=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);s.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(s);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& -(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();F.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);F.multiply(G.projectionMatrix);F.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(E);a.clear();r.length=0;e(c,c,G);A=0;for(E=r.length;At.x&&(t.x=I.x),I.yt.y&&(t.y=I.y),I.zt.z&&(t.z=I.z);E.left=n.x;E.right=t.x;E.top=t.y;E.bottom=n.y;E.updateProjectionMatrix()}E=A.shadowMap;F=A.shadowMatrix;G=A.shadowCamera;G.position.setFromMatrixPosition(A.matrixWorld);r.setFromMatrixPosition(A.target.matrixWorld);G.lookAt(r);G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);A.cameraHelper&& +(A.cameraHelper.visible=A.shadowCameraVisible);A.shadowCameraVisible&&A.cameraHelper.update();F.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);F.multiply(G.projectionMatrix);F.multiply(G.matrixWorldInverse);q.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);p.setFromMatrix(q);a.setRenderTarget(E);a.clear();s.length=0;e(c,c,G);A=0;for(E=s.length;A 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); w.compileShader(L);w.compileShader(P);w.attachShader(H,L);w.attachShader(H,P);w.linkProgram(H);E=H;v=w.getAttribLocation(E,"position");x=w.getAttribLocation(E,"uv");c=w.getUniformLocation(E,"uvOffset");d=w.getUniformLocation(E,"uvScale");e=w.getUniformLocation(E,"rotation");f=w.getUniformLocation(E,"scale");g=w.getUniformLocation(E,"color");h=w.getUniformLocation(E,"map");k=w.getUniformLocation(E,"opacity");l=w.getUniformLocation(E,"modelViewMatrix");p=w.getUniformLocation(E,"projectionMatrix");q= -w.getUniformLocation(E,"fogType");n=w.getUniformLocation(E,"fogDensity");t=w.getUniformLocation(E,"fogNear");s=w.getUniformLocation(E,"fogFar");r=w.getUniformLocation(E,"fogColor");u=w.getUniformLocation(E,"alphaTest");H=document.createElement("canvas");H.width=8;H.height=8;L=H.getContext("2d");L.fillStyle="white";L.fillRect(0,0,8,8);G=new THREE.Texture(H);G.needsUpdate=!0}w.useProgram(E);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, -y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(p,!1,M.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);L=H=0;(P=U.fog)?(w.uniform3f(r,P.color.r,P.color.g,P.color.b),P instanceof THREE.Fog?(w.uniform1f(t,P.near),w.uniform1f(s,P.far),w.uniform1i(q,1),L=H=1):P instanceof THREE.FogExp2&&(w.uniform1f(n,P.density),w.uniform1i(q,2),L=H=2)):(w.uniform1i(q,0),L=H=0);for(var P=0,N=b.length;P< +w.getUniformLocation(E,"fogType");n=w.getUniformLocation(E,"fogDensity");t=w.getUniformLocation(E,"fogNear");r=w.getUniformLocation(E,"fogFar");s=w.getUniformLocation(E,"fogColor");u=w.getUniformLocation(E,"alphaTest");H=document.createElement("canvas");H.width=8;H.height=8;L=H.getContext("2d");L.fillStyle="white";L.fillRect(0,0,8,8);G=new THREE.Texture(H);G.needsUpdate=!0}w.useProgram(E);w.enableVertexAttribArray(v);w.enableVertexAttribArray(x);w.disable(w.CULL_FACE);w.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER, +y);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,A);w.uniformMatrix4fv(p,!1,M.projectionMatrix.elements);w.activeTexture(w.TEXTURE0);w.uniform1i(h,0);L=H=0;(P=U.fog)?(w.uniform3f(s,P.color.r,P.color.g,P.color.b),P instanceof THREE.Fog?(w.uniform1f(t,P.near),w.uniform1f(r,P.far),w.uniform1i(q,1),L=H=1):P instanceof THREE.FogExp2&&(w.uniform1f(n,P.density),w.uniform1i(q,2),L=H=2)):(w.uniform1i(q,0),L=H=0);for(var P=0,N=b.length;P< N;P++){var R=b[P];R._modelViewMatrix.multiplyMatrices(M.matrixWorldInverse,R.matrixWorld);R.z=-R._modelViewMatrix.elements[14]}b.sort(D);for(var V=[],P=0,N=b.length;Pq-1?0:q-1,t=q+1>e-1?e-1:q+1,s=0>p-1?0:p-1,r=p+1>d-1?d-1:p+1,u=[],v=[0,0,h[4*(q*d+p)]/255*b];u.push([-1,0,h[4*(q*d+s)]/255*b]);u.push([-1,-1,h[4*(n*d+s)]/255*b]);u.push([0,-1,h[4*(n*d+p)]/255*b]);u.push([1,-1,h[4*(n*d+r)]/255*b]);u.push([1,0,h[4*(q*d+r)]/255*b]);u.push([1,1,h[4*(t*d+r)]/255*b]);u.push([0,1,h[4*(t*d+p)]/255* -b]);u.push([-1,1,h[4*(t*d+s)]/255*b]);n=[];s=u.length;for(t=0;tq-1?0:q-1,t=q+1>e-1?e-1:q+1,r=0>p-1?0:p-1,s=p+1>d-1?d-1:p+1,u=[],v=[0,0,h[4*(q*d+p)]/255*b];u.push([-1,0,h[4*(q*d+r)]/255*b]);u.push([-1,-1,h[4*(n*d+r)]/255*b]);u.push([0,-1,h[4*(n*d+p)]/255*b]);u.push([1,-1,h[4*(n*d+s)]/255*b]);u.push([1,0,h[4*(q*d+s)]/255*b]);u.push([1,1,h[4*(t*d+s)]/255*b]);u.push([0,1,h[4*(t*d+p)]/255* +b]);u.push([-1,1,h[4*(t*d+r)]/255*b]);n=[];r=u.length;for(t=0;te)return null;var f=[],g=[],h=[],k,l,p;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=l;e<=k&&(k=0);l=k+1;e<=l&&(l=0);p=l+1;e<=p&&(p=0);var n;a:{var t=n=void 0,s=void 0,r=void 0, -u=void 0,v=void 0,x=void 0,D=void 0,w=void 0,t=a[g[k]].x,s=a[g[k]].y,r=a[g[l]].x,u=a[g[l]].y,v=a[g[p]].x,x=a[g[p]].y;if(1E-10>(r-t)*(x-s)-(u-s)*(v-t))n=!1;else{var y=void 0,A=void 0,E=void 0,G=void 0,F=void 0,z=void 0,I=void 0,U=void 0,M=void 0,H=void 0,M=U=I=w=D=void 0,y=v-r,A=x-u,E=t-v,G=s-x,F=r-t,z=u-s;for(n=0;ne)return null;var f=[],g=[],h=[],k,l,p;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=l;e<=k&&(k=0);l=k+1;e<=l&&(l=0);p=l+1;e<=p&&(p=0);var n;a:{var t=n=void 0,r=void 0,s=void 0, +u=void 0,v=void 0,x=void 0,D=void 0,w=void 0,t=a[g[k]].x,r=a[g[k]].y,s=a[g[l]].x,u=a[g[l]].y,v=a[g[p]].x,x=a[g[p]].y;if(1E-10>(s-t)*(x-r)-(u-r)*(v-t))n=!1;else{var y=void 0,A=void 0,E=void 0,G=void 0,F=void 0,z=void 0,I=void 0,U=void 0,M=void 0,H=void 0,M=U=I=w=D=void 0,y=v-s,A=x-u,E=t-v,G=r-x,F=s-t,z=u-r;for(n=0;nMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; +THREE.Path.prototype.getPoints=function(a,b){if(this.useSpacedPoints)return console.log("tata"),this.getSpacedPoints(a,b);a=a||12;var c=[],d,e,f,g,h,k,l,p,q,n,t,r,s;d=0;for(e=this.actions.length;dMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;cn&&(g=b[f],k=-k,h=b[e],n=-n),!(a.yh.y))if(a.y==g.y){if(a.x==g.x)return!0}else{e=n*(a.x-g.x)-k*(a.y-g.y);if(0==e)return!0;0>e||(d=!d)}}else if(a.y==g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<= h.x))return!0}return d}var e=function(a){var b,c,d,e,f=[],g=new THREE.Path;b=0;for(c=a.length;bG||G>E)return[];k=l*p-k*q;if(0>k||k>E)return[]}else{if(0d;d++){for(var e=this.keyTypes[d],f=this.data.hierarchy[a].keys[0],g=this.getNextKeyWith(e,a,1);g.timef.index;)f=g,g=this.getNextKeyWith(e,a,g.index+1);c.prevKey[e]=f;c.nextKey[e]=g}}}; THREE.Animation.prototype.resetBlendWeights=function(){for(var a=0,b=this.hierarchy.length;aa.length-2?q:q+1;c[3]=q>a.length-3?q:q+2;q=a[c[0]];t=a[c[1]];s=a[c[2]];r=a[c[3]];c=e*e;n=e*c;d[0]=f(q[0],t[0],s[0],r[0],e,c,n);d[1]=f(q[1],t[1],s[1],r[1],e,c,n);d[2]=f(q[2],t[2],s[2],r[2],e,c,n);return d},f=function(a,b,c,d,e,f,n){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*n+ -(-3*(b-c)-2*a-d)*f+a*e+b};return function(f){if(!1!==this.isPlaying&&(this.currentTime+=f*this.timeScale,0!==this.weight)){f=this.data.length;if(this.currentTime>f||0>this.currentTime)this.loop?(this.currentTime%=f,0>this.currentTime&&(this.currentTime+=f),this.reset()):this.stop();f=0;for(var h=this.hierarchy.length;fq;q++){var n=this.keyTypes[q],t=l.prevKey[n],s=l.nextKey[n];if(0this.timeScale&&t.time>=this.currentTime){t=this.data.hierarchy[f].keys[0];for(s=this.getNextKeyWith(n,f,1);s.timet.index;)t=s,s=this.getNextKeyWith(n,f,s.index+1);l.prevKey[n]=t;l.nextKey[n]=s}var r=(this.currentTime-t.time)/(s.time-t.time),u=t[n],v=s[n];0>r&&(r=0);1a.length-2?q:q+1;c[3]=q>a.length-3?q:q+2;q=a[c[0]];t=a[c[1]];r=a[c[2]];s=a[c[3]];c=e*e;n=e*c;d[0]=f(q[0],t[0],r[0],s[0],e,c,n);d[1]=f(q[1],t[1],r[1],s[1],e,c,n);d[2]=f(q[2],t[2],r[2],s[2],e,c,n);return d},f=function(a,b,c,d,e,f,n){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*n+ +(-3*(b-c)-2*a-d)*f+a*e+b};return function(f){if(!1!==this.isPlaying&&(this.currentTime+=f*this.timeScale,0!==this.weight)){f=this.data.length;if(this.currentTime>f||0>this.currentTime)this.loop?(this.currentTime%=f,0>this.currentTime&&(this.currentTime+=f),this.reset()):this.stop();f=0;for(var h=this.hierarchy.length;fq;q++){var n=this.keyTypes[q],t=l.prevKey[n],r=l.nextKey[n];if(0this.timeScale&&t.time>=this.currentTime){t=this.data.hierarchy[f].keys[0];for(r=this.getNextKeyWith(n,f,1);r.timet.index;)t=r,r=this.getNextKeyWith(n,f,r.index+1);l.prevKey[n]=t;l.nextKey[n]=r}var s=(this.currentTime-t.time)/(r.time-t.time),u=t[n],v=r[n];0>s&&(s=0);1=this.currentTime?f.interpolate(g,this.currentTime):f.inter THREE.KeyFrameAnimation.prototype.getPrevKeyWith=function(a,b,c){b=this.data.hierarchy[b].keys;for(c=0<=c?c:c+b.length;0<=c;c--)if(b[c].hasTarget(a))return b[c];return b[b.length-1]};THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);a=this.duration/this.frames;var b=Math.floor(this.currentTime/a);b!=this.currentFrame&&(this.mesh.morphTargetInfluences[this.lastFrame]=0,this.mesh.morphTargetInfluences[this.currentFrame]= 1,this.mesh.morphTargetInfluences[b]=0,this.lastFrame=this.currentFrame,this.currentFrame=b);this.mesh.morphTargetInfluences[b]=this.currentTime%a/a;this.mesh.morphTargetInfluences[this.lastFrame]=1-this.mesh.morphTargetInfluences[b]}}}; -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,r){var u,v=h.widthSegments,x=h.heightSegments,D=e/2,w=f/2,y=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",x=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",v=h.depthSegments;var A=v+1,E=x+1,G=e/v,F=f/x,z=new THREE.Vector3;z[u]=0=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(a=!0):Math.sign(e)==Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(O=a.length;0<=--O;){c=O;d=O-1;0>d&&(d=a.length-1);for(var e=0,f=t+2*p,e=0;eMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y, 1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type="ShapeGeometry";!1===a instanceof Array&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;cc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5,a.y));return a.clone()} -THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,l=0,p=a.length;lc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+.5,a.y));return a.clone()} +THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,l=0,p=a.length;lt&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));l=0;for(p=this.vertices.length;ls;s++){d[0]=t[g[s]];d[1]=t[g[(s+1)%3]];d.sort(f);var r=d.toString(); -void 0===e[r]?(e[r]={vert1:d[0],vert2:d[1],face1:q,face2:void 0},p++):e[r].face2=q}d=new Float32Array(6*p);f=0;for(r in e)if(g=e[r],void 0===g.face2||k[g.face1].normal.dot(k[g.face2].normal)<=c)p=l[g.vert1],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z,p=l[g.vert2],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:b}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1}; +THREE.EdgesHelper=function(a,b,c){b=void 0!==b?b:16777215;c=Math.cos(THREE.Math.degToRad(void 0!==c?c:1));var d=[0,0],e={},f=function(a,b){return a-b},g=["a","b","c"],h=new THREE.BufferGeometry,k;a.geometry instanceof THREE.BufferGeometry?(k=new THREE.Geometry,k.fromBufferGeometry(a.geometry)):k=a.geometry.clone();k.mergeVertices();k.computeFaceNormals();var l=k.vertices;k=k.faces;for(var p=0,q=0,n=k.length;qr;r++){d[0]=t[g[r]];d[1]=t[g[(r+1)%3]];d.sort(f);var s=d.toString(); +void 0===e[s]?(e[s]={vert1:d[0],vert2:d[1],face1:q,face2:void 0},p++):e[s].face2=q}d=new Float32Array(6*p);f=0;for(s in e)if(g=e[s],void 0===g.face2||k[g.face1].normal.dot(k[g.face2].normal)<=c)p=l[g.vert1],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z,p=l[g.vert2],d[f++]=p.x,d[f++]=p.y,d[f++]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3));THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:b}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1}; THREE.EdgesHelper.prototype=Object.create(THREE.Line.prototype);THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper; THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=new THREE.Geometry;c=0;for(var e=this.object.geometry.faces.length;cr;r++){d[0]=s[g[r]];d[1]=s[g[(r+1)%3]];d.sort(f);var u=d.toString();void 0===e[u]&&(q[2*p]=d[0],q[2*p+1]=d[1],e[u]=!0,p++)}d=new Float32Array(6*p);n=0;for(t=p;nr;r++)p= -k[q[2*n+r]],g=6*n+3*r,d[g+0]=p.x,d[g+1]=p.y,d[g+2]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3))}else if(a.geometry instanceof THREE.BufferGeometry){if(void 0!==a.geometry.attributes.index){k=a.geometry.attributes.position.array;t=a.geometry.attributes.index.array;l=a.geometry.drawcalls;p=0;0===l.length&&(l=[{count:t.length,index:0,start:0}]);for(var q=new Uint32Array(2*t.length),s=0,v=l.length;sr;r++)d[0]= -g+t[n+r],d[1]=g+t[n+(r+1)%3],d.sort(f),u=d.toString(),void 0===e[u]&&(q[2*p]=d[0],q[2*p+1]=d[1],e[u]=!0,p++);d=new Float32Array(6*p);n=0;for(t=p;nr;r++)g=6*n+3*r,p=3*q[2*n+r],d[g+0]=k[p],d[g+1]=k[p+1],d[g+2]=k[p+2]}else for(k=a.geometry.attributes.position.array,p=k.length/3,q=p/3,d=new Float32Array(6*p),n=0,t=q;nr;r++)g=18*n+6*r,q=9*n+3*r,d[g+0]=k[q],d[g+1]=k[q+1],d[g+2]=k[q+2],p=9*n+(r+1)%3*3,d[g+3]=k[p],d[g+4]=k[p+1],d[g+5]=k[p+2];h.addAttribute("position",new THREE.BufferAttribute(d, +THREE.WireframeHelper=function(a,b){var c=void 0!==b?b:16777215,d=[0,0],e={},f=function(a,b){return a-b},g=["a","b","c"],h=new THREE.BufferGeometry;if(a.geometry instanceof THREE.Geometry){for(var k=a.geometry.vertices,l=a.geometry.faces,p=0,q=new Uint32Array(6*l.length),n=0,t=l.length;ns;s++){d[0]=r[g[s]];d[1]=r[g[(s+1)%3]];d.sort(f);var u=d.toString();void 0===e[u]&&(q[2*p]=d[0],q[2*p+1]=d[1],e[u]=!0,p++)}d=new Float32Array(6*p);n=0;for(t=p;ns;s++)p= +k[q[2*n+s]],g=6*n+3*s,d[g+0]=p.x,d[g+1]=p.y,d[g+2]=p.z;h.addAttribute("position",new THREE.BufferAttribute(d,3))}else if(a.geometry instanceof THREE.BufferGeometry){if(void 0!==a.geometry.attributes.index){k=a.geometry.attributes.position.array;t=a.geometry.attributes.index.array;l=a.geometry.drawcalls;p=0;0===l.length&&(l=[{count:t.length,index:0,start:0}]);for(var q=new Uint32Array(2*t.length),r=0,v=l.length;rs;s++)d[0]= +g+t[n+s],d[1]=g+t[n+(s+1)%3],d.sort(f),u=d.toString(),void 0===e[u]&&(q[2*p]=d[0],q[2*p+1]=d[1],e[u]=!0,p++);d=new Float32Array(6*p);n=0;for(t=p;ns;s++)g=6*n+3*s,p=3*q[2*n+s],d[g+0]=k[p],d[g+1]=k[p+1],d[g+2]=k[p+2]}else for(k=a.geometry.attributes.position.array,p=k.length/3,q=p/3,d=new Float32Array(6*p),n=0,t=q;ns;s++)g=18*n+6*s,q=9*n+3*s,d[g+0]=k[q],d[g+1]=k[q+1],d[g+2]=k[q+2],p=9*n+(s+1)%3*3,d[g+3]=k[p],d[g+4]=k[p+1],d[g+5]=k[p+2];h.addAttribute("position",new THREE.BufferAttribute(d, 3))}THREE.Line.call(this,h,new THREE.LineBasicMaterial({color:c}),THREE.LinePieces);this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.WireframeHelper.prototype=Object.create(THREE.Line.prototype);THREE.WireframeHelper.prototype.constructor=THREE.WireframeHelper;THREE.ImmediateRenderObject=function(){THREE.Object3D.call(this);this.render=function(a){}};THREE.ImmediateRenderObject.prototype=Object.create(THREE.Object3D.prototype);THREE.ImmediateRenderObject.prototype.constructor=THREE.ImmediateRenderObject; THREE.MorphBlendMesh=function(a,b){THREE.Mesh.call(this,a,b);this.animationsMap={};this.animationsList=[];var c=this.geometry.morphTargets.length;this.createAnimation("__default",0,c-1,c/1);this.setAnimationWeight("__default",1)};THREE.MorphBlendMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.MorphBlendMesh.prototype.constructor=THREE.MorphBlendMesh; THREE.MorphBlendMesh.prototype.createAnimation=function(a,b,c,d){b={startFrame:b,endFrame:c,length:c-b+1,fps:d,duration:(c-b)/d,lastFrame:0,currentFrame:0,active:!1,time:0,direction:1,weight:1,directionBackwards:!1,mirroredLoop:!1};this.animationsMap[a]=b;this.animationsList.push(b)}; From 53c2402ac312191b6c306756bb9545bf3c043558 Mon Sep 17 00:00:00 2001 From: Red Solar Date: Fri, 13 Mar 2015 21:52:59 -0500 Subject: [PATCH 317/333] Fixed "Texture is not power of two" warning Decal diffuse texture was generating a warning. Created a new decal diffuse along with a new normal map. This is a replacement pull request for previous request #6196. --- examples/textures/decal/LICENSE.TXT | 5 +++++ examples/textures/decal/decal-diffuse.png | Bin 218370 -> 110747 bytes examples/textures/decal/decal-normal.jpg | Bin 106645 -> 172403 bytes 3 files changed, 5 insertions(+) create mode 100644 examples/textures/decal/LICENSE.TXT diff --git a/examples/textures/decal/LICENSE.TXT b/examples/textures/decal/LICENSE.TXT new file mode 100644 index 00000000000000..a2eb281b466687 --- /dev/null +++ b/examples/textures/decal/LICENSE.TXT @@ -0,0 +1,5 @@ +decal-diffuse.png +decal-normal.jpg + +Licensed under a CC0 1.0 Universal (CC0 1.0) Public Domain Dedication License: +http://creativecommons.org/publicdomain/zero/1.0/ \ No newline at end of file diff --git a/examples/textures/decal/decal-diffuse.png b/examples/textures/decal/decal-diffuse.png index 1eb753be4cb1630eeb551d1c907993ac306d088a..c18707c7abec5c8374603f61f957ba1810a62b15 100644 GIT binary patch literal 110747 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

    f(#>&kq7)+38ft$fT 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 literal 218370 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 z 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 z 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

    dQ34Uv; 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

    DJw4^utKDyQXyUsU?fU^4M8+5P5 zZP>O;5k@9M8UMf{&E09v<0-LaeW~91BpglK6e?}bgvAA^rU3(Kd7j@`OFsC zg&Y)Ogn{c;Ru6iz%~V`cX#nGIWr67AN)-50*>5dY|F4AZBbyn`=4ib?j;dNsj+@�#)Q1U9 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%0A0#gwKN?Nkm`}dd6()Zb(56FYHy?A zrBof<-bT#iue3DU7EcecQw`iawO}ZXw8aYEqt?;>o6c}?wc$S1#C$IrK|z}kKu_fc zf?B>2m-A7{`<^y<98ABZH%TB8lv@Bw4@mE>J1}+`wz?J?F=;cfYhI)woH4neSJ62X z3X=wR-I4{o>k$#+k+?&R7aWVLmd%Bw6eo-^e;t2*td#ColM{5@?{%ag861meqe@)N zt_*+uV%@r-1L?lUxpzOYU$J_q?gcz7aoK%qPikjGLoYA>!&VYeF34#VA4%}8ij^h` zEKL>=2M%D0{4M#{9Mpl{%7itW7)^n%N5jmE9JkgD^A?KyngX-Pv<{SuRT{)uHgaeo zTp%?baxdQgbtw7cID!p6-2QGwpl}XuVW~4}ou9PVd8xyV$A~C_OBR#%kBHZ}Q+FE8 zt$foNL8?<8iK{_YjDArkg2^Rt`iCoo`9Fl_c(kj09!pdst@}+>SXw)p3OEAoKmO$8Eganvb&G|Jqb9D7(W3MQLc8@lXY%S8IaAW{sE<}ZOJuC z{2m4Otph)O5KNF!E3V6!z?IlKNsG5jN4mHhiUIeY0Aw7oPF142?5_(aiCfHN*Tw5C zDueEpovPe}Ny3&##uNlK(q+O1{oZqNbiL+_QbI|XA z4wyvkXb(o$5~I{e)DXd7n=~nHb0HnqkeCJ5Zmg349?Uv6ijh9Wc2EP)xAcx7jRhJ( zP$jfTm6_l)u-&fv=Wds0ti{!1HkN~tq6)31+qi}m{>#gxHG|<9P7&y5+1>F7wjE}8 zrqtj!f3X-+{oSBf`R(HS@=Oz8Iui;Q40JLDtr--2@MvVbrG7$kR8Hki3#lU;AC5g> z!ADQl)z@+Ank~kEJ)fmdl79AYGRMeyVtpF8mZZUi?fdkR20@sYPJ(?dL~Y2q@famS z*j#j(!`#;N#_K!6#H%>}RIMAil|Me1d_K&~d)om2Owp{JR#zZX;b>$}V!9d4#vOQm z-Cx(HuYI=5%YI}#bFmnYrlDru(FCau znbdB#86NnxuW{`mY-h*)q?i3iP0jW0)(E9sM2c4I06( zj4v%U;DG(LY7 zWyD=lz-Fp=y8&Dl!uzCYNFg%P<;j#cH3>5x=#+|mr>6tj9C<4WtN`YCe*M?>?@*A; zH44T%xC~p7Z-KNPE9FFtIQR_=QQPIde%I4pv=&ioGp(+JAOkW6A7GCgLmXszR$FvN z%$^m5xCkH~zUD!_P^8uZAlG&8$FWeNLn|Sb3#qS~NUmWDz7{T|_!++-Yw|Il#E(<2 z0>075lhs3Gkn0P=RC^<$0Ph}?`mp=(+U8+IMeE2XjRDp)4 zbsBanB4~$RKWo0Qd!A!7?}@IPbr73^ez@NPA{QufFB=XlIQxqN0!kJF+^(*al@00G z{}6*Zex0AYI$?L8cqX|#ZP>GX$CoSg!J%NJqb~WTw5a)T#%nyP9w0cGYk)>?_WjR( ze}r*&XFQFT-w0XT{C@}#bEBb+z$R(17(@! z*031xb{^EP5m!nkYxQD`YP%7x|Go*>s-^QaD-+QV?r`v)IlqLZkGpJ0OQ?8XO_-*o zeJHs$w_qJkA@2^@``t;Z60P)H|4%WRL*q#ue@0}wx#do{^HEp#qvIh&g>Yog<>Yf^ z$a)amJz+es1G+3f=TncR5&TWYA!m#a;b5>iZS;zusf#jO4_N=xeA8W(y(jTQ#&NUG z*JNsKExS9iCbb!hnBCTlK;^0dN@sW0M-U0^rs%ubUN&@@`zF>@O(dFH;;7cko-?m=+FQAVES_))@Ksl?Ft0E4ea%|EG90S z>i>rUDff$@5=s{hXM{ysxIx9uap{O94IedhN@$W}I+iq}i03=?gujr|bKIidypl@gHp9d< z88)NhG>QJ4$tZ<~EQrA-3lNzM#qLJjE?!D z;sX{IE-UB2#AjMiwf>-3U#A+@zs^%9wQ%24 zAKx|Hnfc2EqqbdEpAYZ>p~)9v^o_gC_VY4fWZ)p~E~brU z&D}ScsoqR`YVNoxnOe{3_$XfCM&2|qP1EPn>D5VAS}Wmzf6Ao1nQezg8+`a|o=|a7 z5N|Tya%5`Xu93yQvdh?1q)Ku}=}uzrI_ql~vtr!N$^)|2BwDF#O+1?#86&~ci=WZ# zx|Hq#FQw>KT3LoGPl}zO8SlINhd@)Is%RvAyS9WJkF;UZU8(t}f;lp_Tdn1S!dBSr zg}W4n5Bww!_#iyex%|n=*rqUR*eOv{u|;G`T__%}t2gmIiO=a@t@`&HNN(8-g8Q9s*UX39wFR+0BQ+pb;@0h;~)C=%*eQjlpJ*kj9uB3y6ZPKsS?DH34EKO4h- zx1h2`=WW(G^~wG$hHr?T&a1wyx3QnFIWgUqkQq9tY{?`hgxwhrDwnRE-jwm3fm~6- zcpbRN(o@uaHsSKI7gzSsuNqCA!am3Cfc&|UcY@|PxN}t&9Lvm11wX#p#vH)CEn^4u z>8Qw?F9s5<$C4CoCrIU3p=nXNN}{MD~%_9&u}*(EFXyn?^g+>ZVD)OZ>$wT@&!u&OxI z&WH0d`D*9^sfZjc+l8EKr@>R#X&0*}-eeoss>65U_8+hf<5TlTYytJr>%(=ggX)s( zlz?C4c`i&4jCP&D-_wH!d4xPtHZb+86~snR2^z&QZ~M80zfzk^Mnf5)i1fGdM|On2 zB(D&f?R8AY`{tgRQ5!;gLroNNZVi}^<8QAT`0}$ccGz&}$fc#g<;$dMGja5g@i$O$ z$OplI0Ul(41`K@NpVju*ueYU%u08yX1L=>``}arPH^MBw6b~aV!Q*ntoWNDEnd~*S z0Z1T1l0?vs7aEN{-7aHrQEb(x)(FHk@+HiQQ&#Mubx;9@#8$M}ihgeNrsljj;AMhM zdYsmYj}C?-NR%&X$x-@*V6a{c1^KMqTCfQx8Fu+vv?n~hpZEUdm-V_;WVT!wY-m=` z7kL5324*L4&N1= zG=;gGdY7ak#M`sB-51&ee1wFghus=T;W2-9&A5IVqcyt`Xg4p-3g#sHTHx+x<*Nn6FR0{<;5WE)wX+-&V(4rOG(4=iYYSPk;xF z(*@QI^p9TR46FZSP0?i&{KWHEE0T0^>cjG@(H-$c)Jb06=ODZY3Uw0^1WDWr-&W}IxBZ7e_Vt>R zw=*d{={u8ITWAaS$*?-S2s^plT&HUC)p;@=YdSB9ec6N*`qjg%IZ4;@p3xxKlC-7o zlkBUH4^9sxG&wdi1evKrxRWPAeBH5x$Q>C=NJ<-=+0J*ynZ(lASsj!rcrTo(lF)8& zbCXgURh{*NuDEi>ZRwLbn|rAeACd5-Pk=6zOXj>~)LS9wTyfle^(~@#@{WsdudS{e1z*QWx>f-qeqW@fZ+=KE$(^)EhS7R=_3M3{Re?KL5}94- z%M(z1@&J8k!i-_r1`2QxiToU28b!*#Y7y->x?-2v!b3sgFV!RWW?I|u_lmWsK*^~2 z01;K9a;2ai4bk1lYR(Blfk!ECNP`%w`!+psj_j=Wyg}4(55-;jMizoFbcSaUjJ9Ig zGAC8t?__=R+83QYY~j+(v^a3ops6jmA_ERG?NrV+O z2Y+nz1kn!%_Uz9?cTa=qIQur)BEd7yKMLs?z zeazaTR@;{GL>A521JSfq)OK!-O`+x~>(Tlia3D(f-FnIeQ}UXefhKbu2d@=2Pk&!+ zG-jeUbMtrIUr2iI+ZSJWdVuYEe!OMBz-Z*!k^b^!?4`y;lb$;?_i~E?N)a>tBWY9n z1+yL9yp1Zc2!faT+8{$I{4uaCzO?IaP`^+hZE8Gn!EOgc!e6bi+|21Fu`Ch6Yo6_E z#-pL1UKvnWx2`T$1mDe+QYpPF{$5J%7i`59V)mQ9HFkbl7+SG$o?3$T; zebvx*BlNB0T3Ae2fOPF(e}C3R=raS^bI#qnt*sykp;h;j37ntOx}V>u{S)6|%@;hP zcaR!I34JDH#D0D!{cK0TO6Jvfelh~ft@cxre58j055dS`64bHfp@rq}iw%i)g=Xjf z5QY6eefa-1GxC3W)NZAtElpbWj>up9Z}k$f{pa0Z*{`L{k#2&z{o=x+CG>)+UfQ; zrndFJ+Ukhp!f`ux6Tt_EzoU9x2^$&tr47Of0qFI!!B?Nh(uWSOAY!g5GQg@%Q(mTk zpvOg2ChN&ISup$yWTF??;}0f~jDg6X<9hqYmE1||Xuz3wr?q-h{Fv$e<3FB(@3BEz zcdz4)m1|Grua%+jl+o{NZhpPinD=ORoyn)kHn$E0^vc2TfVhK{F^3*zt@2oFHYUe4 zbzmaqXB^(hd&H|vAD-6^I}@alGC&x)0MCJ1!O{{i(f-t4<2%&#s?n81QF9e5NZj5> z3<2-bU4l%{2hxX<4(G@$!6%On9@#vQ_#Kprs3qWBM*%?jfaVg zR+i}m`=|ifpWCclAeKoBQ+kh?&FtvN37t!u5mj`OZYOcyn{S8}oGWr83WJ>SVqyL$ zJv#RfG8Z`W_**$;f$lJA9ZqOzJr92Ea~E_cdE++889uyD5|4_PWxxN@-HBK0hsm$HE1l`sp~@_G;>UJmZ!(p| zzhS7TI2wV~I+Uim+_Q&(>2&C%>N@`sYoUfl1LE?5r$`js8->1KyI%WzvfC{&Qhr^; z**9~+_(7Np0;;+FS5}cSb#OA*I<`~8h}wy2VY0&Y%C?1V1&SK23FNEVepTNfT>-hUCu%fR4o9A6jiciX5jb? z7NcI)u%?jU#vgZZ&xM|ix01GeB6Yk)NN@}!(V_7sVA8{gAww^pH_+9LTsG@`U{go+ z4{weV&KO8zX>u1<>T=xb0DG&BG{{%9d__Y?Gyja8E|7fayAVK{s8LSKN8@mnufY{p;k@r5xq{GLqyoQNE!oj= zq5Iykp0viy=#Am3M>2h6K+p6wo`6I#D(^f=TLXe0bxR;xYyw(uDYL0{d8p2nC>!TF zUUyLD*?daeV_y9AcGz7)zUz$YWRr3wQruEotV@wH65`rp6yGa>WXz@U_%udN&}};? zHEP*EEly;uorN`+e<#T<)yCTi=zj@Xu90?T<^ho_O@lKH7626FMii zZ4nh9_d*i4D|t$eQvpl-E)eP{Eo6vo*>yb$Vr^vpuls*hy+6PZx_hEG#OR;h90Bh9gXTnqQ>{ODZ^|Llehx{rJ|@MAW`{Qc6S-G;nNRsDh^8OvWnL zr7TMaREi0gmmj)!dqfY5m-obgv%WCl%z~68zuhY>rW0PrR~}Ov9z}5KuXD&x#8wqm z%0N+r-1}uQMqYMkhRZehFi8%qfc3+_ypp+)8=&{gXtX4~Bvx+q_mwfrs8^}HLp*us zFotyE_lIs5dE(Qt#=y;if&rC<;ve21pBwriMwiS-w)b*B<*hLh;v7BrFY5fwdnUMkr9@_fJ90Kn#iIQ(XN{El-;*Ige{AOqB?=-t~E9Mf|uuloua>XirnR zfL>7?FRyI>hi-hQox*`z)YQFHu(zINryvGJ7u4ZUaad&GRg1HuNM; zdTnr|#+pPR!3k8<(HfoG@@86AU%Nq|f0aDJfl&QN-1I$MsE0m!4j7{t7gEyk+8$}E z2K>CB8{y{gvxe)horoI8b(fpE>D~#qtoCX2yz;C|YX;mv#y_BV8XAovG?D=_KAFNd;O%Ho>OEt56u%vA_hDFAauuQESJX*p?Zs#+vfayxPrBCwN9H=DP8Fbz8dyNYN6c zG5-b=p6!Ua=~ZXZ5RtpO6Y|09kT%zCv|&|Qdv{#?eN^2CLn~%C*VXZP!g5YJ((dZ8K?u@`$T<-4lXd3aQ}Y@&O9zp z)vP{R_e1|&dL1cqz9l1nDNeReEI{Y7PYM(kTr?i`wpZddV9z)VUgIwm9%NXF_0i-6 zLK~>y3RavA^6*O9s3P+?X6YYV^zkB25u@W?!@m}(cl3N+4%+VI_XA&xXaql$sv`i0 zp2MBQH{4meMX5%m2;{HjW!pPd_VY=lvDhrKfz2C3OJ}b8QWxx0BP zaC!}+W35KrAQ_hB@_ibkK~ZIun?XFZ&z>JeCrk_}zi_LqRd0=NWD#71RoLM*)ytRY zd6LHVKgC**(lKWYC4RLOhSLeIsz<4z1u5{?5AW+b{r@@M`#TXQ7680Kb6M5e%Tv`! zR9cBXfCaezij;x}Gh_m<3ZKXHgP=$nCy-9kcO62 zPX5N4e^Ix}!Cw+PKi1Nqt#_%}X7;>W5{4DTB)MO?0KvU{ap2|0771+sW6WUc zMZbnfj^6pjv6V)ZgKnsgC7DWhY^I&3H+AeK%;;YrN3L!G9uzW)9f?|u*e;kn<8$g0%Ur`mU;(zR`FV$d_#MDY8%q6PkR09OXhDsqfHXG8YbiQ=u>Bu` zaP!B6*OedHQrZdj*1&gyvE1!{1PxEkTnz~+*qErlu!lUYFI;#O+i+WpM%X3h(8THC zGJLxXea(yzJAGw&87Y=H`-6d194iwHZ$&D9li(+o1R?y9kr0wuN?MlRms^G^rmeoob}op09U_BnOPhN;_<5fHt4?XVbVJmsMM60euWvQ^o!0LCf)w!)7jnmOpNCrUkVb{ zhdQJ&u%6tnv}ynQZzNbB*2EUJAK`uG8ik{>y%q=Hh9n8QZW8*iwkUo?>85$C0JZz7 z*m28R-j!Tq34A4R726$L4?26FE)pQ(S!eWUg1%uaCTF?Lgf%H}c5LQa#j8H_F!!RI z-+13}Epya)X@y~h3zq}$U`Q_Du$hl@ zHKrba1(58K>=S+d`8g~f@NWdrlZd7Brk?vpqC6i5_MMvTtG1fyvgpNeTSfEh(fs>c zFC2ebdd8ontG2exh}Nnk0>b5ju`_lcBw8kdL63r3=7J=6G>9W&!#?q`T+ zf>`d`ohB66w-(7`umfsfoSvqh)D03;o#-cUB~B80ooLxoG`3&%dF4?6=sI+MAHIP= z3iTwZ8ygPwf%U|a?+2`vV+PVvtSl4p^YO)TGEx?Nn*t_I8R4ytD_20)Y8-gIzVt<}jPrxnwjPA0rF_9iicNi6SKs^NLl+uFi8b%`X0Ek>X*L|#j`%3mfy zV1=DTRgO^;mu**`f`RC_z<>j^l3DJvIX76?4^i;ryuV$MO+DRU$!~bF33Q+w&0Lh< zF1o#OUrIsf`jY~E3@k*>la2GN$3Qox*>VmH&{lpfWZ#rTzFw6z?ry4>^aCryJIfxi zpAmXCQ=?ipem|^yJX2T9j%Uj}lRayLYsTiIfu!2&QRa?&14pCEY0G+ti7vG=k#I(O zk$$oQjrODkfs}h7)#7U*>Y67~%c#~i+1S*6v^a4pKSU{qqt19o`pi$MWt9fwwUSR7TSIzq9>_n}tM#th|?x?t7FbBd?U( zu3wN0MHq7^Q3qO~kGzTP8(bB>5<{XtKEVpoO=%noma1L z`@?lAp=Y2fPBq%YW136A)D)s>^f4+?*GFVa%*Uyvy-)y`IMlx2-I`YbKKJWtO89uL@E7b zPdabs0w-~fzD4*!*i68}9__P8h_!Qpv6aafQDcuEp=NzD?ENH}w7!5Af>V2sV{qZC zQf2aW9B1Ca@5rOQvPke0sgL65=qk{wH12{Fh%phJrkj(bVy8m+Q;yV))SE!KhlQjo zuOos|IWD@ve$EYn9bIgV$PmYDmgHtMYRI{5<@(S!4wujUt-=cde$HYocK!W*}T`Xm&h`w z42x&I;r^amR27_Kct9i^{zI`8Dx>$f$8O{$FHuOYalQB{JRXY`?lrYkp%?ok8WZ0X zzk#a!WbP-&fgCwpWIcC}tbea9xsq7WHe0t~FKbwa%40&3*hqAc6WUsiN9K9+1xbnr zaZKP;UH5MyKMFH1(eH)u#k_c?MXrBvnAcKZS{XM@b^vR0)U;~enxiDTa)GX>Gc zck_2vgd0h2onK~Gu;&b;bW}lZ-Bq*v(95qhgF_=txf>oyI_7e=%tml`osW#EgOJ^P zVtLBBkn_af#YA-<9vNHv$wJv;inpY%0;U5{&LQHkUqv4e%!)qtZKYn*Xu8&4NLJ?I z?7w!-1LSM}-)KhI^d2d1Y}QXb4BcPAh^pi=s%S5uMn{LhEwa5%G{0tXC9#UC55@VT z4%+3_bxZ9x^KY1F8Z+yV>k18fN`^r?3tA^Zk7`6mOY66T%<)_1&8`eMg+i^~>*1@# zol63v;flxdvp?g0_5o}BK-FXI}FW9rMH(w0$umgez| z43x3`Cm)qO;n#ISqnZtO$lp4b9e84ynFYha7ldFuvO{Xewlykw$duz&tNH&CF!>*k z!bki%1NWy)=r9k$3l!iC64G&4&@XaZoEfZO ztnkx~zkt!ZEByG_7o~QP!*pf>&9KxTrLc3~+jidW{}3>87tLC3VU0qms>Av+ESNHN z(YXbIX_+p_g`e>Z{KHS(dVPN7*4Ii#qOpey%3TO*8cUFJ&bDIlhxw`xoElrK8ist% zJE}eFgd=4}O+E@#OpQ83l5;zjq{KWJYMKx~O2SUM9P8oDqN^|e;NH6DhrN;?2KX6y z4EFwKdW96u(pT5pqb?;xBKX*JdSm@AWWRV$^wMN{^$^eeq>IV{mCuB+yKTlOUoXd! zDVtZb?zCRD+sKO^5e&v#$eDt74J(oqzq7?1Fo*cIDU=IYB)Gk8jPDxrk_Jg4wq6~V z3&oFnlbOozLU4{*izK(#&nf?w?V(WBiOe6haLEfdQF6sPw_d6h^yaAy47Klj$+~2Z z@(;I@S`g6IoeAoB=uvZ^u>Zz6lSC!;I6XZsC+meCPK_wm@_K6`PAw8x_^Z`A<-foC z`@%Cc<=2~pDM2=f3l|twpF4*3{AhSYbk+47yLl3tau8`G%uDj#ertVN4*an&x zSKekxj@;iJ9UVc=PXMr|>C8U;FNe=~z1yHUpSFuf-v36<~L zYFn~_r_gs)^BIHkJ&^L3oP5T3YcutfC(-i?j<KHDouUoN&6QFxahY?Mx+JjGfQ1U#Mwz! z$`HrVQPYx@bzipz?7P1YUh_=O+>zvbu&&ZFjivat44vD z>&C}7b(uXsC1ql?Pl?px4NAXSeKKDQ(f@+p3fkh*D<8}b4xC1B+;70%^1x#7Pf6`osEZ=aQ|DQhN!~E3MWl%9H2~N>M?RA4 z5GaVZdj7)!i=-BbBWo4JeNY9eefg$#gJf1KE)j!hrlsc%J{X@@9ERh^xO3Kby)(Rv z4I2^1j)s@BzfA0|j}>No+|aNlr;VsvhBsb0-($9s(-VAjTxw}KUM|t~QxU`q8uuFx z5*oRqABrn$zh2t3S1d{F1;sv|{F4`oKm_jx$dKNtZVbWjoZrAV?znZT#W*cPo*Q#} zGO^EhT5;c!xG-Gdilje0ak-&o*6qSlH3mW3?IU9_Qb4N`zlo1TpmGV75_8b&Z*#P{ zdjcG9Mvt0doPzYukY0VwtXvHWwq_yah>n&acfbc4oq6%ke=IVQ3Qn-|-|$ISgAZa4 zV=X`QhqP46-)xAg_F5ENe5lZaHF7q!6x%Y7BPj?XU_bzdK?tYYx*@=@ca#maLB@AT z%~Q?vYzz%0-b%sd%2|jHn&c8fb-;b6@M&5B!X#pb(S+fGn2lJ{X99qVIGfn-R;9O` zW(o=f2}91N=)*hE@(CQ?&vqR*sANa30*Io+^r~rJi5Wk0_oR1E^t1_ zoT2-`S6{6MAJyF3dYQEtrmCTr$4y3{Lzw=;?>9HXrG)H3U1ud)*WZ7wbEP`& z^GVbQoKC_ZzVV@LO%@2~jZm;R=O&zqKA_`Lm!56e?GCoqI9(H!Px_#?oWJlZH|5Cy zZ_U+uPAshq@f;nJQE)H&Jn53Og>C>Q49IEzX(JrDBs{q;Rl5ecY@a)t?)A3=DGXiX z;W{W!fR~VztL5m2a&J@qQN;YYHVm4!0DC;#(`cc+$rp!dO96gFoxVga{3%;4c%xX? z|2uL}O0#WB`74K8boVh-JAh^6uuqaX?b;P~tv#!Lo=Nl|8ovIi3@qrATyFj0bsD_v zgtxSXR8KBZ*S?*m03B$96b`@pzZyHwpeC>_04K13g3_BJK>;bDy`U5+5mZV*=^cbX zXi^m+^dd-aQUZun>Ag!r3rY#WNH3uahysFC>A{!Tx3e=l^LBRs-XC}F%x!1x`R;eV z*Qx0*;V>1JEqdf?U1a@S%Iggr7fkm?8o^(Ik+^%1o%(}W8`L584(HY)9Wj(FG3&*n zu_DGW&1sS=aXbVCKSbR3Oj2y#Fy%CzSk~cWmgl+}_}=3+Ezv1}BYCCxqX)g1ljBn( z$^3$vUE|ic) z{VTr;Mm5CuVv$wlF;M$@y|9^p*p<5LRi`0yF8-Et<+mV_Z<66+@H^6~7IS1BGsvZa ziK$n+VOSaD*ugjGir49OuV%FAx+u>+6D^3f#Nw>PC)g=dR45Pvw;?YL$8xH-=GC5; zIq&m0C91QxZ}40hM18$R!$(%{xuipmLcMTAOs#}JgRFhQt@0O*QFV>B6x~s0(Kj38 zMoNGKto9U_K4xpr$W5Q*j6~4rAI?uujNfHRAzRkE9Sg6+65&*pwEML`)BzCbRkd{i z%qU5zu*kXY2$qm@LHxn{rL&CgI$4?@MsfRawc^^o>LSYnC^c?x(@fza#2^LvaV~TX zqh^SO`|&JV8r86A>=;xR%Z;C~xb5I@p(q*(HVNn2=e`YGz^n&6s(S8rVnC=& zk++Bi0CeQQ2_e3;=BA}%e;;Q3mG;f}B6*Z`?c%Ee6DOZS6#Hfq;M5UkLqc*(aY#Ev z(D+O~2fjVZ`9Nwa?{G+Rxr6}UK%!|2$`B*fzL~T4T#yn{AC9jDL~;ZwxUhO5BXsUQ z0dsWVTszMZnpn`+Jr9R;4k&|@$K*EKpfL0E(8|;@Gdd|hz2=k;^?>;) zx7MSrcXhqh8q0b8*ZZk55?&^d3#FT3RvHJe_{x;cj6R=q zg#+X~s}nkjKsW$E-|2X_IsU4MMr4C()14{@$dOt4tsLTPEfd~a-+iO;V*{YmMQ(q> zqCr?^V)Xvvw{$wTw0)pn~Dn*fs-uLd#No~6m&j_U29 z+SZPsE6Iz4{?2lg=mvLhcu1`~rCWDG-jkqAgG#h@_`&@fNlKKyKyNO;gyA7FU{4Es z0alV{mgC7EE05|-DpFH{H}OpxwRRrKcHfF4INb;__5NV(#yA58iQlHY6}4t^N_0PW$MSeL zigNzoJskUaHc&#CRN_tGTnwiGi?x|18hIlsZm}HE0rRSV&Nu!ocLeWIhgs5WT^p8( zEuha&B`JR|&{|rm?dLQN$3>o_2s>(y1*R&sJADm&E%Dv4W3og5{V%{HJFQ{sytT(K zD>>^|wIeb?)5yY|sWy=J)%s-{jHXCzof!T7d($pdQG>6Nsm}}T_^>r6nH%;5mcEoc zrd5RXoHjXYsMEBMp6){PHuZGjIhj^$QAVgYF7T5yDQP2jis{^7n&2PH8dv8(~Hy&bx^ zKI5ylzW_7?B0|tx!`Wng3D#Oi8Cu@*_Lzf?;nvHcKImuZoYgr)TzI0nm!8qdnCa|} z@Ap^Ki-A?n>on$k_c7_YzJkYT7Hf4qUZ7I2m+ z=bjNN(VMf$Nzm20amuXCGSw!%JM&Q11hN>BAY-qm3Fuw%_Tt!X|76^gBo0h(rp z%0jBvn-@L1gmhLX-wvy)?~K51BG-vwi@FxhvDRqR6$nul)C99oAHE$gsEg)e7tEt6 zZUVP9Qvq^;Ms4Xb>3v}SEiYv|Zomo9NQ_PY-(<-Cxc+>!=8y~Piot0O$~7>{<)`hv zqyv&y41T0If&1pN$$)+$ejJb3YE=Q>!_9`O5Rdvw_Tj;~+ao_{@XvPliayZxuZmv; zrJEB`iW|y2#A$}hnZ6dj9@eS{1%cs-j}{h4;rG^Jihs`x{=>N1R%H}vD!9p#PgAgU zuA+XpM}hOj*Ix|ggV?N5X~MgVHSO1^Qr(Il(BMjUNd?Fo8Ve$WP<|0qLWSs!Dq-qV z{Y@JMJVhz&f6TY)!hEnrNmg>pC7AV&zvJdU|q+ z7<45SzG+dDJvB}L*g;T;v>M~K>SBsw6GJ2AoJxvdpL$f|)Y@Oaizm3Y2J20%O09~! zF8jrN_H|QxxtxJbJXh_zFMgN%HcA#6R1bsv7CJQ9H0r5JikZ)r;kx|u!I|L3Ug2O5 z72(B$=#fRwLj^ja&6B2|ln>*RE*;6XAtjkVH^4-)E3OLhUxq1e07e}RDbaP40a?^P z?eXn#QW$0e=WB!>nF(6tuhSe3Nur3*N6)%R^KW@PT{>*vzK}cv>j?J?QA=uX6Q37I z&oi-3P%4$_dmoz&1FD3Ut`?L*`HyLh^+YuO8u9$wMf&?Er+=8aKl(C+3ionFV|inW zwfto(SBCvMB(-M@`_7jN+{Yl4ZrK3Jn!pDN0icrs_5s$K&yRiqIx2ULfwA2+S15i< z^i4`cI#cn40DR^r+s&oKD;$SS{_f!XbMPY3d@w|^AP5Fd^@8TbM@=}x_)J*~Jb7`e zP831V!>1+$0Zpmob^&_ZT&g#|eOTD{e%taPll8vw-u{Sb5MlTXv; z)6jM3wVGhiA^&*d7V9NX^B literal 106645 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

    1|cANaW7{UB!yp5_w7nz)$creGPWbc+5 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 Date: Fri, 13 Mar 2015 22:00:50 -0500 Subject: [PATCH 318/333] Updated normalScale for new texture --- examples/webgl_decals.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/webgl_decals.html b/examples/webgl_decals.html index c046a81e5494b9..3ccc05a81f812f 100644 --- a/examples/webgl_decals.html +++ b/examples/webgl_decals.html @@ -53,7 +53,7 @@ specular: 0x444444, map: decalDiffuse, normalMap: decalNormal, - normalScale: new THREE.Vector2( .15, .15 ), + normalScale: new THREE.Vector2( 1, 1 ), shininess: 30, transparent: true, depthTest: true, From 5ff22c17f2bc3f36e67d61879ad6721bcfc87f37 Mon Sep 17 00:00:00 2001 From: Corey Birnbaum Date: Sat, 14 Mar 2015 00:04:28 -0700 Subject: [PATCH 319/333] Add subScalar() --- src/math/Vector3.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/math/Vector3.js b/src/math/Vector3.js index efdc533543d320..b6ab01316d9d3e 100644 --- a/src/math/Vector3.js +++ b/src/math/Vector3.js @@ -142,6 +142,16 @@ THREE.Vector3.prototype = { return this; }, + + subScalar: function ( s ) { + + this.x -= s; + this.y -= s; + this.z -= s; + + return this; + + }, subVectors: function ( a, b ) { From 15ecabbc7c155408dfac93b82a9f74e6e80dbf90 Mon Sep 17 00:00:00 2001 From: Matthew Tung Date: Sat, 14 Mar 2015 15:37:31 +0800 Subject: [PATCH 320/333] Make playImmediately a property of THREE.Audio, rename it to autoplay and defaults to false --- src/extras/audio/Audio.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/extras/audio/Audio.js b/src/extras/audio/Audio.js index 69aa1980f31b2a..1d5de70cce87c5 100644 --- a/src/extras/audio/Audio.js +++ b/src/extras/audio/Audio.js @@ -2,12 +2,14 @@ * @author mrdoob / http://mrdoob.com/ */ -THREE.Audio = function ( listener ) { +THREE.Audio = function ( listener, autoplay ) { THREE.Object3D.call( this ); this.type = 'Audio'; + this.autoplay = autoplay || false; + this.context = listener.context; this.source = this.context.createBufferSource(); @@ -25,7 +27,7 @@ THREE.Audio = function ( listener ) { THREE.Audio.prototype = Object.create( THREE.Object3D.prototype ); THREE.Audio.prototype.constructor = THREE.Audio; -THREE.Audio.prototype.load = function ( file, playImmediately ) { +THREE.Audio.prototype.load = function ( file ) { var scope = this; @@ -38,7 +40,7 @@ THREE.Audio.prototype.load = function ( file, playImmediately ) { scope.source.buffer = buffer; - if( playImmediately !== false ) scope.play(); + if( scope.autoplay ) scope.play(); } ); From 21844b4c94596420bc57b73b69412d8bc34e66fd Mon Sep 17 00:00:00 2001 From: Matthew Tung Date: Sat, 14 Mar 2015 15:39:34 +0800 Subject: [PATCH 321/333] Use source.onended for handling the 'ended' event (in response to the audio track finishing playback) --- src/extras/audio/Audio.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/extras/audio/Audio.js b/src/extras/audio/Audio.js index 1d5de70cce87c5..de90a610743b33 100644 --- a/src/extras/audio/Audio.js +++ b/src/extras/audio/Audio.js @@ -12,6 +12,7 @@ THREE.Audio = function ( listener, autoplay ) { this.context = listener.context; this.source = this.context.createBufferSource(); + this.source.onended = this.onEnded.bind(this); this.gain = this.context.createGain(); this.gain.connect( this.context.destination ); @@ -59,6 +60,7 @@ THREE.Audio.prototype.play = function () { source.buffer = this.source.buffer; source.loop = this.source.loop; + source.onended = this.source.onended; source.connect( this.panner ); source.start( 0, this.startTime ); @@ -80,7 +82,6 @@ THREE.Audio.prototype.pause = function () { this.source.stop(); this.startTime = this.context.currentTime; - this.isPlaying = false; }; @@ -88,6 +89,11 @@ THREE.Audio.prototype.stop = function () { this.source.stop(); this.startTime = 0; + +}; + +THREE.Audio.prototype.onEnded = function() { + this.isPlaying = false; }; From 1f97cfaa5d931ae34229ff8fa9c632e99a3b8249 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 14 Mar 2015 18:36:02 +0000 Subject: [PATCH 322/333] Added subScalar to Vector2 and Vector4 too. --- src/math/Vector2.js | 21 +++++++++++++++------ src/math/Vector4.js | 11 +++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/math/Vector2.js b/src/math/Vector2.js index d9fba4218445f9..ce352eea1a641a 100644 --- a/src/math/Vector2.js +++ b/src/math/Vector2.js @@ -90,19 +90,19 @@ THREE.Vector2.prototype = { }, - addVectors: function ( a, b ) { + addScalar: function ( s ) { - this.x = a.x + b.x; - this.y = a.y + b.y; + this.x += s; + this.y += s; return this; }, - addScalar: function ( s ) { + addVectors: function ( a, b ) { - this.x += s; - this.y += s; + this.x = a.x + b.x; + this.y = a.y + b.y; return this; @@ -124,6 +124,15 @@ THREE.Vector2.prototype = { }, + subScalar: function ( s ) { + + this.x -= s; + this.y -= s; + + return this; + + }, + subVectors: function ( a, b ) { this.x = a.x - b.x; diff --git a/src/math/Vector4.js b/src/math/Vector4.js index 940f3ce8cb0764..1a7bf50c347875 100644 --- a/src/math/Vector4.js +++ b/src/math/Vector4.js @@ -159,6 +159,17 @@ THREE.Vector4.prototype = { }, + subScalar: function ( s ) { + + this.x -= s; + this.y -= s; + this.z -= s; + this.w -= s; + + return this; + + }, + subVectors: function ( a, b ) { this.x = a.x - b.x; From 6aeb6741b38960c120038d1842a6b12cf71f4708 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 14 Mar 2015 18:37:00 +0000 Subject: [PATCH 323/333] Updated builds. --- build/three.js | 42 ++++++++++++++++++++++++++----- build/three.min.js | 62 +++++++++++++++++++++++----------------------- 2 files changed, 67 insertions(+), 37 deletions(-) diff --git a/build/three.js b/build/three.js index e42a23033ff383..ceda3382564df3 100644 --- a/build/three.js +++ b/build/three.js @@ -1275,19 +1275,19 @@ THREE.Vector2.prototype = { }, - addVectors: function ( a, b ) { + addScalar: function ( s ) { - this.x = a.x + b.x; - this.y = a.y + b.y; + this.x += s; + this.y += s; return this; }, - addScalar: function ( s ) { + addVectors: function ( a, b ) { - this.x += s; - this.y += s; + this.x = a.x + b.x; + this.y = a.y + b.y; return this; @@ -1309,6 +1309,15 @@ THREE.Vector2.prototype = { }, + subScalar: function ( s ) { + + this.x -= s; + this.y -= s; + + return this; + + }, + subVectors: function ( a, b ) { this.x = a.x - b.x; @@ -1758,6 +1767,16 @@ THREE.Vector3.prototype = { return this; }, + + subScalar: function ( s ) { + + this.x -= s; + this.y -= s; + this.z -= s; + + return this; + + }, subVectors: function ( a, b ) { @@ -2618,6 +2637,17 @@ THREE.Vector4.prototype = { }, + subScalar: function ( s ) { + + this.x -= s; + this.y -= s; + this.z -= s; + this.w -= s; + + return this; + + }, + subVectors: function ( a, b ) { this.x = a.x - b.x; diff --git a/build/three.min.js b/build/three.min.js index f436da92264df1..f0994d1f6eb516 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -31,41 +31,41 @@ return a.applyQuaternion(this)},slerp:function(a,b){if(0===b)return this;if(1=== Math.sin(b*h)/k;this._w=f*g+this._w*h;this._x=c*g+this._x*h;this._y=d*g+this._y*h;this._z=e*g+this._z*h;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback= a;return this},onChangeCallback:function(){},clone:function(){return new THREE.Quaternion(this._x,this._y,this._z,this._w)}};THREE.Quaternion.slerp=function(a,b,c,d){return c.copy(a).slerp(b,d)};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; THREE.Vector2.prototype={constructor:THREE.Vector2,set:function(a,b){this.x=a;this.y=b;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a, -b){if(void 0!==b)return THREE.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this}, -subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a):this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector2,b=new THREE.Vector2);a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this}, -roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b= -this.x-a.x;a=this.y-a.y;return b*b+a*a},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x; -a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];return this},clone:function(){return new THREE.Vector2(this.x,this.y)}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; +b){if(void 0!==b)return THREE.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this}, +subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a):this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector2,b=new THREE.Vector2);a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x= +Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))}, +distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0=== +a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];return this},clone:function(){return new THREE.Vector2(this.x,this.y)}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+ a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), -this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y= -a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&&THREE.error("THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));return this}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),applyMatrix3:function(a){var b=this.x, -c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z= -(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,l=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-l*-f;this.y=k*a+b*-f+l*-e-h*-g;this.z=l*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0=== -a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},min:function(a){this.x> -a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3,b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a, -b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z); -return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/ -b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},cross:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c= -a.x,d=a.y,e=a.z,f=b.x,g=b.y,h=b.z;this.x=d*h-e*g;this.y=e*f-c*h;this.z=c*g-d*f;return this},projectOnVector:function(){var a,b;return function(c){void 0===a&&(a=new THREE.Vector3);a.copy(c).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);return this.sub(a.copy(b).multiplyScalar(2* -this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/(this.length()*a.length());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},setEulerFromRotationMatrix:function(a,b){THREE.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")},setEulerFromQuaternion:function(a,b){THREE.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")}, -getPositionFromMatrix:function(a){THREE.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},getScaleFromMatrix:function(a){THREE.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a,b){THREE.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(a,b)},setFromMatrixPosition:function(a){this.x= -a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},setFromMatrixScale:function(a){var b=this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length();a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x===this.x&&a.y===this.y&& -a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];return this},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)}}; -THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*= +a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&&THREE.error("THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));return this}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b, +c));return this}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]* +c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,l=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-l*-f;this.y=k*a+b*-f+l*-e-h*-g;this.z=l*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(), +unproject:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*= +a):this.z=this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3, +b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y): +Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())}, +setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},cross:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y= +e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c=a.x,d=a.y,e=a.z,f=b.x,g=b.y,h=b.z;this.x=d*h-e*g;this.y=e*f-c*h;this.z=c*g-d*f;return this},projectOnVector:function(){var a,b;return function(c){void 0===a&&(a=new THREE.Vector3);a.copy(c).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0=== +a&&(a=new THREE.Vector3);return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/(this.length()*a.length());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},setEulerFromRotationMatrix:function(a,b){THREE.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")}, +setEulerFromQuaternion:function(a,b){THREE.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")},getPositionFromMatrix:function(a){THREE.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},getScaleFromMatrix:function(a){THREE.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a, +b){THREE.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(a,b)},setFromMatrixPosition:function(a){this.x=a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},setFromMatrixScale:function(a){var b=this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length();a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a; +return this},setFromMatrixColumn:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z= +a.array[b+2];return this},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)}};THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x; case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a, -b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b= -this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a):(this.z=this.y=this.x=0,this.w=1);return this},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this}, -setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var l=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+l-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;l=(l+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>l?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>l?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h), -b=d/c,d=k/c):.01>l?(c=b=.707106781,d=0):(d=Math.sqrt(l),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+l-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);this.wb.w&&(this.w=b.w);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector4,b=new THREE.Vector4);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w); -return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w); -return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())}, -setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a, -b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=a.array[b+3];return this},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)}};THREE.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||THREE.Euler.DefaultOrder};THREE.Euler.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" "); -THREE.Euler.DefaultOrder="XYZ"; +b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return THREE.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*= +a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a):(this.z=this.y=this.x=0,this.w=1);return this},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4> +b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var l=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+l-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;l=(l+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>l?.01>e?(b=0,d=c=.707106781):(b= +Math.sqrt(e),c=d/b,d=f/b):h>l?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h),b=d/c,d=k/c):.01>l?(c=b=.707106781,d=0):(d=Math.sqrt(l),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+l-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);this.wb.w&&(this.w=b.w);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector4,b=new THREE.Vector4);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x= +Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y); +this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+ +Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w}, +fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=a.array[b+3];return this},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)}}; +THREE.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||THREE.Euler.DefaultOrder};THREE.Euler.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" ");THREE.Euler.DefaultOrder="XYZ"; THREE.Euler.prototype={constructor:THREE.Euler,_x:0,_y:0,_z:0,_order:THREE.Euler.DefaultOrder,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get order(){return this._order},set order(a){this._order=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this.onChangeCallback();return this},copy:function(a){this._x= a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],l=e[9],p=e[2],q=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-l,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(q,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(l,-1,1)),.99999>Math.abs(l)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h, k)):(this._y=Math.atan2(-p,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(q,-1,1)),.99999>Math.abs(q)?(this._y=Math.atan2(-p,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(p,-1,1)),.99999>Math.abs(p)?(this._x=Math.atan2(q,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-l,k),this._y=Math.atan2(-p,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z= From 493933f42893d713d1ef3dba5a2a2caac04fe8d2 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 14 Mar 2015 18:54:08 +0000 Subject: [PATCH 324/333] Audio: Keeping constructor simple. --- src/extras/audio/Audio.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/extras/audio/Audio.js b/src/extras/audio/Audio.js index de90a610743b33..8cf0d4db242e4d 100644 --- a/src/extras/audio/Audio.js +++ b/src/extras/audio/Audio.js @@ -2,14 +2,12 @@ * @author mrdoob / http://mrdoob.com/ */ -THREE.Audio = function ( listener, autoplay ) { +THREE.Audio = function ( listener ) { THREE.Object3D.call( this ); this.type = 'Audio'; - this.autoplay = autoplay || false; - this.context = listener.context; this.source = this.context.createBufferSource(); this.source.onended = this.onEnded.bind(this); @@ -20,6 +18,8 @@ THREE.Audio = function ( listener, autoplay ) { this.panner = this.context.createPanner(); this.panner.connect( this.gain ); + this.autoplay = false; + this.startTime = 0; this.isPlaying = false; From f6904327f486a6044453a665b4db7583cb7bd22b Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 14 Mar 2015 18:56:07 +0000 Subject: [PATCH 325/333] Audio: Code clean up. --- src/extras/audio/Audio.js | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/extras/audio/Audio.js b/src/extras/audio/Audio.js index 8cf0d4db242e4d..1c922ba35c8018 100644 --- a/src/extras/audio/Audio.js +++ b/src/extras/audio/Audio.js @@ -54,27 +54,24 @@ THREE.Audio.prototype.load = function ( file ) { THREE.Audio.prototype.play = function () { - if ( ! this.isPlaying ) { + if ( this.isPlaying === true ) { - var source = this.context.createBufferSource(); - - source.buffer = this.source.buffer; - source.loop = this.source.loop; - source.onended = this.source.onended; - source.connect( this.panner ); - source.start( 0, this.startTime ); - - this.isPlaying = true; - - this.source = source; + THREE.warn( 'THREE.Audio: Audio is already playing.' ); + return; } - else { + var source = this.context.createBufferSource(); - console.warn("Audio is already playing.") + source.buffer = this.source.buffer; + source.loop = this.source.loop; + source.onended = this.source.onended; + source.connect( this.panner ); + source.start( 0, this.startTime ); - } + this.isPlaying = true; + + this.source = source; }; From b71ae55ce03e996e423daa29a26e9d774032d05d Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 14 Mar 2015 18:56:40 +0000 Subject: [PATCH 326/333] Updated builds. --- build/three.js | 53 ++++++++++++++++++++++++++++++++++++++++++++-- build/three.min.js | 9 ++++---- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/build/three.js b/build/three.js index ceda3382564df3..c83c01cd65ad84 100644 --- a/build/three.js +++ b/build/three.js @@ -27155,6 +27155,7 @@ THREE.Audio = function ( listener ) { this.context = listener.context; this.source = this.context.createBufferSource(); + this.source.onended = this.onEnded.bind(this); this.gain = this.context.createGain(); this.gain.connect( this.context.destination ); @@ -27162,6 +27163,11 @@ THREE.Audio = function ( listener ) { this.panner = this.context.createPanner(); this.panner.connect( this.gain ); + this.autoplay = false; + + this.startTime = 0; + this.isPlaying = false; + }; THREE.Audio.prototype = Object.create( THREE.Object3D.prototype ); @@ -27179,8 +27185,8 @@ THREE.Audio.prototype.load = function ( file ) { scope.context.decodeAudioData( this.response, function ( buffer ) { scope.source.buffer = buffer; - scope.source.connect( scope.panner ); - scope.source.start( 0 ); + + if( scope.autoplay ) scope.play(); } ); @@ -27191,6 +27197,49 @@ THREE.Audio.prototype.load = function ( file ) { }; +THREE.Audio.prototype.play = function () { + + if ( this.isPlaying === true ) { + + THREE.warn( 'THREE.Audio: Audio is already playing.' ); + return; + + } + + var source = this.context.createBufferSource(); + + source.buffer = this.source.buffer; + source.loop = this.source.loop; + source.onended = this.source.onended; + source.connect( this.panner ); + source.start( 0, this.startTime ); + + this.isPlaying = true; + + this.source = source; + +}; + +THREE.Audio.prototype.pause = function () { + + this.source.stop(); + this.startTime = this.context.currentTime; + +}; + +THREE.Audio.prototype.stop = function () { + + this.source.stop(); + this.startTime = 0; + +}; + +THREE.Audio.prototype.onEnded = function() { + + this.isPlaying = false; + +}; + THREE.Audio.prototype.setLoop = function ( value ) { this.source.loop = value; diff --git a/build/three.min.js b/build/three.min.js index f0994d1f6eb516..41ca77accbeeaf 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -639,10 +639,11 @@ THREE.FontUtils.generateShapes=function(a,b){b=b||{};var c=void 0!==b.curveSegme (function(a){var b=function(a){for(var b=a.length,e=0,f=b-1,g=0;ge)return null;var f=[],g=[],h=[],k,l,p;if(0=q--){THREE.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=l;e<=k&&(k=0);l=k+1;e<=l&&(l=0);p=l+1;e<=p&&(p=0);var n;a:{var t=n=void 0,r=void 0,s=void 0, u=void 0,v=void 0,x=void 0,D=void 0,w=void 0,t=a[g[k]].x,r=a[g[k]].y,s=a[g[l]].x,u=a[g[l]].y,v=a[g[p]].x,x=a[g[p]].y;if(1E-10>(s-t)*(x-r)-(u-r)*(v-t))n=!1;else{var y=void 0,A=void 0,E=void 0,G=void 0,F=void 0,z=void 0,I=void 0,U=void 0,M=void 0,H=void 0,M=U=I=w=D=void 0,y=v-s,A=x-u,E=t-v,G=r-x,F=s-t,z=u-r;for(n=0;n Date: Sat, 14 Mar 2015 20:17:18 +0000 Subject: [PATCH 327/333] Texture: Added sourceFile property. See #6236. --- src/textures/Texture.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textures/Texture.js b/src/textures/Texture.js index dd2d513eda379f..231f71a55a6418 100644 --- a/src/textures/Texture.js +++ b/src/textures/Texture.js @@ -11,6 +11,7 @@ THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, f this.uuid = THREE.Math.generateUUID(); this.name = ''; + this.sourceFile = ''; this.image = image !== undefined ? image : THREE.Texture.DEFAULT_IMAGE; this.mipmaps = []; From 11f629d1ef34e027d2cddbbb3bd183381f948eb0 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 15 Mar 2015 18:07:42 +0000 Subject: [PATCH 328/333] JSONLoader: Improved metadata parsing. --- src/loaders/JSONLoader.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/loaders/JSONLoader.js b/src/loaders/JSONLoader.js index 4b4212e0d3d0d7..9e6832db2b52db 100644 --- a/src/loaders/JSONLoader.js +++ b/src/loaders/JSONLoader.js @@ -40,18 +40,23 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex if ( xhr.responseText ) { var json = JSON.parse( xhr.responseText ); + var metadata = json.metadata; - if ( json.metadata !== undefined && json.metadata.version >= 4 ) { + if ( metadata !== undefined ) { - console.error( 'THREE.JSONLoader: "' + url + '" should be loaded with THREE.ObjectLoader instead.' ); - return; + if ( metadata.type === 'object' ) { - } + THREE.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' ); + return; + + } - if ( json.metadata !== undefined && json.metadata.type === 'scene' ) { + if ( metadata.type === 'scene' ) { - THREE.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' ); - return; + THREE.error( 'THREE.JSONLoader: ' + url + ' seems to be a Scene. Use THREE.SceneLoader instead.' ); + return; + + } } @@ -60,7 +65,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex } else { - THREE.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' ); + THREE.error( 'THREE.JSONLoader: ' + url + ' seems to be unreachable or the file is empty.' ); } @@ -72,7 +77,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex } else { - THREE.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' ); + THREE.error( 'THREE.JSONLoader: Couldn\'t load ' + url + ' (' + xhr.status + ')' ); } From 94092d171d9f5226bb8047710fd2ebc65d094438 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 15 Mar 2015 18:07:52 +0000 Subject: [PATCH 329/333] Updated builds. --- build/three.js | 24 +++++++++++++++--------- build/three.min.js | 9 ++++----- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/build/three.js b/build/three.js index c83c01cd65ad84..c2cd9fe63b055f 100644 --- a/build/three.js +++ b/build/three.js @@ -11926,18 +11926,23 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex if ( xhr.responseText ) { var json = JSON.parse( xhr.responseText ); + var metadata = json.metadata; - if ( json.metadata !== undefined && json.metadata.version >= 4 ) { + if ( metadata !== undefined ) { - console.error( 'THREE.JSONLoader: "' + url + '" should be loaded with THREE.ObjectLoader instead.' ); - return; + if ( metadata.type === 'object' ) { - } + THREE.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' ); + return; + + } - if ( json.metadata !== undefined && json.metadata.type === 'scene' ) { + if ( metadata.type === 'scene' ) { - THREE.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' ); - return; + THREE.error( 'THREE.JSONLoader: ' + url + ' seems to be a Scene. Use THREE.SceneLoader instead.' ); + return; + + } } @@ -11946,7 +11951,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex } else { - THREE.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' ); + THREE.error( 'THREE.JSONLoader: ' + url + ' seems to be unreachable or the file is empty.' ); } @@ -11958,7 +11963,7 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex } else { - THREE.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' ); + THREE.error( 'THREE.JSONLoader: Couldn\'t load ' + url + ' (' + xhr.status + ')' ); } @@ -14697,6 +14702,7 @@ THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, f this.uuid = THREE.Math.generateUUID(); this.name = ''; + this.sourceFile = ''; this.image = image !== undefined ? image : THREE.Texture.DEFAULT_IMAGE; this.mipmaps = []; diff --git a/build/three.min.js b/build/three.min.js index 41ca77accbeeaf..5084a609d9e43e 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -263,9 +263,8 @@ THREE.XHRLoader.prototype={constructor:THREE.XHRLoader,load:function(a,b,c,d){va this.responseType),f.send(null),e.manager.itemStart(a))},setResponseType:function(a){this.responseType=a},setCrossOrigin:function(a){this.crossOrigin=a}};THREE.ImageLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager}; THREE.ImageLoader.prototype={constructor:THREE.ImageLoader,load:function(a,b,c,d){var e=this,f=THREE.Cache.get(a);if(void 0!==f)b(f);else return f=document.createElement("img"),f.addEventListener("load",function(c){THREE.Cache.add(a,this);b&&b(this);e.manager.itemEnd(a)},!1),void 0!==c&&f.addEventListener("progress",function(a){c(a)},!1),void 0!==d&&f.addEventListener("error",function(a){d(a)},!1),void 0!==this.crossOrigin&&(f.crossOrigin=this.crossOrigin),f.src=a,e.manager.itemStart(a),f},setCrossOrigin:function(a){this.crossOrigin= a}};THREE.JSONLoader=function(a){THREE.Loader.call(this,a);this.withCredentials=!1};THREE.JSONLoader.prototype=Object.create(THREE.Loader.prototype);THREE.JSONLoader.prototype.constructor=THREE.JSONLoader;THREE.JSONLoader.prototype.load=function(a,b,c){c=c&&"string"===typeof c?c:this.extractUrlBase(a);this.onLoadStart();this.loadAjaxJSON(this,a,b,c)}; -THREE.JSONLoader.prototype.loadAjaxJSON=function(a,b,c,d,e){var f=new XMLHttpRequest,g=0;f.onreadystatechange=function(){if(f.readyState===f.DONE)if(200===f.status||0===f.status){if(f.responseText){var h=JSON.parse(f.responseText);if(void 0!==h.metadata&&4<=h.metadata.version){console.error('THREE.JSONLoader: "'+b+'" should be loaded with THREE.ObjectLoader instead.');return}if(void 0!==h.metadata&&"scene"===h.metadata.type){THREE.error('THREE.JSONLoader: "'+b+'" seems to be a Scene. Use THREE.SceneLoader instead.'); -return}h=a.parse(h,d);c(h.geometry,h.materials)}else THREE.error('THREE.JSONLoader: "'+b+'" seems to be unreachable or the file is empty.');a.onLoadComplete()}else THREE.error("THREE.JSONLoader: Couldn't load \""+b+'" ('+f.status+")");else f.readyState===f.LOADING?e&&(0===g&&(g=f.getResponseHeader("Content-Length")),e({total:g,loaded:f.responseText.length})):f.readyState===f.HEADERS_RECEIVED&&void 0!==e&&(g=f.getResponseHeader("Content-Length"))};f.open("GET",b,!0);f.withCredentials=this.withCredentials; -f.send(null)}; +THREE.JSONLoader.prototype.loadAjaxJSON=function(a,b,c,d,e){var f=new XMLHttpRequest,g=0;f.onreadystatechange=function(){if(f.readyState===f.DONE)if(200===f.status||0===f.status){if(f.responseText){var h=JSON.parse(f.responseText),k=h.metadata;if(void 0!==k){if("object"===k.type){THREE.error("THREE.JSONLoader: "+b+" should be loaded with THREE.ObjectLoader instead.");return}if("scene"===k.type){THREE.error("THREE.JSONLoader: "+b+" seems to be a Scene. Use THREE.SceneLoader instead.");return}}h=a.parse(h, +d);c(h.geometry,h.materials)}else THREE.error("THREE.JSONLoader: "+b+" seems to be unreachable or the file is empty.");a.onLoadComplete()}else THREE.error("THREE.JSONLoader: Couldn't load "+b+" ("+f.status+")");else f.readyState===f.LOADING?e&&(0===g&&(g=f.getResponseHeader("Content-Length")),e({total:g,loaded:f.responseText.length})):f.readyState===f.HEADERS_RECEIVED&&void 0!==e&&(g=f.getResponseHeader("Content-Length"))};f.open("GET",b,!0);f.withCredentials=this.withCredentials;f.send(null)}; THREE.JSONLoader.prototype.parse=function(a,b){var c=new THREE.Geometry,d=void 0!==a.scale?1/a.scale:1;(function(b){var d,g,h,k,l,p,q,n,t,r,s,u,v,x=a.faces;p=a.vertices;var D=a.normals,w=a.colors,y=0;if(void 0!==a.uvs){for(d=0;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1],v=new THREE.Vector2(v,n),2!==g&&c.faceVertexUvs[d][h].push(v),0!==g&&c.faceVertexUvs[d][h+1].push(v);q&&(q=3*x[k++],t.normal.set(D[q++],D[q++],D[q]),s.normal.copy(t.normal));if(r)for(d=0;4>d;d++)q=3*x[k++],r=new THREE.Vector3(D[q++], D[q++],D[q]),2!==d&&t.vertexNormals.push(r),0!==d&&s.vertexNormals.push(r);p&&(p=x[k++],p=w[p],t.color.setHex(p),s.color.setHex(p));if(b)for(d=0;4>d;d++)p=x[k++],p=w[p],2!==d&&t.vertexColors.push(new THREE.Color(p)),0!==d&&s.vertexColors.push(new THREE.Color(p));c.faces.push(t);c.faces.push(s)}else{t=new THREE.Face3;t.a=x[k++];t.b=x[k++];t.c=x[k++];h&&(h=x[k++],t.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)n=x[k++],v=u[2*n],n=u[2*n+1], @@ -333,8 +332,8 @@ THREE.ShaderMaterial.prototype.clone=function(){var a=new THREE.ShaderMaterial;T this.morphTargets;a.morphNormals=this.morphNormals;return a};THREE.RawShaderMaterial=function(a){THREE.ShaderMaterial.call(this,a);this.type="RawShaderMaterial"};THREE.RawShaderMaterial.prototype=Object.create(THREE.ShaderMaterial.prototype);THREE.RawShaderMaterial.prototype.constructor=THREE.RawShaderMaterial;THREE.RawShaderMaterial.prototype.clone=function(){var a=new THREE.RawShaderMaterial;THREE.ShaderMaterial.prototype.clone.call(this,a);return a}; THREE.SpriteMaterial=function(a){THREE.Material.call(this);this.type="SpriteMaterial";this.color=new THREE.Color(16777215);this.map=null;this.rotation=0;this.fog=!1;this.setValues(a)};THREE.SpriteMaterial.prototype=Object.create(THREE.Material.prototype);THREE.SpriteMaterial.prototype.constructor=THREE.SpriteMaterial; THREE.SpriteMaterial.prototype.clone=function(){var a=new THREE.SpriteMaterial;THREE.Material.prototype.clone.call(this,a);a.color.copy(this.color);a.map=this.map;a.rotation=this.rotation;a.fog=this.fog;return a}; -THREE.Texture=function(a,b,c,d,e,f,g,h,k){Object.defineProperty(this,"id",{value:THREE.TextureIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.image=void 0!==a?a:THREE.Texture.DEFAULT_IMAGE;this.mipmaps=[];this.mapping=void 0!==b?b:THREE.Texture.DEFAULT_MAPPING;this.wrapS=void 0!==c?c:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==d?d:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==e?e:THREE.LinearFilter;this.minFilter=void 0!==f?f:THREE.LinearMipMapLinearFilter;this.anisotropy= -void 0!==k?k:1;this.format=void 0!==g?g:THREE.RGBAFormat;this.type=void 0!==h?h:THREE.UnsignedByteType;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.generateMipmaps=!0;this.premultiplyAlpha=!1;this.flipY=!0;this.unpackAlignment=4;this._needsUpdate=!1;this.onUpdate=null};THREE.Texture.DEFAULT_IMAGE=void 0;THREE.Texture.DEFAULT_MAPPING=THREE.UVMapping; +THREE.Texture=function(a,b,c,d,e,f,g,h,k){Object.defineProperty(this,"id",{value:THREE.TextureIdCount++});this.uuid=THREE.Math.generateUUID();this.sourceFile=this.name="";this.image=void 0!==a?a:THREE.Texture.DEFAULT_IMAGE;this.mipmaps=[];this.mapping=void 0!==b?b:THREE.Texture.DEFAULT_MAPPING;this.wrapS=void 0!==c?c:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==d?d:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==e?e:THREE.LinearFilter;this.minFilter=void 0!==f?f:THREE.LinearMipMapLinearFilter; +this.anisotropy=void 0!==k?k:1;this.format=void 0!==g?g:THREE.RGBAFormat;this.type=void 0!==h?h:THREE.UnsignedByteType;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.generateMipmaps=!0;this.premultiplyAlpha=!1;this.flipY=!0;this.unpackAlignment=4;this._needsUpdate=!1;this.onUpdate=null};THREE.Texture.DEFAULT_IMAGE=void 0;THREE.Texture.DEFAULT_MAPPING=THREE.UVMapping; THREE.Texture.prototype={constructor:THREE.Texture,get needsUpdate(){return this._needsUpdate},set needsUpdate(a){!0===a&&this.update();this._needsUpdate=a},clone:function(a){void 0===a&&(a=new THREE.Texture);a.image=this.image;a.mipmaps=this.mipmaps.slice(0);a.mapping=this.mapping;a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.format=this.format;a.type=this.type;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.generateMipmaps= this.generateMipmaps;a.premultiplyAlpha=this.premultiplyAlpha;a.flipY=this.flipY;a.unpackAlignment=this.unpackAlignment;return a},update:function(){this.dispatchEvent({type:"update"})},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Texture.prototype);THREE.TextureIdCount=0;THREE.CubeTexture=function(a,b,c,d,e,f,g,h,k){b=void 0!==b?b:THREE.CubeReflectionMapping;THREE.Texture.call(this,a,b,c,d,e,f,g,h,k);this.images=a}; THREE.CubeTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CubeTexture.prototype.constructor=THREE.CubeTexture;THREE.CubeTexture.clone=function(a){void 0===a&&(a=new THREE.CubeTexture);THREE.Texture.prototype.clone.call(this,a);a.images=this.images;return a};THREE.CompressedTexture=function(a,b,c,d,e,f,g,h,k,l,p){THREE.Texture.call(this,null,f,g,h,k,l,d,e,p);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1};THREE.CompressedTexture.prototype=Object.create(THREE.Texture.prototype); From 2f36e6a1dbc382c9e7f5bc7edab8cfc41df38fe0 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 15 Mar 2015 19:02:22 +0000 Subject: [PATCH 330/333] Editor: Script syntax error robustness. --- editor/js/Script.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/editor/js/Script.js b/editor/js/Script.js index abcb6d24924543..6a6421f3a2639c 100644 --- a/editor/js/Script.js +++ b/editor/js/Script.js @@ -89,14 +89,12 @@ var Script = function ( editor ) { } - for ( var i = 0; i < widgets.length; i ++ ) { + while ( widgets.length > 0 ) { - codemirror.removeLineWidget( widgets[ i ] ); + codemirror.removeLineWidget( widgets.shift() ); } - widgets.length = 0; - // try { From 498475b29295c68dac987874c01b96202cbd1b1c Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 15 Mar 2015 19:43:26 +0000 Subject: [PATCH 331/333] *Animation: Clean up. --- src/extras/animation/Animation.js | 443 +++++++++++----------- src/extras/animation/KeyFrameAnimation.js | 199 +++++----- src/extras/animation/MorphAnimation.js | 12 +- 3 files changed, 328 insertions(+), 326 deletions(-) diff --git a/src/extras/animation/Animation.js b/src/extras/animation/Animation.js index 55ab0786f5d919..07b8171a716475 100644 --- a/src/extras/animation/Animation.js +++ b/src/extras/animation/Animation.js @@ -21,383 +21,386 @@ THREE.Animation = function ( root, data ) { }; +THREE.Animation.prototype = { -THREE.Animation.prototype.keyTypes = [ "pos", "rot", "scl" ]; + constructor: THREE.Animation, + keyTypes: [ "pos", "rot", "scl" ], -THREE.Animation.prototype.play = function ( startTime, weight ) { + play: function ( startTime, weight ) { - this.currentTime = startTime !== undefined ? startTime : 0; - this.weight = weight !== undefined ? weight : 1; + this.currentTime = startTime !== undefined ? startTime : 0; + this.weight = weight !== undefined ? weight : 1; - this.isPlaying = true; + this.isPlaying = true; - this.reset(); + this.reset(); - THREE.AnimationHandler.play( this ); + THREE.AnimationHandler.play( this ); -}; + }, + stop: function() { -THREE.Animation.prototype.stop = function() { + this.isPlaying = false; - this.isPlaying = false; + THREE.AnimationHandler.stop( this ); - THREE.AnimationHandler.stop( this ); + }, -}; + reset: function () { -THREE.Animation.prototype.reset = function () { + for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { - for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { + var object = this.hierarchy[ h ]; - var object = this.hierarchy[ h ]; + if ( object.animationCache === undefined ) { - if ( object.animationCache === undefined ) { + object.animationCache = { + animations: {}, + blending: { + positionWeight: 0.0, + quaternionWeight: 0.0, + scaleWeight: 0.0 + } + }; + } - object.animationCache = { - animations: {}, - blending: { - positionWeight: 0.0, - quaternionWeight: 0.0, - scaleWeight: 0.0 - } - }; - } + var name = this.data.name; + var animations = object.animationCache.animations; + var animationCache = animations[ name ]; - if ( object.animationCache.animations[this.data.name] === undefined ) { + if ( animationCache === undefined ) { - object.animationCache.animations[this.data.name] = {}; - object.animationCache.animations[this.data.name].prevKey = { pos: 0, rot: 0, scl: 0 }; - object.animationCache.animations[this.data.name].nextKey = { pos: 0, rot: 0, scl: 0 }; - object.animationCache.animations[this.data.name].originalMatrix = object.matrix; + animationCache = { + prevKey: { pos: 0, rot: 0, scl: 0 }, + nextKey: { pos: 0, rot: 0, scl: 0 }, + originalMatrix: object.matrix + }; - } + animations[ name ] = animationCache; - var animationCache = object.animationCache.animations[this.data.name]; + } - // Get keys to match our current time + // Get keys to match our current time - for ( var t = 0; t < 3; t ++ ) { + for ( var t = 0; t < 3; t ++ ) { - var type = this.keyTypes[ t ]; + var type = this.keyTypes[ t ]; - var prevKey = this.data.hierarchy[ h ].keys[ 0 ]; - var nextKey = this.getNextKeyWith( type, h, 1 ); + var prevKey = this.data.hierarchy[ h ].keys[ 0 ]; + var nextKey = this.getNextKeyWith( type, h, 1 ); - while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { + while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { - prevKey = nextKey; - nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 ); + prevKey = nextKey; + nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 ); - } + } + + animationCache.prevKey[ type ] = prevKey; + animationCache.nextKey[ type ] = nextKey; - animationCache.prevKey[ type ] = prevKey; - animationCache.nextKey[ type ] = nextKey; + } } - } + }, -}; + resetBlendWeights: function () { + + for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { -THREE.Animation.prototype.resetBlendWeights = function () { + var object = this.hierarchy[ h ]; + var animationCache = object.animationCache; - for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { + if ( animationCache !== undefined ) { - var object = this.hierarchy[ h ]; + var blending = animationCache.blending; - if ( object.animationCache !== undefined ) { + blending.positionWeight = 0.0; + blending.quaternionWeight = 0.0; + blending.scaleWeight = 0.0; - object.animationCache.blending.positionWeight = 0.0; - object.animationCache.blending.quaternionWeight = 0.0; - object.animationCache.blending.scaleWeight = 0.0; + } } - } + }, -}; + update: ( function() { -THREE.Animation.prototype.update = (function() { + var points = []; + var target = new THREE.Vector3(); + var newVector = new THREE.Vector3(); + var newQuat = new THREE.Quaternion(); - var points = []; - var target = new THREE.Vector3(); - var newVector = new THREE.Vector3(); - var newQuat = new THREE.Quaternion(); + // Catmull-Rom spline - // Catmull-Rom spline + var interpolateCatmullRom = function ( points, scale ) { - var interpolateCatmullRom = function ( points, scale ) { + var c = [], v3 = [], + point, intPoint, weight, w2, w3, + pa, pb, pc, pd; - var c = [], v3 = [], - point, intPoint, weight, w2, w3, - pa, pb, pc, pd; + point = ( points.length - 1 ) * scale; + intPoint = Math.floor( point ); + weight = point - intPoint; - point = ( points.length - 1 ) * scale; - intPoint = Math.floor( point ); - weight = point - intPoint; + c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1; + c[ 1 ] = intPoint; + c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1; + c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2; - c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1; - c[ 1 ] = intPoint; - c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1; - c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2; + pa = points[ c[ 0 ] ]; + pb = points[ c[ 1 ] ]; + pc = points[ c[ 2 ] ]; + pd = points[ c[ 3 ] ]; - pa = points[ c[ 0 ] ]; - pb = points[ c[ 1 ] ]; - pc = points[ c[ 2 ] ]; - pd = points[ c[ 3 ] ]; + w2 = weight * weight; + w3 = weight * w2; - w2 = weight * weight; - w3 = weight * w2; + v3[ 0 ] = interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 ); + v3[ 1 ] = interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 ); + v3[ 2 ] = interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 ); - v3[ 0 ] = interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 ); - v3[ 1 ] = interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 ); - v3[ 2 ] = interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 ); + return v3; - return v3; + }; - }; + var interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) { - var interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) { + var v0 = ( p2 - p0 ) * 0.5, + v1 = ( p3 - p1 ) * 0.5; - var v0 = ( p2 - p0 ) * 0.5, - v1 = ( p3 - p1 ) * 0.5; + return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1; - return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1; + }; - }; + return function ( delta ) { - return function ( delta ) { + if ( this.isPlaying === false ) return; - if ( this.isPlaying === false ) return; + this.currentTime += delta * this.timeScale; - this.currentTime += delta * this.timeScale; + if ( this.weight === 0 ) + return; - if ( this.weight === 0 ) - return; + // - // + var duration = this.data.length; - var duration = this.data.length; + if ( this.currentTime > duration || this.currentTime < 0 ) { - if ( this.currentTime > duration || this.currentTime < 0 ) { + if ( this.loop ) { - if ( this.loop ) { + this.currentTime %= duration; - this.currentTime %= duration; + if ( this.currentTime < 0 ) + this.currentTime += duration; - if ( this.currentTime < 0 ) - this.currentTime += duration; + this.reset(); - this.reset(); + } else { - } else { + this.stop(); - this.stop(); + } } - } + for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { - for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { + var object = this.hierarchy[ h ]; + var animationCache = object.animationCache.animations[this.data.name]; + var blending = object.animationCache.blending; - var object = this.hierarchy[ h ]; - var animationCache = object.animationCache.animations[this.data.name]; - var blending = object.animationCache.blending; + // loop through pos/rot/scl - // loop through pos/rot/scl + for ( var t = 0; t < 3; t ++ ) { - for ( var t = 0; t < 3; t ++ ) { + // get keys - // get keys + var type = this.keyTypes[ t ]; + var prevKey = animationCache.prevKey[ type ]; + var nextKey = animationCache.nextKey[ type ]; - var type = this.keyTypes[ t ]; - var prevKey = animationCache.prevKey[ type ]; - var nextKey = animationCache.nextKey[ type ]; + if ( ( this.timeScale > 0 && nextKey.time <= this.currentTime ) || + ( this.timeScale < 0 && prevKey.time >= this.currentTime ) ) { - if ( ( this.timeScale > 0 && nextKey.time <= this.currentTime ) || - ( this.timeScale < 0 && prevKey.time >= this.currentTime ) ) { + prevKey = this.data.hierarchy[ h ].keys[ 0 ]; + nextKey = this.getNextKeyWith( type, h, 1 ); - prevKey = this.data.hierarchy[ h ].keys[ 0 ]; - nextKey = this.getNextKeyWith( type, h, 1 ); + while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { - while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { + prevKey = nextKey; + nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 ); - prevKey = nextKey; - nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 ); + } + + animationCache.prevKey[ type ] = prevKey; + animationCache.nextKey[ type ] = nextKey; } - animationCache.prevKey[ type ] = prevKey; - animationCache.nextKey[ type ] = nextKey; + var scale = ( this.currentTime - prevKey.time ) / ( nextKey.time - prevKey.time ); - } + var prevXYZ = prevKey[ type ]; + var nextXYZ = nextKey[ type ]; - var scale = ( this.currentTime - prevKey.time ) / ( nextKey.time - prevKey.time ); + if ( scale < 0 ) scale = 0; + if ( scale > 1 ) scale = 1; - var prevXYZ = prevKey[ type ]; - var nextXYZ = nextKey[ type ]; + // interpolate - if ( scale < 0 ) scale = 0; - if ( scale > 1 ) scale = 1; + if ( type === "pos" ) { - // interpolate + if ( this.interpolationType === THREE.AnimationHandler.LINEAR ) { - if ( type === "pos" ) { + newVector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale; + newVector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale; + newVector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale; - if ( this.interpolationType === THREE.AnimationHandler.LINEAR ) { + // blend + var proportionalWeight = this.weight / ( this.weight + blending.positionWeight ); + object.position.lerp( newVector, proportionalWeight ); + blending.positionWeight += this.weight; - newVector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale; - newVector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale; - newVector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale; + } else if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || + this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { - // blend - var proportionalWeight = this.weight / ( this.weight + blending.positionWeight ); - object.position.lerp( newVector, proportionalWeight ); - blending.positionWeight += this.weight; + points[ 0 ] = this.getPrevKeyWith( "pos", h, prevKey.index - 1 )[ "pos" ]; + points[ 1 ] = prevXYZ; + points[ 2 ] = nextXYZ; + points[ 3 ] = this.getNextKeyWith( "pos", h, nextKey.index + 1 )[ "pos" ]; - } else if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || - this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { + scale = scale * 0.33 + 0.33; - points[ 0 ] = this.getPrevKeyWith( "pos", h, prevKey.index - 1 )[ "pos" ]; - points[ 1 ] = prevXYZ; - points[ 2 ] = nextXYZ; - points[ 3 ] = this.getNextKeyWith( "pos", h, nextKey.index + 1 )[ "pos" ]; + var currentPoint = interpolateCatmullRom( points, scale ); + var proportionalWeight = this.weight / ( this.weight + blending.positionWeight ); + blending.positionWeight += this.weight; - scale = scale * 0.33 + 0.33; + // blend - var currentPoint = interpolateCatmullRom( points, scale ); - var proportionalWeight = this.weight / ( this.weight + blending.positionWeight ); - blending.positionWeight += this.weight; + var vector = object.position; - // blend + vector.x = vector.x + ( currentPoint[ 0 ] - vector.x ) * proportionalWeight; + vector.y = vector.y + ( currentPoint[ 1 ] - vector.y ) * proportionalWeight; + vector.z = vector.z + ( currentPoint[ 2 ] - vector.z ) * proportionalWeight; - var vector = object.position; - - vector.x = vector.x + ( currentPoint[ 0 ] - vector.x ) * proportionalWeight; - vector.y = vector.y + ( currentPoint[ 1 ] - vector.y ) * proportionalWeight; - vector.z = vector.z + ( currentPoint[ 2 ] - vector.z ) * proportionalWeight; + if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { - if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { + var forwardPoint = interpolateCatmullRom( points, scale * 1.01 ); - var forwardPoint = interpolateCatmullRom( points, scale * 1.01 ); + target.set( forwardPoint[ 0 ], forwardPoint[ 1 ], forwardPoint[ 2 ] ); + target.sub( vector ); + target.y = 0; + target.normalize(); - target.set( forwardPoint[ 0 ], forwardPoint[ 1 ], forwardPoint[ 2 ] ); - target.sub( vector ); - target.y = 0; - target.normalize(); + var angle = Math.atan2( target.x, target.z ); + object.rotation.set( 0, angle, 0 ); - var angle = Math.atan2( target.x, target.z ); - object.rotation.set( 0, angle, 0 ); + } } - } + } else if ( type === "rot" ) { - } else if ( type === "rot" ) { + THREE.Quaternion.slerp( prevXYZ, nextXYZ, newQuat, scale ); - THREE.Quaternion.slerp( prevXYZ, nextXYZ, newQuat, scale ); + // Avoid paying the cost of an additional slerp if we don't have to + if ( blending.quaternionWeight === 0 ) { - // Avoid paying the cost of an additional slerp if we don't have to - if ( blending.quaternionWeight === 0 ) { + object.quaternion.copy(newQuat); + blending.quaternionWeight = this.weight; - object.quaternion.copy(newQuat); - blending.quaternionWeight = this.weight; + } else { - } else { + var proportionalWeight = this.weight / ( this.weight + blending.quaternionWeight ); + THREE.Quaternion.slerp( object.quaternion, newQuat, object.quaternion, proportionalWeight ); + blending.quaternionWeight += this.weight; - var proportionalWeight = this.weight / ( this.weight + blending.quaternionWeight ); - THREE.Quaternion.slerp( object.quaternion, newQuat, object.quaternion, proportionalWeight ); - blending.quaternionWeight += this.weight; + } - } + } else if ( type === "scl" ) { - } else if ( type === "scl" ) { + newVector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale; + newVector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale; + newVector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale; - newVector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale; - newVector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale; - newVector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale; + var proportionalWeight = this.weight / ( this.weight + blending.scaleWeight ); + object.scale.lerp( newVector, proportionalWeight ); + blending.scaleWeight += this.weight; - var proportionalWeight = this.weight / ( this.weight + blending.scaleWeight ); - object.scale.lerp( newVector, proportionalWeight ); - blending.scaleWeight += this.weight; + } } } - } - - return true; - - }; + return true; -})(); + }; + } )(), + getNextKeyWith: function ( type, h, key ) { + var keys = this.data.hierarchy[ h ].keys; + if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || + this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { -// Get next key with + key = key < keys.length - 1 ? key : keys.length - 1; -THREE.Animation.prototype.getNextKeyWith = function ( type, h, key ) { + } else { - var keys = this.data.hierarchy[ h ].keys; + key = key % keys.length; - if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || - this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { - - key = key < keys.length - 1 ? key : keys.length - 1; - - } else { + } - key = key % keys.length; + for ( ; key < keys.length; key ++ ) { - } + if ( keys[ key ][ type ] !== undefined ) { - for ( ; key < keys.length; key ++ ) { + return keys[ key ]; - if ( keys[ key ][ type ] !== undefined ) { - - return keys[ key ]; + } } - } - - return this.data.hierarchy[ h ].keys[ 0 ]; + return this.data.hierarchy[ h ].keys[ 0 ]; -}; + }, -// Get previous key with + getPrevKeyWith: function ( type, h, key ) { -THREE.Animation.prototype.getPrevKeyWith = function ( type, h, key ) { + var keys = this.data.hierarchy[ h ].keys; - var keys = this.data.hierarchy[ h ].keys; + if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || + this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { - if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || - this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { + key = key > 0 ? key : 0; - key = key > 0 ? key : 0; + } else { - } else { + key = key >= 0 ? key : key + keys.length; - key = key >= 0 ? key : key + keys.length; + } - } + for ( ; key >= 0; key -- ) { - for ( ; key >= 0; key -- ) { + if ( keys[ key ][ type ] !== undefined ) { - if ( keys[ key ][ type ] !== undefined ) { + return keys[ key ]; - return keys[ key ]; + } } - } + return this.data.hierarchy[ h ].keys[ keys.length - 1 ]; - return this.data.hierarchy[ h ].keys[ keys.length - 1 ]; + } }; diff --git a/src/extras/animation/KeyFrameAnimation.js b/src/extras/animation/KeyFrameAnimation.js index 3975e7825bc3b3..609c5f21534bde 100644 --- a/src/extras/animation/KeyFrameAnimation.js +++ b/src/extras/animation/KeyFrameAnimation.js @@ -50,195 +50,192 @@ THREE.KeyFrameAnimation = function ( data ) { }; +THREE.KeyFrameAnimation.prototype = { -THREE.KeyFrameAnimation.prototype.play = function ( startTime ) { + constructor: THREE.KeyFrameAnimation, - this.currentTime = startTime !== undefined ? startTime : 0; + play: function ( startTime ) { - if ( this.isPlaying === false ) { + this.currentTime = startTime !== undefined ? startTime : 0; - this.isPlaying = true; + if ( this.isPlaying === false ) { - // reset key cache + this.isPlaying = true; - var h, hl = this.hierarchy.length, - object, - node; + // reset key cache - for ( h = 0; h < hl; h ++ ) { + var h, hl = this.hierarchy.length, + object, + node; - object = this.hierarchy[ h ]; - node = this.data.hierarchy[ h ]; + for ( h = 0; h < hl; h ++ ) { - if ( node.animationCache === undefined ) { + object = this.hierarchy[ h ]; + node = this.data.hierarchy[ h ]; - node.animationCache = {}; - node.animationCache.prevKey = null; - node.animationCache.nextKey = null; - node.animationCache.originalMatrix = object.matrix; + if ( node.animationCache === undefined ) { - } + node.animationCache = {}; + node.animationCache.prevKey = null; + node.animationCache.nextKey = null; + node.animationCache.originalMatrix = object.matrix; + + } + + var keys = this.data.hierarchy[h].keys; - var keys = this.data.hierarchy[h].keys; + if (keys.length) { - if (keys.length) { + node.animationCache.prevKey = keys[ 0 ]; + node.animationCache.nextKey = keys[ 1 ]; - node.animationCache.prevKey = keys[ 0 ]; - node.animationCache.nextKey = keys[ 1 ]; + this.startTime = Math.min( keys[0].time, this.startTime ); + this.endTime = Math.max( keys[keys.length - 1].time, this.endTime ); - this.startTime = Math.min( keys[0].time, this.startTime ); - this.endTime = Math.max( keys[keys.length - 1].time, this.endTime ); + } } + this.update( 0 ); + } - this.update( 0 ); + this.isPaused = false; - } + THREE.AnimationHandler.play( this ); - this.isPaused = false; + }, - THREE.AnimationHandler.play( this ); + stop: function () { -}; + this.isPlaying = false; + this.isPaused = false; + THREE.AnimationHandler.stop( this ); -THREE.KeyFrameAnimation.prototype.stop = function() { + // reset JIT matrix and remove cache - this.isPlaying = false; - this.isPaused = false; - - THREE.AnimationHandler.stop( this ); + for ( var h = 0; h < this.data.hierarchy.length; h ++ ) { - // reset JIT matrix and remove cache + var obj = this.hierarchy[ h ]; + var node = this.data.hierarchy[ h ]; - for ( var h = 0; h < this.data.hierarchy.length; h ++ ) { - - var obj = this.hierarchy[ h ]; - var node = this.data.hierarchy[ h ]; + if ( node.animationCache !== undefined ) { - if ( node.animationCache !== undefined ) { + var original = node.animationCache.originalMatrix; - var original = node.animationCache.originalMatrix; + original.copy( obj.matrix ); + obj.matrix = original; - original.copy( obj.matrix ); - obj.matrix = original; + delete node.animationCache; - delete node.animationCache; + } } - } - -}; + }, + update: function ( delta ) { -// Update + if ( this.isPlaying === false ) return; -THREE.KeyFrameAnimation.prototype.update = function ( delta ) { + this.currentTime += delta * this.timeScale; - if ( this.isPlaying === false ) return; + // - this.currentTime += delta * this.timeScale; + var duration = this.data.length; - // + if ( this.loop === true && this.currentTime > duration ) { - var duration = this.data.length; + this.currentTime %= duration; - if ( this.loop === true && this.currentTime > duration ) { + } - this.currentTime %= duration; + this.currentTime = Math.min( this.currentTime, duration ); - } + for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { - this.currentTime = Math.min( this.currentTime, duration ); + var object = this.hierarchy[ h ]; + var node = this.data.hierarchy[ h ]; - for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { + var keys = node.keys, + animationCache = node.animationCache; - var object = this.hierarchy[ h ]; - var node = this.data.hierarchy[ h ]; - var keys = node.keys, - animationCache = node.animationCache; + if ( keys.length ) { + var prevKey = animationCache.prevKey; + var nextKey = animationCache.nextKey; - if ( keys.length ) { + if ( nextKey.time <= this.currentTime ) { - var prevKey = animationCache.prevKey; - var nextKey = animationCache.nextKey; + while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { - if ( nextKey.time <= this.currentTime ) { + prevKey = nextKey; + nextKey = keys[ prevKey.index + 1 ]; - while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { + } - prevKey = nextKey; - nextKey = keys[ prevKey.index + 1 ]; + animationCache.prevKey = prevKey; + animationCache.nextKey = nextKey; } - animationCache.prevKey = prevKey; - animationCache.nextKey = nextKey; + if ( nextKey.time >= this.currentTime ) { - } + prevKey.interpolate( nextKey, this.currentTime ); - if ( nextKey.time >= this.currentTime ) { + } else { - prevKey.interpolate( nextKey, this.currentTime ); + prevKey.interpolate( nextKey, nextKey.time ); - } else { + } - prevKey.interpolate( nextKey, nextKey.time ); + this.data.hierarchy[ h ].node.updateMatrix(); + object.matrixWorldNeedsUpdate = true; } - this.data.hierarchy[ h ].node.updateMatrix(); - object.matrixWorldNeedsUpdate = true; - } - } - -}; + }, -// Get next key with + getNextKeyWith: function ( sid, h, key ) { -THREE.KeyFrameAnimation.prototype.getNextKeyWith = function( sid, h, key ) { + var keys = this.data.hierarchy[ h ].keys; + key = key % keys.length; - var keys = this.data.hierarchy[ h ].keys; - key = key % keys.length; + for ( ; key < keys.length; key ++ ) { - for ( ; key < keys.length; key ++ ) { + if ( keys[ key ].hasTarget( sid ) ) { - if ( keys[ key ].hasTarget( sid ) ) { + return keys[ key ]; - return keys[ key ]; + } } - } - - return keys[ 0 ]; + return keys[ 0 ]; -}; + }, -// Get previous key with + getPrevKeyWith: function ( sid, h, key ) { -THREE.KeyFrameAnimation.prototype.getPrevKeyWith = function( sid, h, key ) { + var keys = this.data.hierarchy[ h ].keys; + key = key >= 0 ? key : key + keys.length; - var keys = this.data.hierarchy[ h ].keys; - key = key >= 0 ? key : key + keys.length; + for ( ; key >= 0; key -- ) { - for ( ; key >= 0; key -- ) { + if ( keys[ key ].hasTarget( sid ) ) { - if ( keys[ key ].hasTarget( sid ) ) { + return keys[ key ]; - return keys[ key ]; + } } - } + return keys[ keys.length - 1 ]; - return keys[ keys.length - 1 ]; + } }; diff --git a/src/extras/animation/MorphAnimation.js b/src/extras/animation/MorphAnimation.js index 858eb135ae1ed0..c02243126f9bb2 100644 --- a/src/extras/animation/MorphAnimation.js +++ b/src/extras/animation/MorphAnimation.js @@ -50,19 +50,21 @@ THREE.MorphAnimation.prototype = { var interpolation = this.duration / this.frames; var frame = Math.floor( this.currentTime / interpolation ); + var influences = this.mesh.morphTargetInfluences; + if ( frame != this.currentFrame ) { - this.mesh.morphTargetInfluences[ this.lastFrame ] = 0; - this.mesh.morphTargetInfluences[ this.currentFrame ] = 1; - this.mesh.morphTargetInfluences[ frame ] = 0; + influences[ this.lastFrame ] = 0; + influences[ this.currentFrame ] = 1; + influences[ frame ] = 0; this.lastFrame = this.currentFrame; this.currentFrame = frame; } - this.mesh.morphTargetInfluences[ frame ] = ( this.currentTime % interpolation ) / interpolation; - this.mesh.morphTargetInfluences[ this.lastFrame ] = 1 - this.mesh.morphTargetInfluences[ frame ]; + influences[ frame ] = ( this.currentTime % interpolation ) / interpolation; + influences[ this.lastFrame ] = 1 - influences[ frame ]; } From b61ead7858777e4088800fb74f7f592cfc3c388a Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 15 Mar 2015 19:43:35 +0000 Subject: [PATCH 332/333] Simplified example. --- examples/webgl_loader_scene.html | 42 ++++++++------------------------ 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/examples/webgl_loader_scene.html b/examples/webgl_loader_scene.html index eb726d28b2045d..68010dbf32d39a 100644 --- a/examples/webgl_loader_scene.html +++ b/examples/webgl_loader_scene.html @@ -39,15 +39,6 @@ display:none; } - #start { - color:#fff; - text-shadow: #000 0px 0px 2px; - padding:0.1em 0.3em; - width:3em; - text-align: center; - display:none; - } - .shadow { -moz-box-shadow: 0px 0px 5px #000; -webkit-box-shadow: 0px 0px 5px #000; @@ -97,7 +88,6 @@

    -
    Start

    @@ -186,8 +176,6 @@ stats.domElement.style.zIndex = 100; container.appendChild( stats.domElement ); - $( "start" ).addEventListener( 'click', onStartClick, false ); - var callbackProgress = function( progress, result ) { var bar = 250, @@ -207,8 +195,6 @@ $( "message" ).style.display = "none"; $( "progressbar" ).style.display = "none"; - $( "start" ).style.display = "block"; - $( "start" ).className = "enabled"; result.scene.traverse( function ( object ) { @@ -237,6 +223,16 @@ } ); + // + + $( "progress" ).style.display = "none"; + + camera = loaded.currentCamera; + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + scene = loaded.scene; + } $( "progress" ).style.display = "block"; @@ -276,24 +272,6 @@ } - function setButtonActive( id ) { - - $( "start" ).style.backgroundColor = "green"; - - } - - function onStartClick() { - - $( "progress" ).style.display = "none"; - - camera = loaded.currentCamera; - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - scene = loaded.scene; - - } - function onDocumentMouseMove( event ) { mouseX = ( event.clientX - windowHalfX ); From 1aabcb379c7fc9db53e644be038235f45ff4d057 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 15 Mar 2015 21:02:26 +0000 Subject: [PATCH 333/333] Examples clean up. --- examples/index.html | 1 + examples/js/SkyShader.js | 39 ++++++++----------- examples/js/math/Lut.js | 4 +- .../postprocessing/AdaptiveToneMappingPass.js | 16 ++++---- examples/misc_fps.html | 11 +++--- examples/webgl_interactive_cubes_gpu.html | 1 + examples/webgl_shaders_sky.html | 37 +++++++----------- examples/webgl_terrain_dynamic.html | 2 +- 8 files changed, 48 insertions(+), 63 deletions(-) diff --git a/examples/index.html b/examples/index.html index d9bfdcf6badabb..96acb3951a45c4 100644 --- a/examples/index.html +++ b/examples/index.html @@ -358,6 +358,7 @@

    three.js / examples

    "webgl_shadowmap", "webgl_shadowmap_performance", "webgl_shadowmap_viewer", + "webgl_shadowmesh", "webgl_sprites", "webgl_terrain_dynamic", "webgl_test_memory", diff --git a/examples/js/SkyShader.js b/examples/js/SkyShader.js index 5d009e36c7a192..df76f0fb8095f5 100644 --- a/examples/js/SkyShader.js +++ b/examples/js/SkyShader.js @@ -1,16 +1,16 @@ /** * @author zz85 / https://github.com/zz85 - * - * Based on "A Practical Analytic Model for Daylight" + * + * Based on "A Practical Analytic Model for Daylight" * aka The Preetham Model, the de facto standard analytic skydome model * http://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf - * + * * First implemented by Simon Wallner * http://www.simonwallner.at/projects/atmospheric-scattering - * + * * Improved by Martin Upitis * http://blenderartists.org/forum/showthread.php?245954-preethams-sky-impementation-HDR - * + * * Three.js integration by zz85 http://twitter.com/blurspline */ @@ -30,13 +30,11 @@ THREE.ShaderLib['sky'] = { vertexShader: [ "varying vec3 vWorldPosition;", - "varying vec2 vUv;", "void main() {", "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", "vWorldPosition = worldPosition.xyz;", - "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", @@ -46,12 +44,9 @@ THREE.ShaderLib['sky'] = { fragmentShader: [ - "uniform sampler2D skySampler;", "uniform vec3 sunPosition;", "varying vec3 vWorldPosition;", - "varying vec2 vUv;", - "vec3 cameraPos = vec3(0., 0., 0.);", "// uniform sampler2D sDiffuse;", @@ -67,7 +62,6 @@ THREE.ShaderLib['sky'] = { "uniform float mieCoefficient;", "uniform float mieDirectionalG;", - "vec3 sunDirection = normalize(sunPosition);", "float reileighCoefficient = reileigh;", @@ -165,9 +159,9 @@ THREE.ShaderLib['sky'] = { "// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;", "// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);", - + "reileighCoefficient = reileighCoefficient - (1.0* (1.0-sunfade));", - + "float sunE = sunIntensity(dot(sunDirection, up));", "// extinction (absorbtion + out scattering) ", @@ -210,7 +204,7 @@ THREE.ShaderLib['sky'] = { "vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);", "// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;", "vec3 L0 = vec3(0.1) * Fex;", - + "// composition + solar disc", "//if (cosTheta > sunAngularDiameterCos)", "float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);", @@ -219,25 +213,25 @@ THREE.ShaderLib['sky'] = { "vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));", - + "vec3 texColor = (Lin+L0); ", "texColor *= 0.04 ;", "texColor += vec3(0.0,0.001,0.0025)*0.3;", - + "float g_fMaxLuminance = 1.0;", "float fLumScaled = 0.1 / luminance; ", "float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ", "float ExposureBias = fLumCompressed;", - + "vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);", "vec3 color = curr*whiteScale;", "vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));", - + "gl_FragColor.rgb = retColor;", - + "gl_FragColor.a = 1.0;", "}", @@ -250,9 +244,9 @@ THREE.Sky = function () { var skyShader = THREE.ShaderLib[ "sky" ]; var skyUniforms = THREE.UniformsUtils.clone( skyShader.uniforms ); - var skyMat = new THREE.ShaderMaterial( { - fragmentShader: skyShader.fragmentShader, - vertexShader: skyShader.vertexShader, + var skyMat = new THREE.ShaderMaterial( { + fragmentShader: skyShader.fragmentShader, + vertexShader: skyShader.vertexShader, uniforms: skyUniforms, side: THREE.BackSide } ); @@ -265,5 +259,4 @@ THREE.Sky = function () { this.mesh = skyMesh; this.uniforms = skyUniforms; - }; diff --git a/examples/js/math/Lut.js b/examples/js/math/Lut.js index f488f9a93c166a..9b50eb6a8a0f22 100644 --- a/examples/js/math/Lut.js +++ b/examples/js/math/Lut.js @@ -300,7 +300,7 @@ THREE.Lut.prototype = { contextTitle.fillText( this.legend.labels.title.toString() + this.legend.labels.um.toString(), borderThickness, this.legend.labels.fontsize + borderThickness ); var txtTitle = new THREE.Texture( canvasTitle ); - + txtTitle.minFilter = THREE.LinearFilter; txtTitle.needsUpdate = true; var spriteMaterialTitle = new THREE.SpriteMaterial( { map: txtTitle, useScreenCoordinates: false } ); @@ -385,7 +385,7 @@ THREE.Lut.prototype = { contextTick.fillText( value.toString(), borderThickness, this.legend.labels.fontsize + borderThickness ); var txtTick = new THREE.Texture( canvasTick ); - + txtTick.minFilter = THREE.LinearFilter; txtTick.needsUpdate = true; var spriteMaterialTick = new THREE.SpriteMaterial( { map: txtTick, useScreenCoordinates: false } ); diff --git a/examples/js/postprocessing/AdaptiveToneMappingPass.js b/examples/js/postprocessing/AdaptiveToneMappingPass.js index 63c374f0456c9a..248588ba58fe38 100644 --- a/examples/js/postprocessing/AdaptiveToneMappingPass.js +++ b/examples/js/postprocessing/AdaptiveToneMappingPass.js @@ -16,7 +16,7 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) { this.luminanceRT = null; this.previousLuminanceRT = null; this.currentLuminanceRT = null; - + if ( THREE.CopyShader === undefined ) console.error( "THREE.AdaptiveToneMappingPass relies on THREE.CopyShader" ); @@ -72,15 +72,15 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) { "uniform sampler2D currentLum;", "uniform float delta;", "uniform float tau;", - + "void main() {", "vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );", "vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );", - + "float fLastLum = lastLum.r;", "float fCurrentLum = currentLum.r;", - + //The adaption seems to work better in extreme lighting differences //if the input luminance is squared. "fCurrentLum *= fCurrentLum;", @@ -120,7 +120,7 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) { this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); this.scene = new THREE.Scene(); - this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); + this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null ); this.scene.add( this.quad ); }; @@ -160,7 +160,7 @@ THREE.AdaptiveToneMappingPass.prototype = { this.quad.material = this.materialToneMap; this.materialToneMap.uniforms.tDiffuse.value = readBuffer; renderer.render( this.scene, this.camera, writeBuffer, this.clear ); - + }, reset: function( renderer ) { @@ -184,7 +184,7 @@ THREE.AdaptiveToneMappingPass.prototype = { //We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader pars.minFilter = THREE.LinearMipMapLinearFilter; this.currentLuminanceRT = new THREE.WebGLRenderTarget( this.resolution, this.resolution, pars ); - + if ( this.adaptive ) { this.materialToneMap.defines["ADAPTED_LUMINANCE"] = ""; this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT; @@ -261,4 +261,4 @@ THREE.AdaptiveToneMappingPass.prototype = { } } -}; \ No newline at end of file +}; diff --git a/examples/misc_fps.html b/examples/misc_fps.html index 1135dffa4bf0a9..c11cf4006066b0 100644 --- a/examples/misc_fps.html +++ b/examples/misc_fps.html @@ -163,7 +163,7 @@ var actualHeight = hits[0].distance - birdsEye; // collision: stick to the surface if landing on it - + if( ( motion.velocity.y <= 0 ) && ( Math.abs( actualHeight ) < kneeDeep ) ) { motion.position.y -= actualHeight; motion.velocity.y = 0; @@ -185,9 +185,9 @@ // limit the tilt at ±0.4 radians motion.rotation.x = Math.max( -0.4, Math.min ( +0.4, motion.rotation.x ) ); - + // wrap horizontal rotation to 0...2π - + motion.rotation.y += tau; motion.rotation.y %= tau; timeLeft -= dt; @@ -233,6 +233,7 @@ var placeholder = new THREE.Object3D(); var texture = THREE.ImageUtils.loadTexture( textureUrl ); + texture.minFilter = THREE.LinearFilter; texture.anisotropy = textureQuality; var loader = new THREE.JSONLoader(); @@ -256,7 +257,7 @@ var camera = new THREE.PerspectiveCamera( 60, 1, 0.1, 9000 ); var scene = new THREE.Scene(); - + scene.add( camera ); scene.add( makeSkybox( [ @@ -294,7 +295,7 @@ // call our game loop with the time elapsed since last rendering, in ms gameLoop( timeElapsed ); - + renderer.render( scene, camera ); requestAnimationFrame( render ); }; diff --git a/examples/webgl_interactive_cubes_gpu.html b/examples/webgl_interactive_cubes_gpu.html index aafe7f1e6b9477..67c2bcc65d0a13 100644 --- a/examples/webgl_interactive_cubes_gpu.html +++ b/examples/webgl_interactive_cubes_gpu.html @@ -75,6 +75,7 @@ pickingScene = new THREE.Scene(); pickingTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight ); + pickingTexture.minFilter = THREE.LinearFilter; pickingTexture.generateMipmaps = false; scene.add( new THREE.AmbientLight( 0x555555 ) ); diff --git a/examples/webgl_shaders_sky.html b/examples/webgl_shaders_sky.html index 8c3014adcb4bfd..3b7a6ec9234c81 100644 --- a/examples/webgl_shaders_sky.html +++ b/examples/webgl_shaders_sky.html @@ -20,8 +20,8 @@ } #info { - color:#333; - text-shadow: 1px 1px #fff; + color:#ccc; + text-shadow: 1px 1px rgba(0,0,0,0.25); position: absolute; top: 0px; width: 100%; padding: 5px; @@ -29,7 +29,7 @@ } a { - color: #333; + color: #fff; } @@ -90,7 +90,7 @@ mieDirectionalG: 0.8, luminance: 1, inclination: 0.49, // elevation / inclination - azimuth: 0.25, // Facing front, + azimuth: 0.25, // Facing front, sun: !true } @@ -108,8 +108,8 @@ var phi = 2 * Math.PI * (effectController.azimuth - 0.5); sunSphere.position.x = distance * Math.cos(phi); - sunSphere.position.y = distance * Math.sin(phi) * Math.sin(theta); - sunSphere.position.z = distance * Math.sin(phi) * Math.cos(theta); + sunSphere.position.y = distance * Math.sin(phi) * Math.sin(theta); + sunSphere.position.z = distance * Math.sin(phi) * Math.cos(theta); sunSphere.visible = effectController.sun; @@ -129,14 +129,14 @@ gui.add( effectController, "inclination", 0, 1, 0.0001).onChange( guiChanged ); gui.add( effectController, "azimuth", 0, 1, 0.0001).onChange( guiChanged ); gui.add( effectController, "sun").onChange( guiChanged ); - + guiChanged(); camera.lookAt(sunSphere.position) - + } @@ -150,21 +150,10 @@ scene = new THREE.Scene(); - var size = 500; - - var geometryLines = new THREE.BoxGeometry( size, size, size ); - - var geometryPlane = new THREE.PlaneGeometry( size * 10, size * 10, 1, 1); - geometryPlane.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) ); - - - var materialLines = new THREE.MeshBasicMaterial( { wireframe: true } ); - - meshLines = new THREE.Mesh( geometryLines, materialLines ); - - // scene.add( meshLines ); - - scene.add( new THREE.Mesh( geometryPlane, materialLines ) ); + var helper = new THREE.GridHelper( 5000, 5000 ); + helper.color1.setHex( 0xffffff ); + helper.color2.setHex( 0xffffff ); + scene.add( helper ); initSky(); @@ -206,7 +195,7 @@ time = Date.now(); requestAnimationFrame( animate ); - + controls.update(); render(); diff --git a/examples/webgl_terrain_dynamic.html b/examples/webgl_terrain_dynamic.html index 1a143c6a512395..5b3fe0dabd4218 100644 --- a/examples/webgl_terrain_dynamic.html +++ b/examples/webgl_terrain_dynamic.html @@ -606,7 +606,7 @@ var sceneTmp = new THREE.Scene(); - var meshTmp = new THREE.Mesh( new THREE.PlaneGeometry( SCREEN_WIDTH, SCREEN_HEIGHT ), shaderMaterial ); + var meshTmp = new THREE.Mesh( new THREE.PlaneBufferGeometry( SCREEN_WIDTH, SCREEN_HEIGHT ), shaderMaterial ); meshTmp.position.z = -500; sceneTmp.add( meshTmp );