Browse Source

Merge branch 'dev' into temp

Ben Houston 10 năm trước cách đây
mục cha
commit
6179248c31
85 tập tin đã thay đổi với 2843 bổ sung8086 xóa
  1. 211 483
      build/three.js
  2. 297 305
      build/three.min.js
  3. 7 24
      docs/api/core/BufferGeometry.html
  4. 2 7
      docs/api/core/Face3.html
  5. 15 32
      docs/api/core/Geometry.html
  6. 0 59
      docs/api/extras/helpers/VertexTangentsHelper.html
  7. 0 93
      docs/api/lights/AreaLight.html
  8. 0 8
      docs/api/loaders/Loader.html
  9. 0 2
      docs/list.js
  10. 11 0
      editor/js/Sidebar.Geometry.BufferGeometry.js
  11. 0 20
      editor/js/Sidebar.Geometry.Modifiers.js
  12. 13 0
      editor/js/Sidebar.Geometry.js
  13. 1 89
      editor/js/libs/tern-threejs/threejs.js
  14. 1 6
      examples/index.html
  15. 187 0
      examples/js/BufferGeometryUtils.js
  16. 0 1104
      examples/js/ShaderDeferred.js
  17. 28 15
      examples/js/WaterShader.js
  18. 22 23
      examples/js/geometries/DecalGeometry.js
  19. 0 2
      examples/js/loaders/AssimpJSONLoader.js
  20. 0 2
      examples/js/loaders/BinaryLoader.js
  21. 23 15
      examples/js/loaders/DDSLoader.js
  22. 1 27
      examples/js/loaders/deprecated/SceneLoader.js
  23. 506 329
      examples/js/loaders/sea3d/SEA3D.js
  24. 11 12
      examples/js/loaders/sea3d/SEA3DDeflate.js
  25. 25 19
      examples/js/loaders/sea3d/SEA3DLZMA.js
  26. 0 13
      examples/js/loaders/sea3d/SEA3DLZMA_LZIP.js
  27. 760 1087
      examples/js/loaders/sea3d/SEA3DLoader.js
  28. 0 1209
      examples/js/renderers/WebGLDeferredRenderer.js
  29. 0 515
      examples/js/shaders/NormalDisplacementShader.js
  30. 6 7
      examples/misc_controls_fly.html
  31. 0 43
      examples/models/animated/elderlyWalk.js
  32. BIN
      examples/models/sea3d/flag.sea
  33. BIN
      examples/models/sea3d/flag.tjs.sea
  34. BIN
      examples/models/sea3d/keyframe.tjs.sea
  35. BIN
      examples/models/sea3d/mascot.tjs.sea
  36. BIN
      examples/models/sea3d/morph.tjs.sea
  37. BIN
      examples/models/sea3d/robot.tjs.sea
  38. BIN
      examples/models/sea3d/skin.tjs.sea
  39. BIN
      examples/models/sea3d/sound.tjs.sea
  40. 0 43
      examples/models/skinned/human_walk_0_female.js
  41. BIN
      examples/obj/box/box.bin
  42. 0 29
      examples/obj/box/box.js
  43. 0 7
      examples/obj/ninja/.htaccess
  44. 0 2
      examples/webgl_loader_ctm.html
  45. 5 7
      examples/webgl_loader_sea3d.html
  46. 3 7
      examples/webgl_loader_sea3d_hierarchy.html
  47. 4 6
      examples/webgl_loader_sea3d_keyframe.html
  48. 5 7
      examples/webgl_loader_sea3d_morph.html
  49. 5 6
      examples/webgl_loader_sea3d_skinning.html
  50. 2 4
      examples/webgl_loader_sea3d_sound.html
  51. 0 325
      examples/webgl_materials_normaldisplacementmap.html
  52. 0 2
      examples/webgl_materials_normalmap.html
  53. 0 2
      examples/webgl_postprocessing_advanced.html
  54. 377 0
      examples/webgl_raycast_texture.html
  55. 1 9
      examples/webgl_sandbox.html
  56. 3 1
      examples/webgl_terrain_dynamic.html
  57. 0 479
      examples/webgldeferred_animation.html
  58. 0 388
      examples/webgldeferred_arealights.html
  59. 0 429
      examples/webgldeferred_pointlights.html
  60. 18 206
      src/core/BufferGeometry.js
  61. 0 34
      src/core/DirectGeometry.js
  62. 0 8
      src/core/Face3.js
  63. 1 118
      src/core/Geometry.js
  64. 1 90
      src/extras/geometries/SphereGeometry.js
  65. 0 144
      src/extras/helpers/VertexTangentsHelper.js
  66. 0 56
      src/lights/AreaLight.js
  67. 9 0
      src/loaders/BufferGeometryLoader.js
  68. 4 6
      src/loaders/ImageLoader.js
  69. 0 6
      src/loaders/JSONLoader.js
  70. 0 14
      src/loaders/Loader.js
  71. 11 0
      src/loaders/LoadingManager.js
  72. 38 13
      src/loaders/ObjectLoader.js
  73. 4 6
      src/loaders/XHRLoader.js
  74. 8 6
      src/math/Quaternion.js
  75. 25 0
      src/objects/LOD.js
  76. 80 21
      src/objects/Mesh.js
  77. 0 4
      src/renderers/WebGLRenderer.js
  78. 20 4
      src/renderers/webgl/WebGLObjects.js
  79. 77 0
      src/textures/Texture.js
  80. 0 28
      test/unit/lights/AreaLight.tests.js
  81. 0 1
      test/unit/unittests_three.html
  82. 0 1
      utils/build/includes/common.json
  83. 0 1
      utils/build/includes/extras.json
  84. 0 1
      utils/exporters/blender/addons/io_three/constants.py
  85. 15 15
      utils/exporters/blender/tests/scripts/js/review.js

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 211 - 483
build/three.js


+ 297 - 305
build/three.min.js

@@ -26,15 +26,15 @@ lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,medi
 palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,
 tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};THREE.Quaternion=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.Quaternion.prototype={constructor:THREE.Quaternion,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},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},
-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),g=Math.sin(a._x/2),f=Math.sin(a._y/2),h=Math.sin(a._z/2);"XYZ"===a.order?(this._x=g*d*e+c*f*h,this._y=c*f*e-g*d*h,this._z=c*d*h+g*f*e,this._w=c*d*e-g*f*h):"YXZ"===a.order?
-(this._x=g*d*e+c*f*h,this._y=c*f*e-g*d*h,this._z=c*d*h-g*f*e,this._w=c*d*e+g*f*h):"ZXY"===a.order?(this._x=g*d*e-c*f*h,this._y=c*f*e+g*d*h,this._z=c*d*h+g*f*e,this._w=c*d*e-g*f*h):"ZYX"===a.order?(this._x=g*d*e-c*f*h,this._y=c*f*e+g*d*h,this._z=c*d*h-g*f*e,this._w=c*d*e+g*f*h):"YZX"===a.order?(this._x=g*d*e+c*f*h,this._y=c*f*e+g*d*h,this._z=c*d*h-g*f*e,this._w=c*d*e-g*f*h):"XZY"===a.order&&(this._x=g*d*e-c*f*h,this._y=c*f*e-g*d*h,this._z=c*d*h+g*f*e,this._w=c*d*e+g*f*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],g=b[5],f=b[9],h=b[2],k=b[6],b=b[10],l=c+g+b;0<l?(c=.5/Math.sqrt(l+1),this._w=.25/c,this._x=(k-f)*c,this._y=(d-h)*c,this._z=(e-a)*c):c>g&&c>b?(c=2*Math.sqrt(1+c-g-b),this._w=(k-f)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):g>b?(c=2*Math.sqrt(1+g-
-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(f+k)/c):(c=2*Math.sqrt(1+b-c-g),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(f+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,g=a._w,f=b._x,h=b._y,k=b._z,l=b._w;this._x=c*l+g*f+d*k-e*h;this._y=d*l+g*h+e*f-c*k;this._z=e*l+g*k+c*h-d*f;this._w=g*l-c*f-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,g=this._w,f=g*a._w+c*a._x+d*a._y+e*a._z;0>f?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,f=-f):this.copy(a);if(1<=f)return this._w=g,this._x=c,this._y=d,this._z=e,this;var h=Math.acos(f),k=Math.sqrt(1-
-f*f);if(.001>Math.abs(k))return this._w=.5*(g+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;f=Math.sin((1-b)*h)/k;h=Math.sin(b*h)/k;this._w=g*f+this._w*h;this._x=c*f+this._x*h;this._y=d*f+this._y*h;this._z=e*f+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(){}};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};
+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),g=Math.sin(a._x/2),f=Math.sin(a._y/2),h=Math.sin(a._z/2),k=a.order;"XYZ"===k?(this._x=g*d*e+c*f*h,this._y=c*f*e-g*d*h,this._z=c*d*h+g*f*e,this._w=c*d*e-g*f*h):"YXZ"===
+k?(this._x=g*d*e+c*f*h,this._y=c*f*e-g*d*h,this._z=c*d*h-g*f*e,this._w=c*d*e+g*f*h):"ZXY"===k?(this._x=g*d*e-c*f*h,this._y=c*f*e+g*d*h,this._z=c*d*h+g*f*e,this._w=c*d*e-g*f*h):"ZYX"===k?(this._x=g*d*e-c*f*h,this._y=c*f*e+g*d*h,this._z=c*d*h-g*f*e,this._w=c*d*e+g*f*h):"YZX"===k?(this._x=g*d*e+c*f*h,this._y=c*f*e+g*d*h,this._z=c*d*h-g*f*e,this._w=c*d*e-g*f*h):"XZY"===k&&(this._x=g*d*e-c*f*h,this._y=c*f*e-g*d*h,this._z=c*d*h+g*f*e,this._w=c*d*e+g*f*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],g=b[5],f=b[9],h=b[2],k=b[6],b=b[10],l=c+g+b;0<l?(c=.5/Math.sqrt(l+1),this._w=.25/c,this._x=(k-f)*c,this._y=(d-h)*c,this._z=(e-a)*c):c>g&&c>b?(c=2*Math.sqrt(1+c-g-b),this._w=(k-f)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):g>b?(c=2*Math.sqrt(1+g-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=
+.25*c,this._z=(f+k)/c):(c=2*Math.sqrt(1+b-c-g),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(f+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,g=a._w,f=b._x,h=b._y,k=b._z,l=b._w;this._x=c*l+g*f+d*k-e*h;this._y=d*l+g*h+e*f-c*k;this._z=e*l+g*k+c*h-d*f;this._w=g*l-c*f-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,g=this._w,f=g*a._w+c*a._x+d*a._y+e*a._z;0>f?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,f=-f):this.copy(a);if(1<=f)return this._w=g,this._x=c,this._y=d,this._z=e,this;var h=Math.acos(f),k=Math.sqrt(1-f*f);if(.001>Math.abs(k))return this._w=.5*(g+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;f=Math.sin((1-b)*h)/k;h=
+Math.sin(b*h)/k;this._w=g*f+this._w*h;this._x=c*f+this._x*h;this._y=d*f+this._y*h;this._z=e*f+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(){}};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);}},clone:function(){return new this.constructor(this.x,this.y)},
 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},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},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;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},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=
@@ -99,22 +99,22 @@ a&&(a=new THREE.Vector3);void 0===c&&(c=0);void 0===d&&(d=b.length/b.itemSize);f
 b){var c=a.elements,d=this.elements;d[0]=c[10]*c[5]-c[6]*c[9];d[1]=-c[10]*c[1]+c[2]*c[9];d[2]=c[6]*c[1]-c[2]*c[5];d[3]=-c[10]*c[4]+c[6]*c[8];d[4]=c[10]*c[0]-c[2]*c[8];d[5]=-c[6]*c[0]+c[2]*c[4];d[6]=c[9]*c[4]-c[5]*c[8];d[7]=-c[9]*c[0]+c[1]*c[8];d[8]=c[5]*c[0]-c[1]*c[4];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");console.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]]}};THREE.Matrix4=function(){this.elements=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);0<arguments.length&&console.error("THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.")};
-THREE.Matrix4.prototype={constructor:THREE.Matrix4,set:function(a,b,c,d,e,g,f,h,k,l,n,p,m,q,s,r){var u=this.elements;u[0]=a;u[4]=b;u[8]=c;u[12]=d;u[1]=e;u[5]=g;u[9]=f;u[13]=h;u[2]=k;u[6]=l;u[10]=n;u[14]=p;u[3]=m;u[7]=q;u[11]=s;u[15]=r;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new THREE.Matrix4).fromArray(this.elements)},copy:function(a){this.elements.set(a.elements);return this},extractPosition:function(a){console.warn("THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().");
+THREE.Matrix4.prototype={constructor:THREE.Matrix4,set:function(a,b,c,d,e,g,f,h,k,l,n,p,m,q,t,r){var v=this.elements;v[0]=a;v[4]=b;v[8]=c;v[12]=d;v[1]=e;v[5]=g;v[9]=f;v[13]=h;v[2]=k;v[6]=l;v[10]=n;v[14]=p;v[3]=m;v[7]=q;v[11]=t;v[15]=r;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new THREE.Matrix4).fromArray(this.elements)},copy:function(a){this.elements.set(a.elements);return this},extractPosition:function(a){console.warn("THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().");
 return this.copyPosition(a)},copyPosition:function(a){var b=this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a,b,c){var d=this.elements;a.set(d[0],d[1],d[2]);b.set(d[4],d[5],d[6]);c.set(d[8],d[9],d[10]);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);var c=this.elements;b=b.elements;var d=1/a.set(b[0],
 b[1],b[2]).length(),e=1/a.set(b[4],b[5],b[6]).length(),g=1/a.set(b[8],b[9],b[10]).length();c[0]=b[0]*d;c[1]=b[1]*d;c[2]=b[2]*d;c[4]=b[4]*e;c[5]=b[5]*e;c[6]=b[6]*e;c[8]=b[8]*g;c[9]=b[9]*g;c[10]=b[10]*g;return this}}(),makeRotationFromEuler:function(a){!1===a instanceof THREE.Euler&&console.error("THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var b=this.elements,c=a.x,d=a.y,e=a.z,g=Math.cos(c),c=Math.sin(c),f=Math.cos(d),d=Math.sin(d),h=Math.cos(e),
 e=Math.sin(e);if("XYZ"===a.order){a=g*h;var k=g*e,l=c*h,n=c*e;b[0]=f*h;b[4]=-f*e;b[8]=d;b[1]=k+l*d;b[5]=a-n*d;b[9]=-c*f;b[2]=n-a*d;b[6]=l+k*d;b[10]=g*f}else"YXZ"===a.order?(a=f*h,k=f*e,l=d*h,n=d*e,b[0]=a+n*c,b[4]=l*c-k,b[8]=g*d,b[1]=g*e,b[5]=g*h,b[9]=-c,b[2]=k*c-l,b[6]=n+a*c,b[10]=g*f):"ZXY"===a.order?(a=f*h,k=f*e,l=d*h,n=d*e,b[0]=a-n*c,b[4]=-g*e,b[8]=l+k*c,b[1]=k+l*c,b[5]=g*h,b[9]=n-a*c,b[2]=-g*d,b[6]=c,b[10]=g*f):"ZYX"===a.order?(a=g*h,k=g*e,l=c*h,n=c*e,b[0]=f*h,b[4]=l*d-k,b[8]=a*d+n,b[1]=f*e,b[5]=
 n*d+a,b[9]=k*d-l,b[2]=-d,b[6]=c*f,b[10]=g*f):"YZX"===a.order?(a=g*f,k=g*d,l=c*f,n=c*d,b[0]=f*h,b[4]=n-a*e,b[8]=l*e+k,b[1]=e,b[5]=g*h,b[9]=-c*h,b[2]=-d*h,b[6]=k*e+l,b[10]=a-n*e):"XZY"===a.order&&(a=g*f,k=g*d,l=c*f,n=c*d,b[0]=f*h,b[4]=-e,b[8]=d*h,b[1]=a*e+n,b[5]=g*h,b[9]=k*e-l,b[2]=l*e-k,b[6]=c*h,b[10]=n*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,g=a.w,f=c+c,h=d+d,k=e+e;a=c*f;var l=c*h,c=c*k,n=d*h,d=d*k,e=e*k,f=g*f,h=g*h,g=g*k;b[0]=1-(n+e);b[4]=l-g;b[8]=c+h;b[1]=l+g;b[5]=1-(a+e);b[9]=d-f;b[2]=c-h;b[6]=d+f;b[10]=1-(a+n);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,b,c;return function(d,e,g){void 0===a&&(a=new THREE.Vector3);void 0===b&&(b=new THREE.Vector3);void 0===c&&(c=new THREE.Vector3);
 var f=this.elements;c.subVectors(d,e).normalize();0===c.length()&&(c.z=1);a.crossVectors(g,c).normalize();0===a.length()&&(c.x+=1E-4,a.crossVectors(g,c).normalize());b.crossVectors(c,a);f[0]=a.x;f[4]=b.x;f[8]=c.x;f[1]=a.y;f[5]=b.y;f[9]=c.y;f[2]=a.z;f[6]=b.z;f[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,g=c[0],f=c[4],h=c[8],k=c[12],l=c[1],n=c[5],p=c[9],m=c[13],q=c[2],s=c[6],r=c[10],u=c[14],x=c[3],v=c[7],y=c[11],c=c[15],w=d[0],G=d[4],B=d[8],z=d[12],A=d[1],O=d[5],K=d[9],D=d[13],P=d[2],J=d[6],H=d[10],C=d[14],F=d[3],N=d[7],R=d[11],d=d[15];e[0]=g*w+f*A+h*P+k*F;e[4]=g*G+f*O+h*J+k*N;e[8]=g*B+f*K+h*H+k*R;e[12]=g*z+f*D+h*C+k*d;e[1]=l*w+n*A+p*P+m*F;e[5]=l*G+n*O+p*J+m*N;e[9]=l*B+n*K+p*H+m*R;e[13]=l*z+n*D+p*C+m*d;e[2]=q*w+s*A+r*P+u*F;e[6]=q*G+s*O+r*J+u*N;e[10]=
-q*B+s*K+r*H+u*R;e[14]=q*z+s*D+r*C+u*d;e[3]=x*w+v*A+y*P+c*F;e[7]=x*G+v*O+y*J+c*N;e[11]=x*B+v*K+y*H+c*R;e[15]=x*z+v*D+y*C+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]*=
+b){var c=a.elements,d=b.elements,e=this.elements,g=c[0],f=c[4],h=c[8],k=c[12],l=c[1],n=c[5],p=c[9],m=c[13],q=c[2],t=c[6],r=c[10],v=c[14],w=c[3],u=c[7],z=c[11],c=c[15],x=d[0],D=d[4],F=d[8],y=d[12],B=d[1],L=d[5],N=d[9],C=d[13],O=d[2],G=d[6],J=d[10],A=d[14],H=d[3],P=d[7],Q=d[11],d=d[15];e[0]=g*x+f*B+h*O+k*H;e[4]=g*D+f*L+h*G+k*P;e[8]=g*F+f*N+h*J+k*Q;e[12]=g*y+f*C+h*A+k*d;e[1]=l*x+n*B+p*O+m*H;e[5]=l*D+n*L+p*G+m*P;e[9]=l*F+n*N+p*J+m*Q;e[13]=l*y+n*C+p*A+m*d;e[2]=q*x+t*B+r*O+v*H;e[6]=q*D+t*L+r*G+v*P;e[10]=
+q*F+t*N+r*J+v*Q;e[14]=q*y+t*C+r*A+v*d;e[3]=w*x+u*B+z*O+c*H;e[7]=w*D+u*L+z*G+c*P;e[11]=w*F+u*N+z*J+c*Q;e[15]=w*y+u*C+z*A+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;return function(b,c,d){void 0===a&&(a=new THREE.Vector3);void 0===c&&(c=0);void 0===d&&(d=b.length);for(var e=0;e<d;e+=3,c+=3)a.fromArray(b,c),a.applyMatrix4(this),a.toArray(b,c);return b}}(),applyToBuffer:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Vector3);void 0===c&&(c=0);void 0===d&&(d=b.length/b.itemSize);for(var e=0;e<d;e++,c++)a.x=b.getX(c),a.y=b.getY(c),a.z=b.getZ(c),a.applyMatrix4(this),b.setXYZ(a.x,
 a.y,a.z);return b}}(),rotateAxis:function(a){console.warn("THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.");a.transformDirection(this)},crossVector:function(a){console.warn("THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)},determinant:function(){var a=this.elements,b=a[0],c=a[4],d=a[8],e=a[12],g=a[1],f=a[5],h=a[9],k=a[13],l=a[2],n=a[6],p=a[10],m=a[14];return a[3]*(+e*h*n-d*k*
 n-e*f*p+c*k*p+d*f*m-c*h*m)+a[7]*(+b*h*m-b*k*p+e*g*p-d*g*m+d*k*l-e*h*l)+a[11]*(+b*k*n-b*f*m-e*g*n+c*g*m+e*f*l-c*k*l)+a[15]*(-d*f*l-b*h*n+b*f*p+d*g*n-c*g*p+c*h*l)},transpose:function(){var a=this.elements,b;b=a[1];a[1]=a[4];a[4]=b;b=a[2];a[2]=a[8];a[8]=b;b=a[6];a[6]=a[9];a[9]=b;b=a[3];a[3]=a[12];a[12]=b;b=a[7];a[7]=a[13];a[13]=b;b=a[11];a[11]=a[14];a[14]=b;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];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a},getPosition:function(){var a;return function(){void 0===a&&(a=new THREE.Vector3);console.warn("THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.");var b=this.elements;return a.set(b[12],b[13],b[14])}}(),setPosition:function(a){var b=this.elements;b[12]=a.x;b[13]=a.y;b[14]=a.z;return this},getInverse:function(a,b){var c=
-this.elements,d=a.elements,e=d[0],g=d[4],f=d[8],h=d[12],k=d[1],l=d[5],n=d[9],p=d[13],m=d[2],q=d[6],s=d[10],r=d[14],u=d[3],x=d[7],v=d[11],d=d[15];c[0]=n*r*x-p*s*x+p*q*v-l*r*v-n*q*d+l*s*d;c[4]=h*s*x-f*r*x-h*q*v+g*r*v+f*q*d-g*s*d;c[8]=f*p*x-h*n*x+h*l*v-g*p*v-f*l*d+g*n*d;c[12]=h*n*q-f*p*q-h*l*s+g*p*s+f*l*r-g*n*r;c[1]=p*s*u-n*r*u-p*m*v+k*r*v+n*m*d-k*s*d;c[5]=f*r*u-h*s*u+h*m*v-e*r*v-f*m*d+e*s*d;c[9]=h*n*u-f*p*u-h*k*v+e*p*v+f*k*d-e*n*d;c[13]=f*p*m-h*n*m+h*k*s-e*p*s-f*k*r+e*n*r;c[2]=l*r*u-p*q*u+p*m*x-k*r*
-x-l*m*d+k*q*d;c[6]=h*q*u-g*r*u-h*m*x+e*r*x+g*m*d-e*q*d;c[10]=g*p*u-h*l*u+h*k*x-e*p*x-g*k*d+e*l*d;c[14]=h*l*m-g*p*m-h*k*q+e*p*q+g*k*r-e*l*r;c[3]=n*q*u-l*s*u-n*m*x+k*s*x+l*m*v-k*q*v;c[7]=g*s*u-f*q*u+f*m*x-e*s*x-g*m*v+e*q*v;c[11]=f*l*u-g*n*u-f*k*x+e*n*x+g*k*v-e*l*v;c[15]=g*n*m-f*l*m+f*k*q-e*n*q-g*k*s+e*l*s;c=e*c[0]+k*c[4]+m*c[8]+u*c[12];if(0===c){if(b)throw Error("THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0");console.warn("THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0");
+this.elements,d=a.elements,e=d[0],g=d[4],f=d[8],h=d[12],k=d[1],l=d[5],n=d[9],p=d[13],m=d[2],q=d[6],t=d[10],r=d[14],v=d[3],w=d[7],u=d[11],d=d[15];c[0]=n*r*w-p*t*w+p*q*u-l*r*u-n*q*d+l*t*d;c[4]=h*t*w-f*r*w-h*q*u+g*r*u+f*q*d-g*t*d;c[8]=f*p*w-h*n*w+h*l*u-g*p*u-f*l*d+g*n*d;c[12]=h*n*q-f*p*q-h*l*t+g*p*t+f*l*r-g*n*r;c[1]=p*t*v-n*r*v-p*m*u+k*r*u+n*m*d-k*t*d;c[5]=f*r*v-h*t*v+h*m*u-e*r*u-f*m*d+e*t*d;c[9]=h*n*v-f*p*v-h*k*u+e*p*u+f*k*d-e*n*d;c[13]=f*p*m-h*n*m+h*k*t-e*p*t-f*k*r+e*n*r;c[2]=l*r*v-p*q*v+p*m*w-k*r*
+w-l*m*d+k*q*d;c[6]=h*q*v-g*r*v-h*m*w+e*r*w+g*m*d-e*q*d;c[10]=g*p*v-h*l*v+h*k*w-e*p*w-g*k*d+e*l*d;c[14]=h*l*m-g*p*m-h*k*q+e*p*q+g*k*r-e*l*r;c[3]=n*q*v-l*t*v-n*m*w+k*t*w+l*m*u-k*q*u;c[7]=g*t*v-f*q*v+f*m*w-e*t*w-g*m*u+e*q*u;c[11]=f*l*v-g*n*v-f*k*w+e*n*w+g*k*u-e*l*u;c[15]=g*n*m-f*l*m+f*k*q-e*n*q-g*k*t+e*l*t;c=e*c[0]+k*c[4]+m*c[8]+v*c[12];if(0===c){if(b)throw Error("THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0");console.warn("THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0");
 this.identity();return this}this.multiplyScalar(1/c);return this},translate:function(a){console.error("THREE.Matrix4: .translate() has been removed.")},rotateX:function(a){console.error("THREE.Matrix4: .rotateX() has been removed.")},rotateY:function(a){console.error("THREE.Matrix4: .rotateY() has been removed.")},rotateZ:function(a){console.error("THREE.Matrix4: .rotateZ() has been removed.")},rotateByAxis:function(a,b){console.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,g=a.x,f=a.y,h=a.z,k=e*g,l=e*f;this.set(k*g+c,k*f-d*h,k*h+d*f,0,k*f+d*h,l*f+c,l*h-d*g,0,k*h-d*f,l*h+d*g,e*h*h+c,0,0,0,0,1);return this},makeScale:function(a,b,c){this.set(a,0,0,0,0,b,
@@ -135,8 +135,8 @@ THREE.Sphere.prototype={constructor:THREE.Sphere,set:function(a,b){this.center.c
 empty:function(){return 0>=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=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}};
 THREE.Frustum=function(a,b,c,d,e,g){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!==g?g:new THREE.Plane]};
-THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,g){var f=this.planes;f[0].copy(a);f[1].copy(b);f[2].copy(c);f[3].copy(d);f[4].copy(e);f[5].copy(g);return this},clone:function(){return(new this.constructor).copy(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],g=c[3],f=c[4],h=c[5],k=c[6],l=c[7],n=c[8],p=c[9],m=c[10],q=c[11],s=c[12],r=c[13],u=c[14],
-c=c[15];b[0].setComponents(g-a,l-f,q-n,c-s).normalize();b[1].setComponents(g+a,l+f,q+n,c+s).normalize();b[2].setComponents(g+d,l+h,q+p,c+r).normalize();b[3].setComponents(g-d,l-h,q-p,c-r).normalize();b[4].setComponents(g-e,l-k,q-m,c-u).normalize();b[5].setComponents(g+e,l+k,q+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);
+THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,g){var f=this.planes;f[0].copy(a);f[1].copy(b);f[2].copy(c);f[3].copy(d);f[4].copy(e);f[5].copy(g);return this},clone:function(){return(new this.constructor).copy(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],g=c[3],f=c[4],h=c[5],k=c[6],l=c[7],n=c[8],p=c[9],m=c[10],q=c[11],t=c[12],r=c[13],v=c[14],
+c=c[15];b[0].setComponents(g-a,l-f,q-n,c-t).normalize();b[1].setComponents(g+a,l+f,q+n,c+t).normalize();b[2].setComponents(g+d,l+h,q+p,c+r).normalize();b[3].setComponents(g-d,l-h,q-p,c-r).normalize();b[4].setComponents(g-e,l-k,q-m,c-v).normalize();b[5].setComponents(g+e,l+k,q+m,c+v).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)<a)return!1;return!0},intersectsBox:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c){for(var d=this.planes,e=0;6>e;e++){var g=d[e];a.x=0<g.normal.x?c.min.x:c.max.x;b.x=0<g.normal.x?c.max.x:c.min.x;a.y=0<g.normal.y?c.min.y:c.max.y;b.y=0<g.normal.y?c.max.y:c.min.y;a.z=0<g.normal.z?c.min.z:c.max.z;b.z=0<g.normal.z?c.max.z:c.min.z;
 var f=g.distanceToPoint(a),g=g.distanceToPoint(b);if(0>f&&0>g)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}};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,
@@ -180,9 +180,9 @@ this.matrix),this.matrixWorldNeedsUpdate=!1,a=!0;for(var b=0,c=this.children.len
 this.userData);!0!==this.visible&&(d.visible=this.visible);d.matrix=this.matrix.toArray();if(0<this.children.length){d.children=[];for(var e=0;e<this.children.length;e++)d.children.push(this.children[e].toJSON(a).object)}e={};if(c){var c=b(a.geometries),g=b(a.materials),f=b(a.textures);a=b(a.images);0<c.length&&(e.geometries=c);0<g.length&&(e.materials=g);0<f.length&&(e.textures=f);0<a.length&&(e.images=a)}e.object=d;return e},clone:function(a){return(new this.constructor).copy(this,a)},copy:function(a,
 b){void 0===b&&(b=!0);this.name=a.name;this.up.copy(a.up);this.position.copy(a.position);this.quaternion.copy(a.quaternion);this.scale.copy(a.scale);this.rotationAutoUpdate=a.rotationAutoUpdate;this.matrix.copy(a.matrix);this.matrixWorld.copy(a.matrixWorld);this.matrixAutoUpdate=a.matrixAutoUpdate;this.matrixWorldNeedsUpdate=a.matrixWorldNeedsUpdate;this.visible=a.visible;this.castShadow=a.castShadow;this.receiveShadow=a.receiveShadow;this.frustumCulled=a.frustumCulled;this.renderOrder=a.renderOrder;
 this.userData=JSON.parse(JSON.stringify(a.userData));if(!0===b)for(var c=0;c<a.children.length;c++)this.add(a.children[c].clone());return this}};THREE.EventDispatcher.prototype.apply(THREE.Object3D.prototype);THREE.Object3DIdCount=0;
-THREE.Face3=function(a,b,c,d,e,g){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=Array.isArray(d)?d:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=Array.isArray(e)?e:[];this.vertexTangents=[];this.materialIndex=void 0!==g?g:0};
-THREE.Face3.prototype={constructor:THREE.Face3,clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a=a.a;this.b=a.b;this.c=a.c;this.normal.copy(a.normal);this.color.copy(a.color);this.materialIndex=a.materialIndex;for(var b=0,c=a.vertexNormals.length;b<c;b++)this.vertexNormals[b]=a.vertexNormals[b].clone();b=0;for(c=a.vertexColors.length;b<c;b++)this.vertexColors[b]=a.vertexColors[b].clone();b=0;for(c=a.vertexTangents.length;b<c;b++)this.vertexTangents[b]=a.vertexTangents[b].clone();
-return this}};THREE.Face4=function(a,b,c,d,e,g,f){console.warn("THREE.Face4 has been removed. A THREE.Face3 will be created instead.");return new THREE.Face3(a,b,c,e,g,f)};THREE.BufferAttribute=function(a,b){this.uuid=THREE.Math.generateUUID();this.array=a;this.itemSize=b;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0};
+THREE.Face3=function(a,b,c,d,e,g){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=Array.isArray(d)?d:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex=void 0!==g?g:0};
+THREE.Face3.prototype={constructor:THREE.Face3,clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a=a.a;this.b=a.b;this.c=a.c;this.normal.copy(a.normal);this.color.copy(a.color);this.materialIndex=a.materialIndex;for(var b=0,c=a.vertexNormals.length;b<c;b++)this.vertexNormals[b]=a.vertexNormals[b].clone();b=0;for(c=a.vertexColors.length;b<c;b++)this.vertexColors[b]=a.vertexColors[b].clone();return this}};
+THREE.Face4=function(a,b,c,d,e,g,f){console.warn("THREE.Face4 has been removed. A THREE.Face3 will be created instead.");return new THREE.Face3(a,b,c,e,g,f)};THREE.BufferAttribute=function(a,b){this.uuid=THREE.Math.generateUUID();this.array=a;this.itemSize=b;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0};
 THREE.BufferAttribute.prototype={constructor:THREE.BufferAttribute,get length(){console.warn("THREE.BufferAttribute: .length has been deprecated. Please use .count.");return this.array.length},get count(){return this.array.length/this.itemSize},set needsUpdate(a){!0===a&&this.version++},setDynamic:function(a){this.dynamic=a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.itemSize=a.itemSize;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.itemSize;
 c*=b.itemSize;for(var d=0,e=this.itemSize;d<e;d++)this.array[a+d]=b.array[c+d];return this},copyArray:function(a){this.array.set(a);return this},copyColorsArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var g=a[d];void 0===g&&(console.warn("THREE.BufferAttribute.copyColorsArray(): color is undefined",d),g=new THREE.Color);b[c++]=g.r;b[c++]=g.g;b[c++]=g.b}return this},copyIndicesArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var g=a[d];b[c++]=g.a;b[c++]=g.b;b[c++]=
 g.c}return this},copyVector2sArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var g=a[d];void 0===g&&(console.warn("THREE.BufferAttribute.copyVector2sArray(): vector is undefined",d),g=new THREE.Vector2);b[c++]=g.x;b[c++]=g.y}return this},copyVector3sArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var g=a[d];void 0===g&&(console.warn("THREE.BufferAttribute.copyVector3sArray(): vector is undefined",d),g=new THREE.Vector3);b[c++]=g.x;b[c++]=g.y;b[c++]=g.z}return this},
@@ -198,38 +198,35 @@ THREE.InstancedInterleavedBuffer.prototype.copy=function(a){THREE.InterleavedBuf
 THREE.InterleavedBufferAttribute.prototype={constructor:THREE.InterleavedBufferAttribute,get length(){console.warn("THREE.BufferAttribute: .length has been deprecated. Please use .count.");return this.array.length},get count(){return this.data.array.length/this.data.stride},setX:function(a,b){this.data.array[a*this.data.stride+this.offset]=b;return this},setY:function(a,b){this.data.array[a*this.data.stride+this.offset+1]=b;return this},setZ:function(a,b){this.data.array[a*this.data.stride+this.offset+
 2]=b;return this},setW:function(a,b){this.data.array[a*this.data.stride+this.offset+3]=b;return this},getX:function(a){return this.data.array[a*this.data.stride+this.offset]},getY:function(a){return this.data.array[a*this.data.stride+this.offset+1]},getZ:function(a){return this.data.array[a*this.data.stride+this.offset+2]},getW:function(a){return this.data.array[a*this.data.stride+this.offset+3]},setXY:function(a,b,c){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;
 return this},setXYZ:function(a,b,c,d){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;return this},setXYZW:function(a,b,c,d,e){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;this.data.array[a+3]=e;return this}};
-THREE.Geometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="Geometry";this.vertices=[];this.colors=[];this.faces=[];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphColors=[];this.morphNormals=[];this.skinWeights=[];this.skinIndices=[];this.lineDistances=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.lineDistancesNeedUpdate=this.colorsNeedUpdate=this.tangentsNeedUpdate=this.normalsNeedUpdate=
-this.uvsNeedUpdate=this.elementsNeedUpdate=this.verticesNeedUpdate=this.hasTangents=!1};
+THREE.Geometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="Geometry";this.vertices=[];this.colors=[];this.faces=[];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphColors=[];this.morphNormals=[];this.skinWeights=[];this.skinIndices=[];this.lineDistances=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.lineDistancesNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.uvsNeedUpdate=
+this.elementsNeedUpdate=this.verticesNeedUpdate=!1};
 THREE.Geometry.prototype={constructor:THREE.Geometry,applyMatrix:function(a){for(var b=(new THREE.Matrix3).getNormalMatrix(a),c=0,d=this.vertices.length;c<d;c++)this.vertices[c].applyMatrix4(a);c=0;for(d=this.faces.length;c<d;c++){a=this.faces[c];a.normal.applyMatrix3(b).normalize();for(var e=0,g=a.vertexNormals.length;e<g;e++)a.vertexNormals[e].applyMatrix3(b).normalize()}null!==this.boundingBox&&this.computeBoundingBox();null!==this.boundingSphere&&this.computeBoundingSphere();this.normalsNeedUpdate=
 this.verticesNeedUpdate=!0},rotateX:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.makeRotationX(b);this.applyMatrix(a);return this}}(),rotateY:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.makeRotationY(b);this.applyMatrix(a);return this}}(),rotateZ:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.makeRotationZ(b);this.applyMatrix(a);return this}}(),translate:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);
 a.makeTranslation(b,c,d);this.applyMatrix(a);return this}}(),scale:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeScale(b,c,d);this.applyMatrix(a);return this}}(),lookAt:function(){var a;return function(b){void 0===a&&(a=new THREE.Object3D);a.lookAt(b);a.updateMatrix();this.applyMatrix(a.matrix)}}(),fromBufferGeometry:function(a){var b=this,c=null!==a.index?a.index.array:void 0,d=a.attributes,e=d.position.array,g=void 0!==d.normal?d.normal.array:void 0,f=void 0!==
-d.color?d.color.array:void 0,h=void 0!==d.uv?d.uv.array:void 0,k=void 0!==d.uv2?d.uv2.array:void 0,l=void 0!==d.tangent?d.tangent.array:void 0;void 0!==k&&(this.faceVertexUvs[1]=[]);void 0!==l&&(this.hasTangents=!0);for(var n=[],p=[],m=[],q=[],s=d=0,r=0;d<e.length;d+=3,s+=2,r+=4)b.vertices.push(new THREE.Vector3(e[d],e[d+1],e[d+2])),void 0!==g&&n.push(new THREE.Vector3(g[d],g[d+1],g[d+2])),void 0!==f&&b.colors.push(new THREE.Color(f[d],f[d+1],f[d+2])),void 0!==h&&p.push(new THREE.Vector2(h[s],h[s+
-1])),void 0!==k&&m.push(new THREE.Vector2(k[s],k[s+1])),void 0!==l&&q.push(new THREE.Vector4(l[r],l[r+1],l[r+2],l[r+3]));r=function(a,c,d){var e=void 0!==g?[n[a].clone(),n[c].clone(),n[d].clone()]:[],s=void 0!==f?[b.colors[a].clone(),b.colors[c].clone(),b.colors[d].clone()]:[],e=new THREE.Face3(a,c,d,e,s);b.faces.push(e);void 0!==h&&b.faceVertexUvs[0].push([p[a].clone(),p[c].clone(),p[d].clone()]);void 0!==k&&b.faceVertexUvs[1].push([m[a].clone(),m[c].clone(),m[d].clone()]);void 0!==l&&e.vertexTangents.push(q[a].clone(),
-q[c].clone(),q[d].clone())};if(void 0!==c)if(e=a.groups,0<e.length)for(d=0;d<e.length;d++)for(var s=e[d],u=s.start,x=s.count,s=u,u=u+x;s<u;s+=3)r(c[s],c[s+1],c[s+2]);else for(d=0;d<c.length;d+=3)r(c[d],c[d+1],c[d+2]);else for(d=0;d<e.length/3;d+=3)r(d,d+1,d+2);this.computeFaceNormals();null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());return this},center:function(){this.computeBoundingBox();var a=this.boundingBox.center().negate();
-this.translate(a.x,a.y,a.z);return a},normalize:function(){this.computeBoundingSphere();var a=this.boundingSphere.center,b=this.boundingSphere.radius,b=0===b?1:1/b,c=new THREE.Matrix4;c.set(b,0,0,-b*a.x,0,b,0,-b*a.y,0,0,b,-b*a.z,0,0,0,1);this.applyMatrix(c);return this},computeFaceNormals:function(){for(var a=new THREE.Vector3,b=new THREE.Vector3,c=0,d=this.faces.length;c<d;c++){var e=this.faces[c],g=this.vertices[e.a],f=this.vertices[e.b];a.subVectors(this.vertices[e.c],f);b.subVectors(g,f);a.cross(b);
-a.normalize();e.normal.copy(a)}},computeVertexNormals:function(a){var b,c,d;d=Array(this.vertices.length);b=0;for(c=this.vertices.length;b<c;b++)d[b]=new THREE.Vector3;if(a){var e,g,f,h=new THREE.Vector3,k=new THREE.Vector3;a=0;for(b=this.faces.length;a<b;a++)c=this.faces[a],e=this.vertices[c.a],g=this.vertices[c.b],f=this.vertices[c.c],h.subVectors(f,g),k.subVectors(e,g),h.cross(k),d[c.a].add(h),d[c.b].add(h),d[c.c].add(h)}else for(a=0,b=this.faces.length;a<b;a++)c=this.faces[a],d[c.a].add(c.normal),
-d[c.b].add(c.normal),d[c.c].add(c.normal);b=0;for(c=this.vertices.length;b<c;b++)d[b].normalize();a=0;for(b=this.faces.length;a<b;a++)c=this.faces[a],e=c.vertexNormals,3===e.length?(e[0].copy(d[c.a]),e[1].copy(d[c.b]),e[2].copy(d[c.c])):(e[0]=d[c.a].clone(),e[1]=d[c.b].clone(),e[2]=d[c.c].clone())},computeMorphNormals:function(){var a,b,c,d,e;c=0;for(d=this.faces.length;c<d;c++)for(e=this.faces[c],e.__originalFaceNormal?e.__originalFaceNormal.copy(e.normal):e.__originalFaceNormal=e.normal.clone(),
-e.__originalVertexNormals||(e.__originalVertexNormals=[]),a=0,b=e.vertexNormals.length;a<b;a++)e.__originalVertexNormals[a]?e.__originalVertexNormals[a].copy(e.vertexNormals[a]):e.__originalVertexNormals[a]=e.vertexNormals[a].clone();var g=new THREE.Geometry;g.faces=this.faces;a=0;for(b=this.morphTargets.length;a<b;a++){if(!this.morphNormals[a]){this.morphNormals[a]={};this.morphNormals[a].faceNormals=[];this.morphNormals[a].vertexNormals=[];e=this.morphNormals[a].faceNormals;var f=this.morphNormals[a].vertexNormals,
-h,k;c=0;for(d=this.faces.length;c<d;c++)h=new THREE.Vector3,k={a:new THREE.Vector3,b:new THREE.Vector3,c:new THREE.Vector3},e.push(h),f.push(k)}f=this.morphNormals[a];g.vertices=this.morphTargets[a].vertices;g.computeFaceNormals();g.computeVertexNormals();c=0;for(d=this.faces.length;c<d;c++)e=this.faces[c],h=f.faceNormals[c],k=f.vertexNormals[c],h.copy(e.normal),k.a.copy(e.vertexNormals[0]),k.b.copy(e.vertexNormals[1]),k.c.copy(e.vertexNormals[2])}c=0;for(d=this.faces.length;c<d;c++)e=this.faces[c],
-e.normal=e.__originalFaceNormal,e.vertexNormals=e.__originalVertexNormals},computeTangents:function(){var a,b,c,d,e,g,f,h,k,l,n,p,m,q,s,r,u,x=[],v=[];c=new THREE.Vector3;var y=new THREE.Vector3,w=new THREE.Vector3,G=new THREE.Vector3,B=new THREE.Vector3;a=0;for(b=this.vertices.length;a<b;a++)x[a]=new THREE.Vector3,v[a]=new THREE.Vector3;a=0;for(b=this.faces.length;a<b;a++)e=this.faces[a],g=this.faceVertexUvs[0][a],d=e.a,u=e.b,e=e.c,f=this.vertices[d],h=this.vertices[u],k=this.vertices[e],l=g[0],n=
-g[1],p=g[2],g=h.x-f.x,m=k.x-f.x,q=h.y-f.y,s=k.y-f.y,h=h.z-f.z,f=k.z-f.z,k=n.x-l.x,r=p.x-l.x,n=n.y-l.y,l=p.y-l.y,p=1/(k*l-r*n),c.set((l*g-n*m)*p,(l*q-n*s)*p,(l*h-n*f)*p),y.set((k*m-r*g)*p,(k*s-r*q)*p,(k*f-r*h)*p),x[d].add(c),x[u].add(c),x[e].add(c),v[d].add(y),v[u].add(y),v[e].add(y);y=["a","b","c","d"];a=0;for(b=this.faces.length;a<b;a++)for(e=this.faces[a],c=0;c<Math.min(e.vertexNormals.length,3);c++)B.copy(e.vertexNormals[c]),d=e[y[c]],u=x[d],w.copy(u),w.sub(B.multiplyScalar(B.dot(u))).normalize(),
-G.crossVectors(e.vertexNormals[c],u),d=G.dot(v[d]),d=0>d?-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;c<d;c++)0<c&&(a+=b[c].distanceTo(b[c-1])),this.lineDistances[c]=a},computeBoundingBox:function(){null===this.boundingBox&&(this.boundingBox=new THREE.Box3);this.boundingBox.setFromPoints(this.vertices)},computeBoundingSphere:function(){null===this.boundingSphere&&(this.boundingSphere=new THREE.Sphere);
-this.boundingSphere.setFromPoints(this.vertices)},merge:function(a,b,c){if(!1===a instanceof THREE.Geometry)console.error("THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.",a);else{var d,e=this.vertices.length,g=this.vertices,f=a.vertices,h=this.faces,k=a.faces,l=this.faceVertexUvs[0];a=a.faceVertexUvs[0];void 0===c&&(c=0);void 0!==b&&(d=(new THREE.Matrix3).getNormalMatrix(b));for(var n=0,p=f.length;n<p;n++){var m=f[n].clone();void 0!==b&&m.applyMatrix4(b);g.push(m)}n=0;for(p=k.length;n<
-p;n++){var f=k[n],q,s=f.vertexNormals,r=f.vertexColors,m=new THREE.Face3(f.a+e,f.b+e,f.c+e);m.normal.copy(f.normal);void 0!==d&&m.normal.applyMatrix3(d).normalize();b=0;for(g=s.length;b<g;b++)q=s[b].clone(),void 0!==d&&q.applyMatrix3(d).normalize(),m.vertexNormals.push(q);m.color.copy(f.color);b=0;for(g=r.length;b<g;b++)q=r[b],m.vertexColors.push(q.clone());m.materialIndex=f.materialIndex+c;h.push(m)}n=0;for(p=a.length;n<p;n++)if(c=a[n],d=[],void 0!==c){b=0;for(g=c.length;b<g;b++)d.push(c[b].clone());
-l.push(d)}}},mergeMesh:function(a){!1===a instanceof THREE.Mesh?console.error("THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.",a):(a.matrixAutoUpdate&&a.updateMatrix(),this.merge(a.geometry,a.matrix))},mergeVertices:function(){var a={},b=[],c=[],d,e=Math.pow(10,4),g,f;g=0;for(f=this.vertices.length;g<f;g++)d=this.vertices[g],d=Math.round(d.x*e)+"_"+Math.round(d.y*e)+"_"+Math.round(d.z*e),void 0===a[d]?(a[d]=g,b.push(this.vertices[g]),c[g]=b.length-1):c[g]=c[a[d]];a=[];g=0;for(f=this.faces.length;g<
-f;g++)for(e=this.faces[g],e.a=c[e.a],e.b=c[e.b],e.c=c[e.c],e=[e.a,e.b,e.c],d=0;3>d;d++)if(e[d]===e[(d+1)%3]){a.push(g);break}for(g=a.length-1;0<=g;g--)for(e=a[g],this.faces.splice(e,1),c=0,f=this.faceVertexUvs.length;c<f;c++)this.faceVertexUvs[c].splice(e,1);g=this.vertices.length-b.length;this.vertices=b;return g},toJSON:function(){function a(a,b,c){return c?a|1<<b:a&~(1<<b)}function b(a){var b=a.x.toString()+a.y.toString()+a.z.toString();if(void 0!==l[b])return l[b];l[b]=k.length/3;k.push(a.x,a.y,
-a.z);return l[b]}function c(a){var b=a.r.toString()+a.g.toString()+a.b.toString();if(void 0!==p[b])return p[b];p[b]=n.length;n.push(a.getHex());return p[b]}function d(a){var b=a.x.toString()+a.y.toString();if(void 0!==q[b])return q[b];q[b]=m.length/2;m.push(a.x,a.y);return q[b]}var e={metadata:{version:4.4,type:"Geometry",generator:"Geometry.toJSON"}};e.uuid=this.uuid;e.type=this.type;""!==this.name&&(e.name=this.name);if(void 0!==this.parameters){var g=this.parameters,f;for(f in g)void 0!==g[f]&&
-(e[f]=g[f]);return e}g=[];for(f=0;f<this.vertices.length;f++){var h=this.vertices[f];g.push(h.x,h.y,h.z)}var h=[],k=[],l={},n=[],p={},m=[],q={};for(f=0;f<this.faces.length;f++){var s=this.faces[f],r=void 0!==this.faceVertexUvs[0][f],u=0<s.normal.length(),x=0<s.vertexNormals.length,v=1!==s.color.r||1!==s.color.g||1!==s.color.b,y=0<s.vertexColors.length,w=0,w=a(w,0,0),w=a(w,1,!1),w=a(w,2,!1),w=a(w,3,r),w=a(w,4,u),w=a(w,5,x),w=a(w,6,v),w=a(w,7,y);h.push(w);h.push(s.a,s.b,s.c);r&&(r=this.faceVertexUvs[0][f],
-h.push(d(r[0]),d(r[1]),d(r[2])));u&&h.push(b(s.normal));x&&(u=s.vertexNormals,h.push(b(u[0]),b(u[1]),b(u[2])));v&&h.push(c(s.color));y&&(s=s.vertexColors,h.push(c(s[0]),c(s[1]),c(s[2])))}e.data={};e.data.vertices=g;e.data.normals=k;0<n.length&&(e.data.colors=n);0<m.length&&(e.data.uvs=[m]);e.data.faces=h;return e},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.vertices=[];this.faces=[];this.faceVertexUvs=[[]];for(var b=a.vertices,c=0,d=b.length;c<d;c++)this.vertices.push(b[c].clone());
-b=a.faces;c=0;for(d=b.length;c<d;c++)this.faces.push(b[c].clone());c=0;for(d=a.faceVertexUvs.length;c<d;c++){b=a.faceVertexUvs[c];void 0===this.faceVertexUvs[c]&&(this.faceVertexUvs[c]=[]);for(var e=0,g=b.length;e<g;e++){for(var f=b[e],h=[],k=0,l=f.length;k<l;k++)h.push(f[k].clone());this.faceVertexUvs[c].push(h)}}return this},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Geometry.prototype);THREE.GeometryIdCount=0;
-THREE.DirectGeometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="DirectGeometry";this.indices=[];this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.tangents=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.tangentsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=
-this.verticesNeedUpdate=!1};
-THREE.DirectGeometry.prototype={constructor:THREE.DirectGeometry,computeBoundingBox:THREE.Geometry.prototype.computeBoundingBox,computeBoundingSphere:THREE.Geometry.prototype.computeBoundingSphere,computeFaceNormals:function(){console.warn("THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.");return this},computeVertexNormals:function(){console.warn("THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.");return this},computeTangents:function(){console.warn("THREE.DirectGeometry: computeTangents() is not a method of this type of geometry.");
-return this},computeGroups:function(a){var b,c=[],d;a=a.faces;for(var e=0;e<a.length;e++){var g=a[e];g.materialIndex!==d&&(d=g.materialIndex,void 0!==b&&(b.count=3*e-b.start,c.push(b)),b={start:3*e,materialIndex:d})}void 0!==b&&(b.count=3*e-b.start,c.push(b));this.groups=c},fromGeometry:function(a){var b=a.faces,c=a.vertices,d=a.faceVertexUvs,e=d[0]&&0<d[0].length,g=d[1]&&0<d[1].length,f=a.hasTangents,h=a.morphTargets,k=h.length;if(0<k){for(var l=[],n=0;n<k;n++)l[n]=[];this.morphTargets.position=
-l}var p=a.morphNormals,m=p.length;if(0<m){for(var q=[],n=0;n<m;n++)q[n]=[];this.morphTargets.normal=q}for(var s=a.skinIndices,r=a.skinWeights,u=s.length===c.length,x=r.length===c.length,n=0;n<b.length;n++){var v=b[n];this.vertices.push(c[v.a],c[v.b],c[v.c]);var y=v.vertexNormals;3===y.length?this.normals.push(y[0],y[1],y[2]):(y=v.normal,this.normals.push(y,y,y));y=v.vertexColors;3===y.length?this.colors.push(y[0],y[1],y[2]):(y=v.color,this.colors.push(y,y,y));!0===e&&(y=d[0][n],void 0!==y?this.uvs.push(y[0],
-y[1],y[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ",n),this.uvs.push(new THREE.Vector2,new THREE.Vector2,new THREE.Vector2)));!0===g&&(y=d[1][n],void 0!==y?this.uvs2.push(y[0],y[1],y[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ",n),this.uvs2.push(new THREE.Vector2,new THREE.Vector2,new THREE.Vector2)));!0===f&&(y=v.vertexTangents,3===y.length?this.tangents.push(y[0],y[1],y[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined tangents ",
-n),this.tangents.push(new THREE.Vector4,new THREE.Vector4,new THREE.Vector4)));for(y=0;y<k;y++){var w=h[y].vertices;l[y].push(w[v.a],w[v.b],w[v.c])}for(y=0;y<m;y++)w=p[y].vertexNormals[n],q[y].push(w.a,w.b,w.c);u&&this.skinIndices.push(s[v.a],s[v.b],s[v.c]);x&&this.skinWeights.push(r[v.a],r[v.b],r[v.c])}this.computeGroups(a);this.verticesNeedUpdate=a.verticesNeedUpdate;this.normalsNeedUpdate=a.normalsNeedUpdate;this.colorsNeedUpdate=a.colorsNeedUpdate;this.uvsNeedUpdate=a.uvsNeedUpdate;this.tangentsNeedUpdate=
-a.tangentsNeedUpdate;this.groupsNeedUpdate=a.groupsNeedUpdate;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.DirectGeometry.prototype);THREE.BufferGeometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null};
+d.color?d.color.array:void 0,h=void 0!==d.uv?d.uv.array:void 0,k=void 0!==d.uv2?d.uv2.array:void 0;void 0!==k&&(this.faceVertexUvs[1]=[]);for(var l=[],n=[],p=[],m=d=0;d<e.length;d+=3,m+=2)b.vertices.push(new THREE.Vector3(e[d],e[d+1],e[d+2])),void 0!==g&&l.push(new THREE.Vector3(g[d],g[d+1],g[d+2])),void 0!==f&&b.colors.push(new THREE.Color(f[d],f[d+1],f[d+2])),void 0!==h&&n.push(new THREE.Vector2(h[m],h[m+1])),void 0!==k&&p.push(new THREE.Vector2(k[m],k[m+1]));var q=function(a,c,d){var e=void 0!==
+g?[l[a].clone(),l[c].clone(),l[d].clone()]:[],m=void 0!==f?[b.colors[a].clone(),b.colors[c].clone(),b.colors[d].clone()]:[],e=new THREE.Face3(a,c,d,e,m);b.faces.push(e);void 0!==h&&b.faceVertexUvs[0].push([n[a].clone(),n[c].clone(),n[d].clone()]);void 0!==k&&b.faceVertexUvs[1].push([p[a].clone(),p[c].clone(),p[d].clone()])};if(void 0!==c)if(e=a.groups,0<e.length)for(d=0;d<e.length;d++)for(var m=e[d],t=m.start,r=m.count,m=t,t=t+r;m<t;m+=3)q(c[m],c[m+1],c[m+2]);else for(d=0;d<c.length;d+=3)q(c[d],c[d+
+1],c[d+2]);else for(d=0;d<e.length/3;d+=3)q(d,d+1,d+2);this.computeFaceNormals();null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());return this},center:function(){this.computeBoundingBox();var a=this.boundingBox.center().negate();this.translate(a.x,a.y,a.z);return a},normalize:function(){this.computeBoundingSphere();var a=this.boundingSphere.center,b=this.boundingSphere.radius,b=0===b?1:1/b,c=new THREE.Matrix4;c.set(b,
+0,0,-b*a.x,0,b,0,-b*a.y,0,0,b,-b*a.z,0,0,0,1);this.applyMatrix(c);return this},computeFaceNormals:function(){for(var a=new THREE.Vector3,b=new THREE.Vector3,c=0,d=this.faces.length;c<d;c++){var e=this.faces[c],g=this.vertices[e.a],f=this.vertices[e.b];a.subVectors(this.vertices[e.c],f);b.subVectors(g,f);a.cross(b);a.normalize();e.normal.copy(a)}},computeVertexNormals:function(a){var b,c,d;d=Array(this.vertices.length);b=0;for(c=this.vertices.length;b<c;b++)d[b]=new THREE.Vector3;if(a){var e,g,f,h=
+new THREE.Vector3,k=new THREE.Vector3;a=0;for(b=this.faces.length;a<b;a++)c=this.faces[a],e=this.vertices[c.a],g=this.vertices[c.b],f=this.vertices[c.c],h.subVectors(f,g),k.subVectors(e,g),h.cross(k),d[c.a].add(h),d[c.b].add(h),d[c.c].add(h)}else for(a=0,b=this.faces.length;a<b;a++)c=this.faces[a],d[c.a].add(c.normal),d[c.b].add(c.normal),d[c.c].add(c.normal);b=0;for(c=this.vertices.length;b<c;b++)d[b].normalize();a=0;for(b=this.faces.length;a<b;a++)c=this.faces[a],e=c.vertexNormals,3===e.length?
+(e[0].copy(d[c.a]),e[1].copy(d[c.b]),e[2].copy(d[c.c])):(e[0]=d[c.a].clone(),e[1]=d[c.b].clone(),e[2]=d[c.c].clone())},computeMorphNormals:function(){var a,b,c,d,e;c=0;for(d=this.faces.length;c<d;c++)for(e=this.faces[c],e.__originalFaceNormal?e.__originalFaceNormal.copy(e.normal):e.__originalFaceNormal=e.normal.clone(),e.__originalVertexNormals||(e.__originalVertexNormals=[]),a=0,b=e.vertexNormals.length;a<b;a++)e.__originalVertexNormals[a]?e.__originalVertexNormals[a].copy(e.vertexNormals[a]):e.__originalVertexNormals[a]=
+e.vertexNormals[a].clone();var g=new THREE.Geometry;g.faces=this.faces;a=0;for(b=this.morphTargets.length;a<b;a++){if(!this.morphNormals[a]){this.morphNormals[a]={};this.morphNormals[a].faceNormals=[];this.morphNormals[a].vertexNormals=[];e=this.morphNormals[a].faceNormals;var f=this.morphNormals[a].vertexNormals,h,k;c=0;for(d=this.faces.length;c<d;c++)h=new THREE.Vector3,k={a:new THREE.Vector3,b:new THREE.Vector3,c:new THREE.Vector3},e.push(h),f.push(k)}f=this.morphNormals[a];g.vertices=this.morphTargets[a].vertices;
+g.computeFaceNormals();g.computeVertexNormals();c=0;for(d=this.faces.length;c<d;c++)e=this.faces[c],h=f.faceNormals[c],k=f.vertexNormals[c],h.copy(e.normal),k.a.copy(e.vertexNormals[0]),k.b.copy(e.vertexNormals[1]),k.c.copy(e.vertexNormals[2])}c=0;for(d=this.faces.length;c<d;c++)e=this.faces[c],e.normal=e.__originalFaceNormal,e.vertexNormals=e.__originalVertexNormals},computeTangents:function(){console.warn("THREE.Geometry: .computeTangents() has been removed.")},computeLineDistances:function(){for(var a=
+0,b=this.vertices,c=0,d=b.length;c<d;c++)0<c&&(a+=b[c].distanceTo(b[c-1])),this.lineDistances[c]=a},computeBoundingBox:function(){null===this.boundingBox&&(this.boundingBox=new THREE.Box3);this.boundingBox.setFromPoints(this.vertices)},computeBoundingSphere:function(){null===this.boundingSphere&&(this.boundingSphere=new THREE.Sphere);this.boundingSphere.setFromPoints(this.vertices)},merge:function(a,b,c){if(!1===a instanceof THREE.Geometry)console.error("THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.",
+a);else{var d,e=this.vertices.length,g=this.vertices,f=a.vertices,h=this.faces,k=a.faces,l=this.faceVertexUvs[0];a=a.faceVertexUvs[0];void 0===c&&(c=0);void 0!==b&&(d=(new THREE.Matrix3).getNormalMatrix(b));for(var n=0,p=f.length;n<p;n++){var m=f[n].clone();void 0!==b&&m.applyMatrix4(b);g.push(m)}n=0;for(p=k.length;n<p;n++){var f=k[n],q,t=f.vertexNormals,r=f.vertexColors,m=new THREE.Face3(f.a+e,f.b+e,f.c+e);m.normal.copy(f.normal);void 0!==d&&m.normal.applyMatrix3(d).normalize();b=0;for(g=t.length;b<
+g;b++)q=t[b].clone(),void 0!==d&&q.applyMatrix3(d).normalize(),m.vertexNormals.push(q);m.color.copy(f.color);b=0;for(g=r.length;b<g;b++)q=r[b],m.vertexColors.push(q.clone());m.materialIndex=f.materialIndex+c;h.push(m)}n=0;for(p=a.length;n<p;n++)if(c=a[n],d=[],void 0!==c){b=0;for(g=c.length;b<g;b++)d.push(c[b].clone());l.push(d)}}},mergeMesh:function(a){!1===a instanceof THREE.Mesh?console.error("THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.",a):(a.matrixAutoUpdate&&a.updateMatrix(),
+this.merge(a.geometry,a.matrix))},mergeVertices:function(){var a={},b=[],c=[],d,e=Math.pow(10,4),g,f;g=0;for(f=this.vertices.length;g<f;g++)d=this.vertices[g],d=Math.round(d.x*e)+"_"+Math.round(d.y*e)+"_"+Math.round(d.z*e),void 0===a[d]?(a[d]=g,b.push(this.vertices[g]),c[g]=b.length-1):c[g]=c[a[d]];a=[];g=0;for(f=this.faces.length;g<f;g++)for(e=this.faces[g],e.a=c[e.a],e.b=c[e.b],e.c=c[e.c],e=[e.a,e.b,e.c],d=0;3>d;d++)if(e[d]===e[(d+1)%3]){a.push(g);break}for(g=a.length-1;0<=g;g--)for(e=a[g],this.faces.splice(e,
+1),c=0,f=this.faceVertexUvs.length;c<f;c++)this.faceVertexUvs[c].splice(e,1);g=this.vertices.length-b.length;this.vertices=b;return g},toJSON:function(){function a(a,b,c){return c?a|1<<b:a&~(1<<b)}function b(a){var b=a.x.toString()+a.y.toString()+a.z.toString();if(void 0!==l[b])return l[b];l[b]=k.length/3;k.push(a.x,a.y,a.z);return l[b]}function c(a){var b=a.r.toString()+a.g.toString()+a.b.toString();if(void 0!==p[b])return p[b];p[b]=n.length;n.push(a.getHex());return p[b]}function d(a){var b=a.x.toString()+
+a.y.toString();if(void 0!==q[b])return q[b];q[b]=m.length/2;m.push(a.x,a.y);return q[b]}var e={metadata:{version:4.4,type:"Geometry",generator:"Geometry.toJSON"}};e.uuid=this.uuid;e.type=this.type;""!==this.name&&(e.name=this.name);if(void 0!==this.parameters){var g=this.parameters,f;for(f in g)void 0!==g[f]&&(e[f]=g[f]);return e}g=[];for(f=0;f<this.vertices.length;f++){var h=this.vertices[f];g.push(h.x,h.y,h.z)}var h=[],k=[],l={},n=[],p={},m=[],q={};for(f=0;f<this.faces.length;f++){var t=this.faces[f],
+r=void 0!==this.faceVertexUvs[0][f],v=0<t.normal.length(),w=0<t.vertexNormals.length,u=1!==t.color.r||1!==t.color.g||1!==t.color.b,z=0<t.vertexColors.length,x=0,x=a(x,0,0),x=a(x,1,!1),x=a(x,2,!1),x=a(x,3,r),x=a(x,4,v),x=a(x,5,w),x=a(x,6,u),x=a(x,7,z);h.push(x);h.push(t.a,t.b,t.c);r&&(r=this.faceVertexUvs[0][f],h.push(d(r[0]),d(r[1]),d(r[2])));v&&h.push(b(t.normal));w&&(v=t.vertexNormals,h.push(b(v[0]),b(v[1]),b(v[2])));u&&h.push(c(t.color));z&&(t=t.vertexColors,h.push(c(t[0]),c(t[1]),c(t[2])))}e.data=
+{};e.data.vertices=g;e.data.normals=k;0<n.length&&(e.data.colors=n);0<m.length&&(e.data.uvs=[m]);e.data.faces=h;return e},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.vertices=[];this.faces=[];this.faceVertexUvs=[[]];for(var b=a.vertices,c=0,d=b.length;c<d;c++)this.vertices.push(b[c].clone());b=a.faces;c=0;for(d=b.length;c<d;c++)this.faces.push(b[c].clone());c=0;for(d=a.faceVertexUvs.length;c<d;c++){b=a.faceVertexUvs[c];void 0===this.faceVertexUvs[c]&&(this.faceVertexUvs[c]=
+[]);for(var e=0,g=b.length;e<g;e++){for(var f=b[e],h=[],k=0,l=f.length;k<l;k++)h.push(f[k].clone());this.faceVertexUvs[c].push(h)}}return this},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Geometry.prototype);THREE.GeometryIdCount=0;
+THREE.DirectGeometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="DirectGeometry";this.indices=[];this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1};
+THREE.DirectGeometry.prototype={constructor:THREE.DirectGeometry,computeBoundingBox:THREE.Geometry.prototype.computeBoundingBox,computeBoundingSphere:THREE.Geometry.prototype.computeBoundingSphere,computeFaceNormals:function(){console.warn("THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.")},computeVertexNormals:function(){console.warn("THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.")},computeGroups:function(a){var b,c=[],
+d;a=a.faces;for(var e=0;e<a.length;e++){var g=a[e];g.materialIndex!==d&&(d=g.materialIndex,void 0!==b&&(b.count=3*e-b.start,c.push(b)),b={start:3*e,materialIndex:d})}void 0!==b&&(b.count=3*e-b.start,c.push(b));this.groups=c},fromGeometry:function(a){var b=a.faces,c=a.vertices,d=a.faceVertexUvs,e=d[0]&&0<d[0].length,g=d[1]&&0<d[1].length,f=a.morphTargets,h=f.length;if(0<h){for(var k=[],l=0;l<h;l++)k[l]=[];this.morphTargets.position=k}var n=a.morphNormals,p=n.length;if(0<p){for(var m=[],l=0;l<p;l++)m[l]=
+[];this.morphTargets.normal=m}for(var q=a.skinIndices,t=a.skinWeights,r=q.length===c.length,v=t.length===c.length,l=0;l<b.length;l++){var w=b[l];this.vertices.push(c[w.a],c[w.b],c[w.c]);var u=w.vertexNormals;3===u.length?this.normals.push(u[0],u[1],u[2]):(u=w.normal,this.normals.push(u,u,u));u=w.vertexColors;3===u.length?this.colors.push(u[0],u[1],u[2]):(u=w.color,this.colors.push(u,u,u));!0===e&&(u=d[0][l],void 0!==u?this.uvs.push(u[0],u[1],u[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ",
+l),this.uvs.push(new THREE.Vector2,new THREE.Vector2,new THREE.Vector2)));!0===g&&(u=d[1][l],void 0!==u?this.uvs2.push(u[0],u[1],u[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ",l),this.uvs2.push(new THREE.Vector2,new THREE.Vector2,new THREE.Vector2)));for(u=0;u<h;u++){var z=f[u].vertices;k[u].push(z[w.a],z[w.b],z[w.c])}for(u=0;u<p;u++)z=n[u].vertexNormals[l],m[u].push(z.a,z.b,z.c);r&&this.skinIndices.push(q[w.a],q[w.b],q[w.c]);v&&this.skinWeights.push(t[w.a],t[w.b],
+t[w.c])}this.computeGroups(a);this.verticesNeedUpdate=a.verticesNeedUpdate;this.normalsNeedUpdate=a.normalsNeedUpdate;this.colorsNeedUpdate=a.colorsNeedUpdate;this.uvsNeedUpdate=a.uvsNeedUpdate;this.groupsNeedUpdate=a.groupsNeedUpdate;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.DirectGeometry.prototype);
+THREE.BufferGeometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null};
 THREE.BufferGeometry.prototype={constructor:THREE.BufferGeometry,addIndex:function(a){this.index=a},addAttribute:function(a,b,c){!1===b instanceof THREE.BufferAttribute&&!1===b instanceof THREE.InterleavedBufferAttribute?(console.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),this.addAttribute(a,new THREE.BufferAttribute(b,c))):("index"===a&&(console.warn("THREE.BufferGeometry.addAttribute: Use .addIndex() for index attribute."),this.addIndex(b)),this.attributes[a]=
 b)},getAttribute:function(a){return this.attributes[a]},removeAttribute:function(a){delete this.attributes[a]},get drawcalls(){console.error("THREE.BufferGeometry: .drawcalls has been renamed to .groups.");return this.groups},get offsets(){console.warn("THREE.BufferGeometry: .offsets has been renamed to .groups.");return this.groups},addDrawCall:function(a,b,c){void 0!==c&&console.warn("THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.");console.warn("THREE.BufferGeometry: .addDrawCall() is now .addGroup().");
 this.addGroup(a,b)},clearDrawCalls:function(){console.warn("THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().");this.clearGroups()},addGroup:function(a,b,c){this.groups.push({start:a,count:b,materialIndex:void 0!==c?c:0})},clearGroups:function(){this.groups=[]},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=
@@ -237,27 +234,23 @@ this.addGroup(a,b)},clearDrawCalls:function(){console.warn("THREE.BufferGeometry
 translate:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeTranslation(b,c,d);this.applyMatrix(a);return this}}(),scale:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeScale(b,c,d);this.applyMatrix(a);return this}}(),lookAt:function(){var a;return function(b){void 0===a&&(a=new THREE.Object3D);a.lookAt(b);a.updateMatrix();this.applyMatrix(a.matrix)}}(),center:function(){this.computeBoundingBox();var a=this.boundingBox.center().negate();
 this.translate(a.x,a.y,a.z);return a},setFromObject:function(a){var b=a.geometry;if(a instanceof THREE.PointCloud||a instanceof THREE.Line){a=new THREE.Float32Attribute(3*b.vertices.length,3);var c=new THREE.Float32Attribute(3*b.colors.length,3);this.addAttribute("position",a.copyVector3sArray(b.vertices));this.addAttribute("color",c.copyColorsArray(b.colors));b.lineDistances&&b.lineDistances.length===b.vertices.length&&(a=new THREE.Float32Attribute(b.lineDistances.length,1),this.addAttribute("lineDistance",
 a.copyArray(b.lineDistances)));null!==b.boundingSphere&&(this.boundingSphere=b.boundingSphere.clone());null!==b.boundingBox&&(this.boundingBox=b.boundingBox.clone())}else a instanceof THREE.Mesh&&b instanceof THREE.Geometry&&this.fromGeometry(b);return this},updateFromObject:function(a){var b=a.geometry;if(a instanceof THREE.Mesh){var c=b.__directGeometry;if(void 0===c)return this.fromGeometry(b);c.verticesNeedUpdate=b.verticesNeedUpdate;c.normalsNeedUpdate=b.normalsNeedUpdate;c.colorsNeedUpdate=
-b.colorsNeedUpdate;c.uvsNeedUpdate=b.uvsNeedUpdate;c.tangentsNeedUpdate=b.tangentsNeedUpdate;c.groupsNeedUpdate=b.groupsNeedUpdate;b.verticesNeedUpdate=!1;b.normalsNeedUpdate=!1;b.colorsNeedUpdate=!1;b.uvsNeedUpdate=!1;b.tangentsNeedUpdate=!1;b.groupsNeedUpdate=!1;b=c}!0===b.verticesNeedUpdate&&(c=this.attributes.position,void 0!==c&&(c.copyVector3sArray(b.vertices),c.needsUpdate=!0),b.verticesNeedUpdate=!1);!0===b.normalsNeedUpdate&&(c=this.attributes.normal,void 0!==c&&(c.copyVector3sArray(b.normals),
-c.needsUpdate=!0),b.normalsNeedUpdate=!1);!0===b.colorsNeedUpdate&&(c=this.attributes.color,void 0!==c&&(c.copyColorsArray(b.colors),c.needsUpdate=!0),b.colorsNeedUpdate=!1);!0===b.tangentsNeedUpdate&&(c=this.attributes.tangent,void 0!==c&&(c.copyVector4sArray(b.tangents),c.needsUpdate=!0),b.tangentsNeedUpdate=!1);b.lineDistancesNeedUpdate&&(c=this.attributes.lineDistance,void 0!==c&&(c.copyArray(b.lineDistances),c.needsUpdate=!0),b.lineDistancesNeedUpdate=!1);b.groupsNeedUpdate&&(b.computeGroups(a.geometry),
-this.groups=b.groups,b.groupsNeedUpdate=!1);return this},fromGeometry:function(a){a.__directGeometry=(new THREE.DirectGeometry).fromGeometry(a);return this.fromDirectGeometry(a.__directGeometry)},fromDirectGeometry:function(a){var b=new Float32Array(3*a.vertices.length);this.addAttribute("position",(new THREE.BufferAttribute(b,3)).copyVector3sArray(a.vertices));0<a.normals.length&&(b=new Float32Array(3*a.normals.length),this.addAttribute("normal",(new THREE.BufferAttribute(b,3)).copyVector3sArray(a.normals)));
-0<a.colors.length&&(b=new Float32Array(3*a.colors.length),this.addAttribute("color",(new THREE.BufferAttribute(b,3)).copyColorsArray(a.colors)));0<a.uvs.length&&(b=new Float32Array(2*a.uvs.length),this.addAttribute("uv",(new THREE.BufferAttribute(b,2)).copyVector2sArray(a.uvs)));0<a.uvs2.length&&(b=new Float32Array(2*a.uvs2.length),this.addAttribute("uv2",(new THREE.BufferAttribute(b,2)).copyVector2sArray(a.uvs2)));0<a.tangents.length&&(b=new Float32Array(4*a.tangents.length),this.addAttribute("tangent",
-(new THREE.BufferAttribute(b,4)).copyVector4sArray(a.tangents)));0<a.indices.length&&(b=new (65535<a.vertices.length?Uint32Array:Uint16Array)(3*a.indices.length),this.addIndex((new THREE.BufferAttribute(b,1)).copyIndicesArray(a.indices)));this.groups=a.groups;for(var c in a.morphTargets){for(var b=[],d=a.morphTargets[c],e=0,g=d.length;e<g;e++){var f=d[e],h=new THREE.Float32Attribute(3*f.length,3);b.push(h.copyVector3sArray(f))}this.morphAttributes[c]=b}0<a.skinIndices.length&&(c=new THREE.Float32Attribute(4*
-a.skinIndices.length,4),this.addAttribute("skinIndex",c.copyVector4sArray(a.skinIndices)));0<a.skinWeights.length&&(c=new THREE.Float32Attribute(4*a.skinWeights.length,4),this.addAttribute("skinWeight",c.copyVector4sArray(a.skinWeights)));null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());return this},computeBoundingBox:function(){var a=new THREE.Vector3;return function(){null===this.boundingBox&&(this.boundingBox=
-new THREE.Box3);var b=this.attributes.position.array;if(b){var c=this.boundingBox;c.makeEmpty();for(var d=0,e=b.length;d<e;d+=3)a.fromArray(b,d),c.expandByPoint(a)}if(void 0===b||0===b.length)this.boundingBox.min.set(0,0,0),this.boundingBox.max.set(0,0,0);(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.',this)}}(),
-computeBoundingSphere:function(){var a=new THREE.Box3,b=new THREE.Vector3;return function(){null===this.boundingSphere&&(this.boundingSphere=new THREE.Sphere);var c=this.attributes.position.array;if(c){a.makeEmpty();for(var d=this.boundingSphere.center,e=0,g=c.length;e<g;e+=3)b.fromArray(c,e),a.expandByPoint(b);a.center(d);for(var f=0,e=0,g=c.length;e<g;e+=3)b.fromArray(c,e),f=Math.max(f,d.distanceToSquared(b));this.boundingSphere.radius=Math.sqrt(f);isNaN(this.boundingSphere.radius)&&console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.',
-this)}}}(),computeFaceNormals:function(){},computeVertexNormals:function(){var a=this.index,b=this.attributes,c=this.groups;if(b.position){var d=b.position.array;if(void 0===b.normal)this.addAttribute("normal",new THREE.BufferAttribute(new Float32Array(d.length),3));else for(var e=b.normal.array,g=0,f=e.length;g<f;g++)e[g]=0;var e=b.normal.array,h,k,l,n=new THREE.Vector3,p=new THREE.Vector3,m=new THREE.Vector3,q=new THREE.Vector3,s=new THREE.Vector3;if(a){a=a.array;0===c.length&&this.addGroup(0,a.length);
-for(var r=0,u=c.length;r<u;++r)for(g=c[r],f=g.start,h=g.count,g=f,f+=h;g<f;g+=3)h=3*a[g+0],k=3*a[g+1],l=3*a[g+2],n.fromArray(d,h),p.fromArray(d,k),m.fromArray(d,l),q.subVectors(m,p),s.subVectors(n,p),q.cross(s),e[h]+=q.x,e[h+1]+=q.y,e[h+2]+=q.z,e[k]+=q.x,e[k+1]+=q.y,e[k+2]+=q.z,e[l]+=q.x,e[l+1]+=q.y,e[l+2]+=q.z}else for(g=0,f=d.length;g<f;g+=9)n.fromArray(d,g),p.fromArray(d,g+3),m.fromArray(d,g+6),q.subVectors(m,p),s.subVectors(n,p),q.cross(s),e[g]=q.x,e[g+1]=q.y,e[g+2]=q.z,e[g+3]=q.x,e[g+4]=q.y,
-e[g+5]=q.z,e[g+6]=q.x,e[g+7]=q.y,e[g+8]=q.z;this.normalizeNormals();b.normal.needsUpdate=!0}},computeTangents:function(){function a(a,b,c){p.fromArray(d,3*a);m.fromArray(d,3*b);q.fromArray(d,3*c);s.fromArray(g,2*a);r.fromArray(g,2*b);u.fromArray(g,2*c);x=m.x-p.x;v=q.x-p.x;y=m.y-p.y;w=q.y-p.y;G=m.z-p.z;B=q.z-p.z;z=r.x-s.x;A=u.x-s.x;O=r.y-s.y;K=u.y-s.y;D=1/(z*K-A*O);P.set((K*x-O*v)*D,(K*y-O*w)*D,(K*G-O*B)*D);J.set((z*v-A*x)*D,(z*w-A*y)*D,(z*B-A*G)*D);k[a].add(P);k[b].add(P);k[c].add(P);l[a].add(J);
-l[b].add(J);l[c].add(J)}function b(a){E.fromArray(e,3*a);ha.copy(E);ia=k[a];Q.copy(ia);Q.sub(E.multiplyScalar(E.dot(ia))).normalize();S.crossVectors(ha,ia);za=S.dot(l[a]);X=0>za?-1:1;h[4*a]=Q.x;h[4*a+1]=Q.y;h[4*a+2]=Q.z;h[4*a+3]=X}if(void 0===this.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.index.array,
-d=this.attributes.position.array,e=this.attributes.normal.array,g=this.attributes.uv.array,f=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*f),4));for(var h=this.attributes.tangent.array,k=[],l=[],n=0;n<f;n++)k[n]=new THREE.Vector3,l[n]=new THREE.Vector3;var p=new THREE.Vector3,m=new THREE.Vector3,q=new THREE.Vector3,s=new THREE.Vector2,r=new THREE.Vector2,u=new THREE.Vector2,x,v,y,w,G,B,z,A,O,K,D,P=new THREE.Vector3,J=new THREE.Vector3,
-H,C,F,N,R;0===this.groups.length&&this.addGroup(0,c.length);for(var U=this.groups,f=0,n=U.length;f<n;++f)for(H=U[f],C=H.start,F=H.count,H=C,C+=F;H<C;H+=3)F=c[H+0],N=c[H+1],R=c[H+2],a(F,N,R);for(var Q=new THREE.Vector3,S=new THREE.Vector3,E=new THREE.Vector3,ha=new THREE.Vector3,X,ia,za,f=0,n=U.length;f<n;++f)for(H=U[f],C=H.start,F=H.count,H=C,C+=F;H<C;H+=3)F=c[H+0],N=c[H+1],R=c[H+2],b(F),b(N),b(R)}},computeOffsets:function(a){console.warn("THREE.BufferGeometry: .computeOffsets() has been removed.")},
+b.colorsNeedUpdate;c.uvsNeedUpdate=b.uvsNeedUpdate;c.groupsNeedUpdate=b.groupsNeedUpdate;b.verticesNeedUpdate=!1;b.normalsNeedUpdate=!1;b.colorsNeedUpdate=!1;b.uvsNeedUpdate=!1;b.groupsNeedUpdate=!1;b=c}!0===b.verticesNeedUpdate&&(c=this.attributes.position,void 0!==c&&(c.copyVector3sArray(b.vertices),c.needsUpdate=!0),b.verticesNeedUpdate=!1);!0===b.normalsNeedUpdate&&(c=this.attributes.normal,void 0!==c&&(c.copyVector3sArray(b.normals),c.needsUpdate=!0),b.normalsNeedUpdate=!1);!0===b.colorsNeedUpdate&&
+(c=this.attributes.color,void 0!==c&&(c.copyColorsArray(b.colors),c.needsUpdate=!0),b.colorsNeedUpdate=!1);b.lineDistancesNeedUpdate&&(c=this.attributes.lineDistance,void 0!==c&&(c.copyArray(b.lineDistances),c.needsUpdate=!0),b.lineDistancesNeedUpdate=!1);b.groupsNeedUpdate&&(b.computeGroups(a.geometry),this.groups=b.groups,b.groupsNeedUpdate=!1);return this},fromGeometry:function(a){a.__directGeometry=(new THREE.DirectGeometry).fromGeometry(a);return this.fromDirectGeometry(a.__directGeometry)},
+fromDirectGeometry:function(a){var b=new Float32Array(3*a.vertices.length);this.addAttribute("position",(new THREE.BufferAttribute(b,3)).copyVector3sArray(a.vertices));0<a.normals.length&&(b=new Float32Array(3*a.normals.length),this.addAttribute("normal",(new THREE.BufferAttribute(b,3)).copyVector3sArray(a.normals)));0<a.colors.length&&(b=new Float32Array(3*a.colors.length),this.addAttribute("color",(new THREE.BufferAttribute(b,3)).copyColorsArray(a.colors)));0<a.uvs.length&&(b=new Float32Array(2*
+a.uvs.length),this.addAttribute("uv",(new THREE.BufferAttribute(b,2)).copyVector2sArray(a.uvs)));0<a.uvs2.length&&(b=new Float32Array(2*a.uvs2.length),this.addAttribute("uv2",(new THREE.BufferAttribute(b,2)).copyVector2sArray(a.uvs2)));0<a.indices.length&&(b=new (65535<a.vertices.length?Uint32Array:Uint16Array)(3*a.indices.length),this.addIndex((new THREE.BufferAttribute(b,1)).copyIndicesArray(a.indices)));this.groups=a.groups;for(var c in a.morphTargets){for(var b=[],d=a.morphTargets[c],e=0,g=d.length;e<
+g;e++){var f=d[e],h=new THREE.Float32Attribute(3*f.length,3);b.push(h.copyVector3sArray(f))}this.morphAttributes[c]=b}0<a.skinIndices.length&&(c=new THREE.Float32Attribute(4*a.skinIndices.length,4),this.addAttribute("skinIndex",c.copyVector4sArray(a.skinIndices)));0<a.skinWeights.length&&(c=new THREE.Float32Attribute(4*a.skinWeights.length,4),this.addAttribute("skinWeight",c.copyVector4sArray(a.skinWeights)));null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());null!==a.boundingBox&&
+(this.boundingBox=a.boundingBox.clone());return this},computeBoundingBox:function(){var a=new THREE.Vector3;return function(){null===this.boundingBox&&(this.boundingBox=new THREE.Box3);var b=this.attributes.position.array;if(b){var c=this.boundingBox;c.makeEmpty();for(var d=0,e=b.length;d<e;d+=3)a.fromArray(b,d),c.expandByPoint(a)}if(void 0===b||0===b.length)this.boundingBox.min.set(0,0,0),this.boundingBox.max.set(0,0,0);(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.',this)}}(),computeBoundingSphere:function(){var a=new THREE.Box3,b=new THREE.Vector3;return function(){null===this.boundingSphere&&(this.boundingSphere=new THREE.Sphere);var c=this.attributes.position.array;if(c){a.makeEmpty();for(var d=this.boundingSphere.center,e=0,g=c.length;e<g;e+=3)b.fromArray(c,e),a.expandByPoint(b);a.center(d);for(var f=0,e=0,g=c.length;e<
+g;e+=3)b.fromArray(c,e),f=Math.max(f,d.distanceToSquared(b));this.boundingSphere.radius=Math.sqrt(f);isNaN(this.boundingSphere.radius)&&console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.',this)}}}(),computeFaceNormals:function(){},computeVertexNormals:function(){var a=this.index,b=this.attributes,c=this.groups;if(b.position){var d=b.position.array;if(void 0===b.normal)this.addAttribute("normal",new THREE.BufferAttribute(new Float32Array(d.length),
+3));else for(var e=b.normal.array,g=0,f=e.length;g<f;g++)e[g]=0;var e=b.normal.array,h,k,l,n=new THREE.Vector3,p=new THREE.Vector3,m=new THREE.Vector3,q=new THREE.Vector3,t=new THREE.Vector3;if(a){a=a.array;0===c.length&&this.addGroup(0,a.length);for(var r=0,v=c.length;r<v;++r)for(g=c[r],f=g.start,h=g.count,g=f,f+=h;g<f;g+=3)h=3*a[g+0],k=3*a[g+1],l=3*a[g+2],n.fromArray(d,h),p.fromArray(d,k),m.fromArray(d,l),q.subVectors(m,p),t.subVectors(n,p),q.cross(t),e[h]+=q.x,e[h+1]+=q.y,e[h+2]+=q.z,e[k]+=q.x,
+e[k+1]+=q.y,e[k+2]+=q.z,e[l]+=q.x,e[l+1]+=q.y,e[l+2]+=q.z}else for(g=0,f=d.length;g<f;g+=9)n.fromArray(d,g),p.fromArray(d,g+3),m.fromArray(d,g+6),q.subVectors(m,p),t.subVectors(n,p),q.cross(t),e[g]=q.x,e[g+1]=q.y,e[g+2]=q.z,e[g+3]=q.x,e[g+4]=q.y,e[g+5]=q.z,e[g+6]=q.x,e[g+7]=q.y,e[g+8]=q.z;this.normalizeNormals();b.normal.needsUpdate=!0}},computeTangents:function(){console.warn("THREE.BufferGeometry: .computeTangents() has been removed.")},computeOffsets:function(a){console.warn("THREE.BufferGeometry: .computeOffsets() has been removed.")},
 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,g=a.attributes[d],f=g.array,h=0,g=g.itemSize*b;h<f.length;h++,g++)e[g]=f[h];return this}},normalizeNormals:function(){for(var a=this.attributes.normal.array,b,c,d,e=0,g=a.length;e<g;e+=3)b=a[e],c=a[e+1],d=a[e+2],b=1/Math.sqrt(b*b+c*c+
-d*d),a[e]*=b,a[e+1]*=b,a[e+2]*=b},toJSON:function(){var a={metadata:{version:4.4,type:"BufferGeometry",generator:"BufferGeometry.toJSON"}};a.uuid=this.uuid;a.type=this.type;""!==this.name&&(a.name=this.name);if(void 0!==this.parameters){var b=this.parameters,c;for(c in b)void 0!==b[c]&&(a[c]=b[c]);return a}a.data={attributes:{}};var b=this.attributes,d=this.groups,e=this.boundingSphere;for(c in b){var g=b[c],f=Array.prototype.slice.call(g.array);a.data.attributes[c]={itemSize:g.itemSize,type:g.array.constructor.name,
-array:f}}0<d.length&&(a.data.groups=JSON.parse(JSON.stringify(d)));null!==e&&(a.data.boundingSphere={center:e.center.toArray(),radius:e.radius});return a},clone:function(){return(new this.constructor).copy(this)},copy:function(a){var b=a.index;null!==b&&this.addIndex(b.clone());var b=a.attributes,c;for(c in b)this.addAttribute(c,b[c].clone());a=a.groups;c=0;for(b=a.length;c<b;c++){var d=a[c];this.addGroup(d.start,d.count)}return this},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.BufferGeometry.prototype);
-THREE.BufferGeometry.MaxIndex=65535;THREE.InstancedBufferGeometry=function(){THREE.BufferGeometry.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0};THREE.InstancedBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.InstancedBufferGeometry.prototype.constructor=THREE.InstancedBufferGeometry;THREE.InstancedBufferGeometry.prototype.addGroup=function(a,b,c){this.groups.push({start:a,count:b,instances:c})};
-THREE.InstancedBufferGeometry.prototype.copy=function(a){var b=a.index;null!==b&&this.addIndex(b.clone());var b=a.attributes,c;for(c in b)this.addAttribute(c,b[c].clone());a=a.groups;c=0;for(b=a.length;c<b;c++){var d=a[c];this.addGroup(d.start,d.count,d.instances)}return this};THREE.EventDispatcher.prototype.apply(THREE.InstancedBufferGeometry.prototype);THREE.Camera=function(){THREE.Object3D.call(this);this.type="Camera";this.matrixWorldInverse=new THREE.Matrix4;this.projectionMatrix=new THREE.Matrix4};
-THREE.Camera.prototype=Object.create(THREE.Object3D.prototype);THREE.Camera.prototype.constructor=THREE.Camera;THREE.Camera.prototype.getWorldDirection=function(){var a=new THREE.Quaternion;return function(b){b=b||new THREE.Vector3;this.getWorldQuaternion(a);return b.set(0,0,-1).applyQuaternion(a)}}();THREE.Camera.prototype.lookAt=function(){var a=new THREE.Matrix4;return function(b){a.lookAt(this.position,b,this.up);this.quaternion.setFromRotationMatrix(a)}}();THREE.Camera.prototype.clone=function(){return(new this.constructor).copy(this)};
-THREE.Camera.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a);this.matrixWorldInverse.copy(a.matrixWorldInverse);this.projectionMatrix.copy(a.projectionMatrix);return this};
+d*d),a[e]*=b,a[e+1]*=b,a[e+2]*=b},toJSON:function(){var a={metadata:{version:4.4,type:"BufferGeometry",generator:"BufferGeometry.toJSON"}};a.uuid=this.uuid;a.type=this.type;""!==this.name&&(a.name=this.name);if(void 0!==this.parameters){var b=this.parameters,c;for(c in b)void 0!==b[c]&&(a[c]=b[c]);return a}a.data={attributes:{}};var d=this.index;null!==d&&(b=Array.prototype.slice.call(d.array),a.data.index={type:d.array.constructor.name,array:b});d=this.attributes;for(c in d){var e=d[c],b=Array.prototype.slice.call(e.array);
+a.data.attributes[c]={itemSize:e.itemSize,type:e.array.constructor.name,array:b}}c=this.groups;0<c.length&&(a.data.groups=JSON.parse(JSON.stringify(c)));c=this.boundingSphere;null!==c&&(a.data.boundingSphere={center:c.center.toArray(),radius:c.radius});return a},clone:function(){return(new this.constructor).copy(this)},copy:function(a){var b=a.index;null!==b&&this.addIndex(b.clone());var b=a.attributes,c;for(c in b)this.addAttribute(c,b[c].clone());a=a.groups;c=0;for(b=a.length;c<b;c++){var d=a[c];
+this.addGroup(d.start,d.count)}return this},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.BufferGeometry.prototype);THREE.BufferGeometry.MaxIndex=65535;THREE.InstancedBufferGeometry=function(){THREE.BufferGeometry.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0};THREE.InstancedBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.InstancedBufferGeometry.prototype.constructor=THREE.InstancedBufferGeometry;
+THREE.InstancedBufferGeometry.prototype.addGroup=function(a,b,c){this.groups.push({start:a,count:b,instances:c})};THREE.InstancedBufferGeometry.prototype.copy=function(a){var b=a.index;null!==b&&this.addIndex(b.clone());var b=a.attributes,c;for(c in b)this.addAttribute(c,b[c].clone());a=a.groups;c=0;for(b=a.length;c<b;c++){var d=a[c];this.addGroup(d.start,d.count,d.instances)}return this};THREE.EventDispatcher.prototype.apply(THREE.InstancedBufferGeometry.prototype);
+THREE.Camera=function(){THREE.Object3D.call(this);this.type="Camera";this.matrixWorldInverse=new THREE.Matrix4;this.projectionMatrix=new THREE.Matrix4};THREE.Camera.prototype=Object.create(THREE.Object3D.prototype);THREE.Camera.prototype.constructor=THREE.Camera;THREE.Camera.prototype.getWorldDirection=function(){var a=new THREE.Quaternion;return function(b){b=b||new THREE.Vector3;this.getWorldQuaternion(a);return b.set(0,0,-1).applyQuaternion(a)}}();
+THREE.Camera.prototype.lookAt=function(){var a=new THREE.Matrix4;return function(b){a.lookAt(this.position,b,this.up);this.quaternion.setFromRotationMatrix(a)}}();THREE.Camera.prototype.clone=function(){return(new this.constructor).copy(this)};THREE.Camera.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a);this.matrixWorldInverse.copy(a.matrixWorldInverse);this.projectionMatrix.copy(a.projectionMatrix);return this};
 THREE.CubeCamera=function(a,b,c){THREE.Object3D.call(this);this.type="CubeCamera";var d=new THREE.PerspectiveCamera(90,1,a,b);d.up.set(0,-1,0);d.lookAt(new THREE.Vector3(1,0,0));this.add(d);var e=new THREE.PerspectiveCamera(90,1,a,b);e.up.set(0,-1,0);e.lookAt(new THREE.Vector3(-1,0,0));this.add(e);var g=new THREE.PerspectiveCamera(90,1,a,b);g.up.set(0,0,1);g.lookAt(new THREE.Vector3(0,1,0));this.add(g);var f=new THREE.PerspectiveCamera(90,1,a,b);f.up.set(0,0,-1);f.lookAt(new THREE.Vector3(0,-1,0));
 this.add(f);var h=new THREE.PerspectiveCamera(90,1,a,b);h.up.set(0,-1,0);h.lookAt(new THREE.Vector3(0,0,1));this.add(h);var k=new THREE.PerspectiveCamera(90,1,a,b);k.up.set(0,-1,0);k.lookAt(new THREE.Vector3(0,0,-1));this.add(k);this.renderTarget=new THREE.WebGLRenderTargetCube(c,c,{format:THREE.RGBFormat,magFilter:THREE.LinearFilter,minFilter:THREE.LinearFilter});this.updateCubeMap=function(a,b){null===this.parent&&this.updateMatrixWorld();var c=this.renderTarget,m=c.generateMipmaps;c.generateMipmaps=
 !1;c.activeCubeFace=0;a.render(b,d,c);c.activeCubeFace=1;a.render(b,e,c);c.activeCubeFace=2;a.render(b,g,c);c.activeCubeFace=3;a.render(b,f,c);c.activeCubeFace=4;a.render(b,h,c);c.generateMipmaps=m;c.activeCubeFace=5;a.render(b,k,c);a.setRenderTarget(null)}};THREE.CubeCamera.prototype=Object.create(THREE.Object3D.prototype);THREE.CubeCamera.prototype.constructor=THREE.CubeCamera;
@@ -268,9 +261,7 @@ THREE.PerspectiveCamera.prototype=Object.create(THREE.Camera.prototype);THREE.Pe
 THREE.PerspectiveCamera.prototype.updateProjectionMatrix=function(){var a=THREE.Math.radToDeg(2*Math.atan(Math.tan(.5*THREE.Math.degToRad(this.fov))/this.zoom));if(this.fullWidth){var b=this.fullWidth/this.fullHeight,a=Math.tan(THREE.Math.degToRad(.5*a))*this.near,c=-a,d=b*c,b=Math.abs(b*a-d),c=Math.abs(a-c);this.projectionMatrix.makeFrustum(d+this.x*b/this.fullWidth,d+(this.x+this.width)*b/this.fullWidth,a-(this.y+this.height)*c/this.fullHeight,a-this.y*c/this.fullHeight,this.near,this.far)}else this.projectionMatrix.makePerspective(a,
 this.aspect,this.near,this.far)};THREE.PerspectiveCamera.prototype.copy=function(a){THREE.Camera.prototype.copy.call(this,a);this.fov=a.fov;this.aspect=a.aspect;this.near=a.near;this.far=a.far;this.zoom=a.zoom;return this};THREE.PerspectiveCamera.prototype.toJSON=function(a){a=THREE.Object3D.prototype.toJSON.call(this,a);a.object.zoom=this.zoom;a.object.fov=this.fov;a.object.aspect=this.aspect;a.object.near=this.near;a.object.far=this.far;return a};
 THREE.Light=function(a){THREE.Object3D.call(this);this.type="Light";this.color=new THREE.Color(a)};THREE.Light.prototype=Object.create(THREE.Object3D.prototype);THREE.Light.prototype.constructor=THREE.Light;THREE.Light.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a);this.color.copy(a.color);return this};THREE.AmbientLight=function(a){THREE.Light.call(this,a);this.type="AmbientLight"};THREE.AmbientLight.prototype=Object.create(THREE.Light.prototype);
-THREE.AmbientLight.prototype.constructor=THREE.AmbientLight;THREE.AmbientLight.prototype.toJSON=function(a){a=THREE.Object3D.prototype.toJSON.call(this,a);a.object.color=this.color.getHex();return a};THREE.AreaLight=function(a,b){THREE.Light.call(this,a);this.type="AreaLight";this.normal=new THREE.Vector3(0,-1,0);this.right=new THREE.Vector3(1,0,0);this.intensity=void 0!==b?b:1;this.height=this.width=1;this.constantAttenuation=1.5;this.linearAttenuation=.5;this.quadraticAttenuation=.1};
-THREE.AreaLight.prototype=Object.create(THREE.Light.prototype);THREE.AreaLight.prototype.constructor=THREE.AreaLight;THREE.AreaLight.prototype.copy=function(a){THREE.Light.prototype.copy.call(this,a);this.intensity=a.intensity;this.normal.copy(a.normal);this.right.copy(a.right);this.width=a.width;this.height=a.height;this.constantAttenuation=a.constantAttenuation;this.linearAttenuation=a.linearAttenuation;this.quadraticAttenuation=a.quadraticAttenuation;return this};
-THREE.AreaLight.prototype.toJSON=function(a){a=THREE.Object3D.prototype.toJSON.call(this,a);a.object.color=this.color.getHex();a.object.intensity=this.intensity;return a};
+THREE.AmbientLight.prototype.constructor=THREE.AmbientLight;THREE.AmbientLight.prototype.toJSON=function(a){a=THREE.Object3D.prototype.toJSON.call(this,a);a.object.color=this.color.getHex();return a};
 THREE.DirectionalLight=function(a,b){THREE.Light.call(this,a);this.type="DirectionalLight";this.position.set(0,1,0);this.updateMatrix();this.target=new THREE.Object3D;this.intensity=void 0!==b?b:1;this.onlyShadow=this.castShadow=!1;this.shadowCameraNear=50;this.shadowCameraFar=5E3;this.shadowCameraLeft=-500;this.shadowCameraTop=this.shadowCameraRight=500;this.shadowCameraBottom=-500;this.shadowCameraVisible=!1;this.shadowBias=0;this.shadowDarkness=.5;this.shadowMapHeight=this.shadowMapWidth=512;this.shadowMatrix=
 this.shadowCamera=this.shadowMapSize=this.shadowMap=null};THREE.DirectionalLight.prototype=Object.create(THREE.Light.prototype);THREE.DirectionalLight.prototype.constructor=THREE.DirectionalLight;
 THREE.DirectionalLight.prototype.copy=function(a){THREE.Light.prototype.copy.call(this,a);this.intensity=a.intensity;this.target=a.target.clone();this.castShadow=a.castShadow;this.onlyShadow=a.onlyShadow;this.shadowCameraNear=a.shadowCameraNear;this.shadowCameraFar=a.shadowCameraFar;this.shadowCameraLeft=a.shadowCameraLeft;this.shadowCameraRight=a.shadowCameraRight;this.shadowCameraTop=a.shadowCameraTop;this.shadowCameraBottom=a.shadowCameraBottom;this.shadowCameraVisible=a.shadowCameraVisible;this.shadowBias=
@@ -283,30 +274,31 @@ this.shadowMapWidth=512;this.shadowMatrix=this.shadowCamera=this.shadowMapSize=t
 THREE.SpotLight.prototype.copy=function(a){THREE.Light.prototype.copy.call(this,a);this.intensity=a.intensity;this.distance=a.distance;this.angle=a.angle;this.exponent=a.exponent;this.decay=a.decay;this.target=a.target.clone();this.castShadow=a.castShadow;this.onlyShadow=a.onlyShadow;this.shadowCameraNear=a.shadowCameraNear;this.shadowCameraFar=a.shadowCameraFar;this.shadowCameraFov=a.shadowCameraFov;this.shadowCameraVisible=a.shadowCameraVisible;this.shadowBias=a.shadowBias;this.shadowDarkness=a.shadowDarkness;
 this.shadowMapWidth=a.shadowMapWidth;this.shadowMapHeight=a.shadowMapHeight;return this};THREE.SpotLight.prototype.toJSON=function(a){a=THREE.Object3D.prototype.toJSON.call(this,a);a.object.color=this.color.getHex();a.object.intensity=this.intensity;a.object.distance=this.distance;a.object.angle=this.angle;a.object.exponent=this.exponent;a.object.decay=this.decay;return a};
 THREE.Cache={enabled:!1,files:{},add:function(a,b){!1!==this.enabled&&(this.files[a]=b)},get:function(a){if(!1!==this.enabled)return this.files[a]},remove:function(a){delete this.files[a]},clear:function(){this.files={}}};THREE.Loader=function(){this.onLoadStart=function(){};this.onLoadProgress=function(){};this.onLoadComplete=function(){}};
-THREE.Loader.prototype={constructor:THREE.Loader,crossOrigin:void 0,extractUrlBase:function(a){a=a.split("/");if(1===a.length)return"./";a.pop();return a.join("/")+"/"},initMaterials:function(a,b,c){for(var d=[],e=0;e<a.length;++e)d[e]=this.createMaterial(a[e],b,c);return d},needsTangents:function(a){for(var b=0,c=a.length;b<c;b++)if(a[b]instanceof THREE.ShaderMaterial)return!0;return!1},createMaterial:function(){var a;return function(b,c,d){function e(a){a=Math.log(a)/Math.LN2;return Math.pow(2,
-Math.round(a))}function g(b,f,g,h,k,l,u){var x=c+g,v,y=THREE.Loader.Handlers.get(x);null!==y?v=y.load(x):(v=new THREE.Texture,y=a,y.setCrossOrigin(d),y.load(x,function(a){if(!1===THREE.Math.isPowerOfTwo(a.width)||!1===THREE.Math.isPowerOfTwo(a.height)){var b=e(a.width),c=e(a.height),d=document.createElement("canvas");d.width=b;d.height=c;d.getContext("2d").drawImage(a,0,0,b,c);v.image=d}else v.image=a;v.needsUpdate=!0}));v.sourceFile=g;h&&(v.repeat.set(h[0],h[1]),1!==h[0]&&(v.wrapS=THREE.RepeatWrapping),
-1!==h[1]&&(v.wrapT=THREE.RepeatWrapping));k&&v.offset.set(k[0],k[1]);l&&(g={repeat:THREE.RepeatWrapping,mirror:THREE.MirroredRepeatWrapping},void 0!==g[l[0]]&&(v.wrapS=g[l[0]]),void 0!==g[l[1]]&&(v.wrapT=g[l[1]]));u&&(v.anisotropy=u);b[f]=v}function f(a){return(255*a[0]<<16)+(255*a[1]<<8)+255*a[2]}void 0===d&&void 0!==this.crossOrigin&&(d=this.crossOrigin);void 0===a&&(a=new THREE.ImageLoader);var h="MeshLambertMaterial",k={color:15658734,opacity:1,map:null,lightMap:null,normalMap:null,bumpMap:null,
-wireframe:!1};if(b.shading){var l=b.shading.toLowerCase();"phong"===l?h="MeshPhongMaterial":"basic"===l&&(h="MeshBasicMaterial")}void 0!==b.blending&&void 0!==THREE[b.blending]&&(k.blending=THREE[b.blending]);void 0!==b.transparent&&(k.transparent=b.transparent);void 0!==b.opacity&&1>b.opacity&&(k.transparent=!0);void 0!==b.depthTest&&(k.depthTest=b.depthTest);void 0!==b.depthWrite&&(k.depthWrite=b.depthWrite);void 0!==b.visible&&(k.visible=b.visible);void 0!==b.flipSided&&(k.side=THREE.BackSide);
-void 0!==b.doubleSided&&(k.side=THREE.DoubleSide);void 0!==b.wireframe&&(k.wireframe=b.wireframe);void 0!==b.vertexColors&&("face"===b.vertexColors?k.vertexColors=THREE.FaceColors:b.vertexColors&&(k.vertexColors=THREE.VertexColors));b.colorDiffuse?k.color=f(b.colorDiffuse):b.DbgColor&&(k.color=b.DbgColor);b.colorSpecular&&(k.specular=f(b.colorSpecular));b.colorEmissive&&(k.emissive=f(b.colorEmissive));void 0!==b.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),
-b.opacity=b.transparency);void 0!==b.opacity&&(k.opacity=b.opacity);b.specularCoef&&(k.shininess=b.specularCoef);b.mapDiffuse&&c&&g(k,"map",b.mapDiffuse,b.mapDiffuseRepeat,b.mapDiffuseOffset,b.mapDiffuseWrap,b.mapDiffuseAnisotropy);b.mapLight&&c&&g(k,"lightMap",b.mapLight,b.mapLightRepeat,b.mapLightOffset,b.mapLightWrap,b.mapLightAnisotropy);b.mapAO&&c&&g(k,"aoMap",b.mapAO,b.mapAORepeat,b.mapAOOffset,b.mapAOWrap,b.mapAOAnisotropy);b.mapBump&&c&&g(k,"bumpMap",b.mapBump,b.mapBumpRepeat,b.mapBumpOffset,
-b.mapBumpWrap,b.mapBumpAnisotropy);b.mapNormal&&c&&g(k,"normalMap",b.mapNormal,b.mapNormalRepeat,b.mapNormalOffset,b.mapNormalWrap,b.mapNormalAnisotropy);b.mapSpecular&&c&&g(k,"specularMap",b.mapSpecular,b.mapSpecularRepeat,b.mapSpecularOffset,b.mapSpecularWrap,b.mapSpecularAnisotropy);b.mapAlpha&&c&&g(k,"alphaMap",b.mapAlpha,b.mapAlphaRepeat,b.mapAlphaOffset,b.mapAlphaWrap,b.mapAlphaAnisotropy);b.mapBumpScale&&(k.bumpScale=b.mapBumpScale);b.mapNormalFactor&&(k.normalScale=new THREE.Vector2(b.mapNormalFactor,
-b.mapNormalFactor));h=new THREE[h](k);void 0!==b.DbgName&&(h.name=b.DbgName);return h}}()};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<c;b+=2){var d=this.handlers[b+1];if(this.handlers[b].test(a))return d}return null}};THREE.XHRLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager};
-THREE.XHRLoader.prototype={constructor:THREE.XHRLoader,load:function(a,b,c,d){var e=this,g=THREE.Cache.get(a);if(void 0!==g)return b&&setTimeout(function(){b(g)},0),g;var f=new XMLHttpRequest;f.open("GET",a,!0);f.addEventListener("load",function(c){THREE.Cache.add(a,this.response);b&&b(this.response);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);
-void 0!==this.responseType&&(f.responseType=this.responseType);void 0!==this.withCredentials&&(f.withCredentials=this.withCredentials);f.send(null);e.manager.itemStart(a);return f},setResponseType:function(a){this.responseType=a},setCrossOrigin:function(a){this.crossOrigin=a},setWithCredentials:function(a){this.withCredentials=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,g=THREE.Cache.get(a);if(void 0!==g)return b&&setTimeout(function(){b(g)},0),g;var 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);e.manager.itemStart(a);
-f.src=a;return f},setCrossOrigin:function(a){this.crossOrigin=a}};THREE.JSONLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager;this.withCredentials=!1};
+THREE.Loader.prototype={constructor:THREE.Loader,crossOrigin:void 0,extractUrlBase:function(a){a=a.split("/");if(1===a.length)return"./";a.pop();return a.join("/")+"/"},initMaterials:function(a,b,c){for(var d=[],e=0;e<a.length;++e)d[e]=this.createMaterial(a[e],b,c);return d},createMaterial:function(){var a;return function(b,c,d){function e(a){a=Math.log(a)/Math.LN2;return Math.pow(2,Math.round(a))}function g(b,f,g,h,k,l,v){var w=c+g,u,z=THREE.Loader.Handlers.get(w);null!==z?u=z.load(w):(u=new THREE.Texture,
+z=a,z.setCrossOrigin(d),z.load(w,function(a){if(!1===THREE.Math.isPowerOfTwo(a.width)||!1===THREE.Math.isPowerOfTwo(a.height)){var b=e(a.width),c=e(a.height),d=document.createElement("canvas");d.width=b;d.height=c;d.getContext("2d").drawImage(a,0,0,b,c);u.image=d}else u.image=a;u.needsUpdate=!0}));u.sourceFile=g;h&&(u.repeat.set(h[0],h[1]),1!==h[0]&&(u.wrapS=THREE.RepeatWrapping),1!==h[1]&&(u.wrapT=THREE.RepeatWrapping));k&&u.offset.set(k[0],k[1]);l&&(g={repeat:THREE.RepeatWrapping,mirror:THREE.MirroredRepeatWrapping},
+void 0!==g[l[0]]&&(u.wrapS=g[l[0]]),void 0!==g[l[1]]&&(u.wrapT=g[l[1]]));v&&(u.anisotropy=v);b[f]=u}function f(a){return(255*a[0]<<16)+(255*a[1]<<8)+255*a[2]}void 0===d&&void 0!==this.crossOrigin&&(d=this.crossOrigin);void 0===a&&(a=new THREE.ImageLoader);var h="MeshLambertMaterial",k={color:15658734,opacity:1,map:null,lightMap:null,normalMap:null,bumpMap:null,wireframe:!1};if(b.shading){var l=b.shading.toLowerCase();"phong"===l?h="MeshPhongMaterial":"basic"===l&&(h="MeshBasicMaterial")}void 0!==
+b.blending&&void 0!==THREE[b.blending]&&(k.blending=THREE[b.blending]);void 0!==b.transparent&&(k.transparent=b.transparent);void 0!==b.opacity&&1>b.opacity&&(k.transparent=!0);void 0!==b.depthTest&&(k.depthTest=b.depthTest);void 0!==b.depthWrite&&(k.depthWrite=b.depthWrite);void 0!==b.visible&&(k.visible=b.visible);void 0!==b.flipSided&&(k.side=THREE.BackSide);void 0!==b.doubleSided&&(k.side=THREE.DoubleSide);void 0!==b.wireframe&&(k.wireframe=b.wireframe);void 0!==b.vertexColors&&("face"===b.vertexColors?
+k.vertexColors=THREE.FaceColors:b.vertexColors&&(k.vertexColors=THREE.VertexColors));b.colorDiffuse?k.color=f(b.colorDiffuse):b.DbgColor&&(k.color=b.DbgColor);b.colorSpecular&&(k.specular=f(b.colorSpecular));b.colorEmissive&&(k.emissive=f(b.colorEmissive));void 0!==b.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),b.opacity=b.transparency);void 0!==b.opacity&&(k.opacity=b.opacity);b.specularCoef&&(k.shininess=b.specularCoef);b.mapDiffuse&&c&&g(k,"map",b.mapDiffuse,
+b.mapDiffuseRepeat,b.mapDiffuseOffset,b.mapDiffuseWrap,b.mapDiffuseAnisotropy);b.mapLight&&c&&g(k,"lightMap",b.mapLight,b.mapLightRepeat,b.mapLightOffset,b.mapLightWrap,b.mapLightAnisotropy);b.mapAO&&c&&g(k,"aoMap",b.mapAO,b.mapAORepeat,b.mapAOOffset,b.mapAOWrap,b.mapAOAnisotropy);b.mapBump&&c&&g(k,"bumpMap",b.mapBump,b.mapBumpRepeat,b.mapBumpOffset,b.mapBumpWrap,b.mapBumpAnisotropy);b.mapNormal&&c&&g(k,"normalMap",b.mapNormal,b.mapNormalRepeat,b.mapNormalOffset,b.mapNormalWrap,b.mapNormalAnisotropy);
+b.mapSpecular&&c&&g(k,"specularMap",b.mapSpecular,b.mapSpecularRepeat,b.mapSpecularOffset,b.mapSpecularWrap,b.mapSpecularAnisotropy);b.mapAlpha&&c&&g(k,"alphaMap",b.mapAlpha,b.mapAlphaRepeat,b.mapAlphaOffset,b.mapAlphaWrap,b.mapAlphaAnisotropy);b.mapBumpScale&&(k.bumpScale=b.mapBumpScale);b.mapNormalFactor&&(k.normalScale=new THREE.Vector2(b.mapNormalFactor,b.mapNormalFactor));h=new THREE[h](k);void 0!==b.DbgName&&(h.name=b.DbgName);return h}}()};
+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<c;b+=2){var d=this.handlers[b+1];if(this.handlers[b].test(a))return d}return null}};THREE.XHRLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager};
+THREE.XHRLoader.prototype={constructor:THREE.XHRLoader,load:function(a,b,c,d){var e=this,g=THREE.Cache.get(a);if(void 0!==g)return b&&setTimeout(function(){b(g)},0),g;var f=new XMLHttpRequest;f.open("GET",a,!0);f.addEventListener("load",function(c){THREE.Cache.add(a,this.response);b&&b(this.response);e.manager.itemEnd(a)},!1);void 0!==c&&f.addEventListener("progress",function(a){c(a)},!1);f.addEventListener("error",function(b){d&&d(b);e.manager.itemError(a)},!1);void 0!==this.crossOrigin&&(f.crossOrigin=
+this.crossOrigin);void 0!==this.responseType&&(f.responseType=this.responseType);void 0!==this.withCredentials&&(f.withCredentials=this.withCredentials);f.send(null);e.manager.itemStart(a);return f},setResponseType:function(a){this.responseType=a},setCrossOrigin:function(a){this.crossOrigin=a},setWithCredentials:function(a){this.withCredentials=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,g=THREE.Cache.get(a);if(void 0!==g)return b&&setTimeout(function(){b(g)},0),g;var 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);f.addEventListener("error",function(b){d&&d(b);e.manager.itemError(a)},!1);void 0!==this.crossOrigin&&(f.crossOrigin=this.crossOrigin);
+e.manager.itemStart(a);f.src=a;return f},setCrossOrigin:function(a){this.crossOrigin=a}};THREE.JSONLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager;this.withCredentials=!1};
 THREE.JSONLoader.prototype={constructor:THREE.JSONLoader,load:function(a,b,c,d){var e=this,g=this.texturePath&&"string"===typeof this.texturePath?this.texturePath:THREE.Loader.prototype.extractUrlBase(a);c=new THREE.XHRLoader(this.manager);c.setCrossOrigin(this.crossOrigin);c.setWithCredentials(this.withCredentials);c.load(a,function(c){c=JSON.parse(c);var d=c.metadata;if(void 0!==d){if("object"===d.type){console.error("THREE.JSONLoader: "+a+" should be loaded with THREE.ObjectLoader instead.");return}if("scene"===
-d.type){console.error("THREE.JSONLoader: "+a+" should be loaded with THREE.SceneLoader instead.");return}}c=e.parse(c,g);b(c.geometry,c.materials)})},setCrossOrigin:function(a){this.crossOrigin=a},setTexturePath:function(a){this.texturePath=a},parse:function(a,b){var c=new THREE.Geometry,d=void 0!==a.scale?1/a.scale:1;(function(b){var d,f,h,k,l,n,p,m,q,s,r,u,x,v=a.faces;n=a.vertices;var y=a.normals,w=a.colors,G=0;if(void 0!==a.uvs){for(d=0;d<a.uvs.length;d++)a.uvs[d].length&&G++;for(d=0;d<G;d++)c.faceVertexUvs[d]=
-[]}k=0;for(l=n.length;k<l;)d=new THREE.Vector3,d.x=n[k++]*b,d.y=n[k++]*b,d.z=n[k++]*b,c.vertices.push(d);k=0;for(l=v.length;k<l;)if(b=v[k++],q=b&1,h=b&2,d=b&8,p=b&16,s=b&32,n=b&64,b&=128,q){q=new THREE.Face3;q.a=v[k];q.b=v[k+1];q.c=v[k+3];r=new THREE.Face3;r.a=v[k+1];r.b=v[k+2];r.c=v[k+3];k+=4;h&&(h=v[k++],q.materialIndex=h,r.materialIndex=h);h=c.faces.length;if(d)for(d=0;d<G;d++)for(u=a.uvs[d],c.faceVertexUvs[d][h]=[],c.faceVertexUvs[d][h+1]=[],f=0;4>f;f++)m=v[k++],x=u[2*m],m=u[2*m+1],x=new THREE.Vector2(x,
-m),2!==f&&c.faceVertexUvs[d][h].push(x),0!==f&&c.faceVertexUvs[d][h+1].push(x);p&&(p=3*v[k++],q.normal.set(y[p++],y[p++],y[p]),r.normal.copy(q.normal));if(s)for(d=0;4>d;d++)p=3*v[k++],s=new THREE.Vector3(y[p++],y[p++],y[p]),2!==d&&q.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);n&&(n=v[k++],n=w[n],q.color.setHex(n),r.color.setHex(n));if(b)for(d=0;4>d;d++)n=v[k++],n=w[n],2!==d&&q.vertexColors.push(new THREE.Color(n)),0!==d&&r.vertexColors.push(new THREE.Color(n));c.faces.push(q);c.faces.push(r)}else{q=
-new THREE.Face3;q.a=v[k++];q.b=v[k++];q.c=v[k++];h&&(h=v[k++],q.materialIndex=h);h=c.faces.length;if(d)for(d=0;d<G;d++)for(u=a.uvs[d],c.faceVertexUvs[d][h]=[],f=0;3>f;f++)m=v[k++],x=u[2*m],m=u[2*m+1],x=new THREE.Vector2(x,m),c.faceVertexUvs[d][h].push(x);p&&(p=3*v[k++],q.normal.set(y[p++],y[p++],y[p]));if(s)for(d=0;3>d;d++)p=3*v[k++],s=new THREE.Vector3(y[p++],y[p++],y[p]),q.vertexNormals.push(s);n&&(n=v[k++],q.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=v[k++],q.vertexColors.push(new THREE.Color(w[n]));
+d.type){console.error("THREE.JSONLoader: "+a+" should be loaded with THREE.SceneLoader instead.");return}}c=e.parse(c,g);b(c.geometry,c.materials)})},setCrossOrigin:function(a){this.crossOrigin=a},setTexturePath:function(a){this.texturePath=a},parse:function(a,b){var c=new THREE.Geometry,d=void 0!==a.scale?1/a.scale:1;(function(b){var d,f,h,k,l,n,p,m,q,t,r,v,w,u=a.faces;n=a.vertices;var z=a.normals,x=a.colors,D=0;if(void 0!==a.uvs){for(d=0;d<a.uvs.length;d++)a.uvs[d].length&&D++;for(d=0;d<D;d++)c.faceVertexUvs[d]=
+[]}k=0;for(l=n.length;k<l;)d=new THREE.Vector3,d.x=n[k++]*b,d.y=n[k++]*b,d.z=n[k++]*b,c.vertices.push(d);k=0;for(l=u.length;k<l;)if(b=u[k++],q=b&1,h=b&2,d=b&8,p=b&16,t=b&32,n=b&64,b&=128,q){q=new THREE.Face3;q.a=u[k];q.b=u[k+1];q.c=u[k+3];r=new THREE.Face3;r.a=u[k+1];r.b=u[k+2];r.c=u[k+3];k+=4;h&&(h=u[k++],q.materialIndex=h,r.materialIndex=h);h=c.faces.length;if(d)for(d=0;d<D;d++)for(v=a.uvs[d],c.faceVertexUvs[d][h]=[],c.faceVertexUvs[d][h+1]=[],f=0;4>f;f++)m=u[k++],w=v[2*m],m=v[2*m+1],w=new THREE.Vector2(w,
+m),2!==f&&c.faceVertexUvs[d][h].push(w),0!==f&&c.faceVertexUvs[d][h+1].push(w);p&&(p=3*u[k++],q.normal.set(z[p++],z[p++],z[p]),r.normal.copy(q.normal));if(t)for(d=0;4>d;d++)p=3*u[k++],t=new THREE.Vector3(z[p++],z[p++],z[p]),2!==d&&q.vertexNormals.push(t),0!==d&&r.vertexNormals.push(t);n&&(n=u[k++],n=x[n],q.color.setHex(n),r.color.setHex(n));if(b)for(d=0;4>d;d++)n=u[k++],n=x[n],2!==d&&q.vertexColors.push(new THREE.Color(n)),0!==d&&r.vertexColors.push(new THREE.Color(n));c.faces.push(q);c.faces.push(r)}else{q=
+new THREE.Face3;q.a=u[k++];q.b=u[k++];q.c=u[k++];h&&(h=u[k++],q.materialIndex=h);h=c.faces.length;if(d)for(d=0;d<D;d++)for(v=a.uvs[d],c.faceVertexUvs[d][h]=[],f=0;3>f;f++)m=u[k++],w=v[2*m],m=v[2*m+1],w=new THREE.Vector2(w,m),c.faceVertexUvs[d][h].push(w);p&&(p=3*u[k++],q.normal.set(z[p++],z[p++],z[p]));if(t)for(d=0;3>d;d++)p=3*u[k++],t=new THREE.Vector3(z[p++],z[p++],z[p]),q.vertexNormals.push(t);n&&(n=u[k++],q.color.setHex(x[n]));if(b)for(d=0;3>d;d++)n=u[k++],q.vertexColors.push(new THREE.Color(x[n]));
 c.faces.push(q)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,f=a.skinWeights.length;d<f;d+=b)c.skinWeights.push(new THREE.Vector4(a.skinWeights[d],1<b?a.skinWeights[d+1]:0,2<b?a.skinWeights[d+2]:0,3<b?a.skinWeights[d+3]:0));if(a.skinIndices)for(d=0,f=a.skinIndices.length;d<f;d+=b)c.skinIndices.push(new THREE.Vector4(a.skinIndices[d],1<b?a.skinIndices[d+1]:0,2<b?a.skinIndices[d+2]:0,3<b?a.skinIndices[d+3]:0));c.bones=a.bones;c.bones&&0<
 c.bones.length&&(c.skinWeights.length!==c.skinIndices.length||c.skinIndices.length!==c.vertices.length)&&console.warn("When skinning, number of vertices ("+c.vertices.length+"), skinIndices ("+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,f,h,k,l,n;d=0;for(f=a.morphTargets.length;d<f;d++)for(c.morphTargets[d]={},c.morphTargets[d].name=a.morphTargets[d].name,c.morphTargets[d].vertices=
 [],l=c.morphTargets[d].vertices,n=a.morphTargets[d].vertices,h=0,k=n.length;h<k;h+=3){var p=new THREE.Vector3;p.x=n[h]*b;p.y=n[h+1]*b;p.z=n[h+2]*b;l.push(p)}}if(void 0!==a.morphColors)for(d=0,f=a.morphColors.length;d<f;d++)for(c.morphColors[d]={},c.morphColors[d].name=a.morphColors[d].name,c.morphColors[d].colors=[],k=c.morphColors[d].colors,l=a.morphColors[d].colors,b=0,h=l.length;b<h;b+=3)n=new THREE.Color(16755200),n.setRGB(l[b],l[b+1],l[b+2]),k.push(n)})(d);c.computeFaceNormals();c.computeBoundingSphere();
-if(void 0===a.materials||0===a.materials.length)return{geometry:c};d=THREE.Loader.prototype.initMaterials(a.materials,b,this.crossOrigin);THREE.Loader.prototype.needsTangents(d)&&c.computeTangents();return{geometry:c,materials:d}}};
-THREE.LoadingManager=function(a,b,c){var d=this,e=!1,g=0,f=0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){f++;if(!1===e&&void 0!==d.onStart)d.onStart(a,g,f);e=!0};this.itemEnd=function(a){g++;if(void 0!==d.onProgress)d.onProgress(a,g,f);if(g===f&&(e=!1,void 0!==d.onLoad))d.onLoad()}};THREE.DefaultLoadingManager=new THREE.LoadingManager;THREE.BufferGeometryLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager};
-THREE.BufferGeometryLoader.prototype={constructor:THREE.BufferGeometryLoader,load:function(a,b,c,d){var e=this,g=new THREE.XHRLoader(e.manager);g.setCrossOrigin(this.crossOrigin);g.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.BufferGeometry,c=a.data.attributes,d;for(d in c){var e=c[d],g=new self[e.type](e.array);b.addAttribute(d,new THREE.BufferAttribute(g,e.itemSize))}c=a.data.groups||a.data.drawcalls||a.data.offsets;
-if(void 0!==c)for(d=0,e=c.length;d!==e;++d)g=c[d],b.addGroup(g.start,g.count);a=a.data.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};
+if(void 0===a.materials||0===a.materials.length)return{geometry:c};d=THREE.Loader.prototype.initMaterials(a.materials,b,this.crossOrigin);return{geometry:c,materials:d}}};
+THREE.LoadingManager=function(a,b,c){var d=this,e=!1,g=0,f=0;this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){f++;if(!1===e&&void 0!==d.onStart)d.onStart(a,g,f);e=!0};this.itemEnd=function(a){g++;if(void 0!==d.onProgress)d.onProgress(a,g,f);if(g===f&&(e=!1,void 0!==d.onLoad))d.onLoad()};this.itemError=function(a){if(void 0!==d.onError)d.onError(a)}};THREE.DefaultLoadingManager=new THREE.LoadingManager;
+THREE.BufferGeometryLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager};
+THREE.BufferGeometryLoader.prototype={constructor:THREE.BufferGeometryLoader,load:function(a,b,c,d){var e=this,g=new THREE.XHRLoader(e.manager);g.setCrossOrigin(this.crossOrigin);g.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.BufferGeometry,c=a.data.index;void 0!==c&&(c=new self[c.type](c.array),b.addIndex(new THREE.BufferAttribute(c,1)));var d=a.data.attributes,e;for(e in d){var g=d[e],c=new self[g.type](g.array);
+b.addAttribute(e,new THREE.BufferAttribute(c,g.itemSize))}e=a.data.groups||a.data.drawcalls||a.data.offsets;if(void 0!==e)for(c=0,d=e.length;c!==d;++c)g=e[c],b.addGroup(g.start,g.count);a=a.data.boundingSphere;void 0!==a&&(e=new THREE.Vector3,void 0!==a.center&&e.fromArray(a.center),b.boundingSphere=new THREE.Sphere(e,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,g=new THREE.XHRLoader(e.manager);g.setCrossOrigin(this.crossOrigin);g.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.attributes&&(b.attributes=a.attributes);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.alphaTest&&
 (b.alphaTest=a.alphaTest);void 0!==a.wireframe&&(b.wireframe=a.wireframe);void 0!==a.wireframeLinewidth&&(b.wireframeLinewidth=a.wireframeLinewidth);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<d;c++)b.materials.push(this.parse(a.materials[c]));return b}};THREE.ObjectLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager;this.texturePath=""};
@@ -314,17 +306,18 @@ THREE.ObjectLoader.prototype={constructor:THREE.ObjectLoader,load:function(a,b,c
 d=this.parseTextures(a.textures,d),d=this.parseMaterials(a.materials,d),e=this.parseObject(a.object,c,d);void 0!==a.images&&0!==a.images.length||void 0===b||b(e);return e},parseGeometries:function(a){var b={};if(void 0!==a)for(var c=new THREE.JSONLoader,d=new THREE.BufferGeometryLoader,e=0,g=a.length;e<g;e++){var f,h=a[e];switch(h.type){case "PlaneGeometry":case "PlaneBufferGeometry":f=new THREE[h.type](h.width,h.height,h.widthSegments,h.heightSegments);break;case "BoxGeometry":case "CubeGeometry":f=
 new THREE.BoxGeometry(h.width,h.height,h.depth,h.widthSegments,h.heightSegments,h.depthSegments);break;case "CircleBufferGeometry":f=new THREE.CircleBufferGeometry(h.radius,h.segments,h.thetaStart,h.thetaLength);break;case "CircleGeometry":f=new THREE.CircleGeometry(h.radius,h.segments,h.thetaStart,h.thetaLength);break;case "CylinderGeometry":f=new THREE.CylinderGeometry(h.radiusTop,h.radiusBottom,h.height,h.radialSegments,h.heightSegments,h.openEnded,h.thetaStart,h.thetaLength);break;case "SphereGeometry":f=
 new THREE.SphereGeometry(h.radius,h.widthSegments,h.heightSegments,h.phiStart,h.phiLength,h.thetaStart,h.thetaLength);break;case "SphereBufferGeometry":f=new THREE.SphereBufferGeometry(h.radius,h.widthSegments,h.heightSegments,h.phiStart,h.phiLength,h.thetaStart,h.thetaLength);break;case "DodecahedronGeometry":f=new THREE.DodecahedronGeometry(h.radius,h.detail);break;case "IcosahedronGeometry":f=new THREE.IcosahedronGeometry(h.radius,h.detail);break;case "OctahedronGeometry":f=new THREE.OctahedronGeometry(h.radius,
-h.detail);break;case "TetrahedronGeometry":f=new THREE.TetrahedronGeometry(h.radius,h.detail);break;case "RingGeometry":f=new THREE.RingGeometry(h.innerRadius,h.outerRadius,h.thetaSegments,h.phiSegments,h.thetaStart,h.thetaLength);break;case "TorusGeometry":f=new THREE.TorusGeometry(h.radius,h.tube,h.radialSegments,h.tubularSegments,h.arc);break;case "TorusKnotGeometry":f=new THREE.TorusKnotGeometry(h.radius,h.tube,h.radialSegments,h.tubularSegments,h.p,h.q,h.heightScale);break;case "BufferGeometry":f=
-d.parse(h);break;case "Geometry":f=c.parse(h.data,this.texturePath).geometry;break;case "TextGeometry":f=new THREE.TextGeometry(h.text,h.data)}f.uuid=h.uuid;void 0!==h.name&&(f.name=h.name);b[h.uuid]=f}return b},parseMaterials:function(a,b){var c={};if(void 0!==a)for(var d=function(a){void 0===b[a]&&console.warn("THREE.ObjectLoader: Undefined texture",a);return b[a]},e=new THREE.MaterialLoader,g=0,f=a.length;g<f;g++){var h=a[g],k=e.parse(h);k.uuid=h.uuid;void 0!==h.depthTest&&(k.depthTest=h.depthTest);
-void 0!==h.depthWrite&&(k.depthWrite=h.depthWrite);void 0!==h.name&&(k.name=h.name);void 0!==h.map&&(k.map=d(h.map));void 0!==h.alphaMap&&(k.alphaMap=d(h.alphaMap),k.transparent=!0);void 0!==h.bumpMap&&(k.bumpMap=d(h.bumpMap));void 0!==h.bumpScale&&(k.bumpScale=h.bumpScale);void 0!==h.normalMap&&(k.normalMap=d(h.normalMap));h.normalScale&&(k.normalScale=new THREE.Vector2(h.normalScale,h.normalScale));void 0!==h.specularMap&&(k.specularMap=d(h.specularMap));void 0!==h.envMap&&(k.envMap=d(h.envMap),
-k.combine=THREE.MultiplyOperation);h.reflectivity&&(k.reflectivity=h.reflectivity);void 0!==h.lightMap&&(k.lightMap=d(h.lightMap));void 0!==h.lightMapIntensity&&(k.lightMapIntensity=h.lightMapIntensity);void 0!==h.aoMap&&(k.aoMap=d(h.aoMap));void 0!==h.aoMapIntensity&&(k.aoMapIntensity=h.aoMapIntensity);c[h.uuid]=k}return c},parseImages:function(a,b){var c=this,d={};if(void 0!==a&&0<a.length){var e=new THREE.LoadingManager(b),g=new THREE.ImageLoader(e);g.setCrossOrigin(this.crossOrigin);for(var e=
-function(a){a=c.texturePath+a;c.manager.itemStart(a);return g.load(a,function(){c.manager.itemEnd(a)})},f=0,h=a.length;f<h;f++){var k=a[f];d[k.uuid]=e(k.url)}}return d},parseTextures:function(a,b){function c(a){if("number"===typeof a)return a;console.warn("THREE.ObjectLoader.parseTexture: Constant should be in numeric form.",a);return THREE[a]}var d={};if(void 0!==a)for(var e=0,g=a.length;e<g;e++){var f=a[e];void 0===f.image&&console.warn('THREE.ObjectLoader: No "image" specified for',f.uuid);void 0===
-b[f.image]&&console.warn("THREE.ObjectLoader: Undefined image",f.image);var h=new THREE.Texture(b[f.image]);h.needsUpdate=!0;h.uuid=f.uuid;void 0!==f.name&&(h.name=f.name);void 0!==f.mapping&&(h.mapping=c(f.mapping));void 0!==f.repeat&&(h.repeat=new THREE.Vector2(f.repeat[0],f.repeat[1]));void 0!==f.minFilter&&(h.minFilter=c(f.minFilter));void 0!==f.magFilter&&(h.magFilter=c(f.magFilter));void 0!==f.anisotropy&&(h.anisotropy=f.anisotropy);Array.isArray(f.wrap)&&(h.wrapS=c(f.wrap[0]),h.wrapT=c(f.wrap[1]));
-d[f.uuid]=h}return d},parseObject:function(){var a=new THREE.Matrix4;return function(b,c,d){var e;e=function(a){void 0===c[a]&&console.warn("THREE.ObjectLoader: Undefined geometry",a);return c[a]};var g=function(a){void 0===d[a]&&console.warn("THREE.ObjectLoader: Undefined material",a);return d[a]};switch(b.type){case "Scene":e=new THREE.Scene;break;case "PerspectiveCamera":e=new THREE.PerspectiveCamera(b.fov,b.aspect,b.near,b.far);break;case "OrthographicCamera":e=new THREE.OrthographicCamera(b.left,
-b.right,b.top,b.bottom,b.near,b.far);break;case "AmbientLight":e=new THREE.AmbientLight(b.color);break;case "AreaLight":e=new THREE.AreaLight(b.color,b.intensity);break;case "DirectionalLight":e=new THREE.DirectionalLight(b.color,b.intensity);break;case "PointLight":e=new THREE.PointLight(b.color,b.intensity,b.distance,b.decay);break;case "SpotLight":e=new THREE.SpotLight(b.color,b.intensity,b.distance,b.angle,b.exponent,b.decay);break;case "HemisphereLight":e=new THREE.HemisphereLight(b.color,b.groundColor,
-b.intensity);break;case "Mesh":e=new THREE.Mesh(e(b.geometry),g(b.material));break;case "Line":e=new THREE.Line(e(b.geometry),g(b.material),b.mode);break;case "PointCloud":e=new THREE.PointCloud(e(b.geometry),g(b.material));break;case "Sprite":e=new THREE.Sprite(g(b.material));break;case "Group":e=new THREE.Group;break;default:e=new THREE.Object3D}e.uuid=b.uuid;void 0!==b.name&&(e.name=b.name);void 0!==b.matrix?(a.fromArray(b.matrix),a.decompose(e.position,e.quaternion,e.scale)):(void 0!==b.position&&
-e.position.fromArray(b.position),void 0!==b.rotation&&e.rotation.fromArray(b.rotation),void 0!==b.scale&&e.scale.fromArray(b.scale));void 0!==b.castShadow&&(e.castShadow=b.castShadow);void 0!==b.receiveShadow&&(e.receiveShadow=b.receiveShadow);void 0!==b.visible&&(e.visible=b.visible);void 0!==b.userData&&(e.userData=b.userData);if(void 0!==b.children)for(var f in b.children)e.add(this.parseObject(b.children[f],c,d));return e}}()};THREE.TextureLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager};
-THREE.TextureLoader.prototype={constructor:THREE.TextureLoader,load:function(a,b,c,d){var e=new THREE.ImageLoader(this.manager);e.setCrossOrigin(this.crossOrigin);e.load(a,function(a){a=new THREE.Texture(a);a.needsUpdate=!0;void 0!==b&&b(a)},c,d)},setCrossOrigin:function(a){this.crossOrigin=a}};THREE.DataTextureLoader=THREE.BinaryTextureLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager;this._parser=null};
+h.detail);break;case "TetrahedronGeometry":f=new THREE.TetrahedronGeometry(h.radius,h.detail);break;case "RingGeometry":f=new THREE.RingGeometry(h.innerRadius,h.outerRadius,h.thetaSegments,h.phiSegments,h.thetaStart,h.thetaLength);break;case "TorusGeometry":f=new THREE.TorusGeometry(h.radius,h.tube,h.radialSegments,h.tubularSegments,h.arc);break;case "TorusKnotGeometry":f=new THREE.TorusKnotGeometry(h.radius,h.tube,h.radialSegments,h.tubularSegments,h.p,h.q,h.heightScale);break;case "TextGeometry":f=
+new THREE.TextGeometry(h.text,h.data);break;case "BufferGeometry":f=d.parse(h);break;case "Geometry":f=c.parse(h.data,this.texturePath).geometry;break;default:console.warn('THREE.ObjectLoader: Unsupported geometry type "'+h.type+'"');continue}f.uuid=h.uuid;void 0!==h.name&&(f.name=h.name);b[h.uuid]=f}return b},parseMaterials:function(a,b){var c={};if(void 0!==a)for(var d=function(a){void 0===b[a]&&console.warn("THREE.ObjectLoader: Undefined texture",a);return b[a]},e=new THREE.MaterialLoader,g=0,
+f=a.length;g<f;g++){var h=a[g],k=e.parse(h);k.uuid=h.uuid;void 0!==h.depthTest&&(k.depthTest=h.depthTest);void 0!==h.depthWrite&&(k.depthWrite=h.depthWrite);void 0!==h.name&&(k.name=h.name);void 0!==h.map&&(k.map=d(h.map));void 0!==h.alphaMap&&(k.alphaMap=d(h.alphaMap),k.transparent=!0);void 0!==h.bumpMap&&(k.bumpMap=d(h.bumpMap));void 0!==h.bumpScale&&(k.bumpScale=h.bumpScale);void 0!==h.normalMap&&(k.normalMap=d(h.normalMap));h.normalScale&&(k.normalScale=new THREE.Vector2(h.normalScale,h.normalScale));
+void 0!==h.specularMap&&(k.specularMap=d(h.specularMap));void 0!==h.envMap&&(k.envMap=d(h.envMap),k.combine=THREE.MultiplyOperation);h.reflectivity&&(k.reflectivity=h.reflectivity);void 0!==h.lightMap&&(k.lightMap=d(h.lightMap));void 0!==h.lightMapIntensity&&(k.lightMapIntensity=h.lightMapIntensity);void 0!==h.aoMap&&(k.aoMap=d(h.aoMap));void 0!==h.aoMapIntensity&&(k.aoMapIntensity=h.aoMapIntensity);c[h.uuid]=k}return c},parseImages:function(a,b){var c=this,d={};if(void 0!==a&&0<a.length){var e=new THREE.LoadingManager(b),
+g=new THREE.ImageLoader(e);g.setCrossOrigin(this.crossOrigin);for(var e=function(a){a=c.texturePath+a;c.manager.itemStart(a);return g.load(a,function(){c.manager.itemEnd(a)})},f=0,h=a.length;f<h;f++){var k=a[f];d[k.uuid]=e(k.url)}}return d},parseTextures:function(a,b){function c(a){if("number"===typeof a)return a;console.warn("THREE.ObjectLoader.parseTexture: Constant should be in numeric form.",a);return THREE[a]}var d={};if(void 0!==a)for(var e=0,g=a.length;e<g;e++){var f=a[e];void 0===f.image&&
+console.warn('THREE.ObjectLoader: No "image" specified for',f.uuid);void 0===b[f.image]&&console.warn("THREE.ObjectLoader: Undefined image",f.image);var h=new THREE.Texture(b[f.image]);h.needsUpdate=!0;h.uuid=f.uuid;void 0!==f.name&&(h.name=f.name);void 0!==f.mapping&&(h.mapping=c(f.mapping));void 0!==f.repeat&&(h.repeat=new THREE.Vector2(f.repeat[0],f.repeat[1]));void 0!==f.minFilter&&(h.minFilter=c(f.minFilter));void 0!==f.magFilter&&(h.magFilter=c(f.magFilter));void 0!==f.anisotropy&&(h.anisotropy=
+f.anisotropy);Array.isArray(f.wrap)&&(h.wrapS=c(f.wrap[0]),h.wrapT=c(f.wrap[1]));d[f.uuid]=h}return d},parseObject:function(){var a=new THREE.Matrix4;return function(b,c,d){var e;e=function(a){void 0===c[a]&&console.warn("THREE.ObjectLoader: Undefined geometry",a);return c[a]};var g=function(a){void 0===d[a]&&console.warn("THREE.ObjectLoader: Undefined material",a);return d[a]};switch(b.type){case "Scene":e=new THREE.Scene;break;case "PerspectiveCamera":e=new THREE.PerspectiveCamera(b.fov,b.aspect,
+b.near,b.far);break;case "OrthographicCamera":e=new THREE.OrthographicCamera(b.left,b.right,b.top,b.bottom,b.near,b.far);break;case "AmbientLight":e=new THREE.AmbientLight(b.color);break;case "DirectionalLight":e=new THREE.DirectionalLight(b.color,b.intensity);break;case "PointLight":e=new THREE.PointLight(b.color,b.intensity,b.distance,b.decay);break;case "SpotLight":e=new THREE.SpotLight(b.color,b.intensity,b.distance,b.angle,b.exponent,b.decay);break;case "HemisphereLight":e=new THREE.HemisphereLight(b.color,
+b.groundColor,b.intensity);break;case "Mesh":e=new THREE.Mesh(e(b.geometry),g(b.material));break;case "LOD":e=new THREE.LOD;break;case "Line":e=new THREE.Line(e(b.geometry),g(b.material),b.mode);break;case "PointCloud":e=new THREE.PointCloud(e(b.geometry),g(b.material));break;case "Sprite":e=new THREE.Sprite(g(b.material));break;case "Group":e=new THREE.Group;break;default:e=new THREE.Object3D}e.uuid=b.uuid;void 0!==b.name&&(e.name=b.name);void 0!==b.matrix?(a.fromArray(b.matrix),a.decompose(e.position,
+e.quaternion,e.scale)):(void 0!==b.position&&e.position.fromArray(b.position),void 0!==b.rotation&&e.rotation.fromArray(b.rotation),void 0!==b.scale&&e.scale.fromArray(b.scale));void 0!==b.castShadow&&(e.castShadow=b.castShadow);void 0!==b.receiveShadow&&(e.receiveShadow=b.receiveShadow);void 0!==b.visible&&(e.visible=b.visible);void 0!==b.userData&&(e.userData=b.userData);if(void 0!==b.children)for(var f in b.children)e.add(this.parseObject(b.children[f],c,d));if("LOD"===b.type)for(b=b.levels,g=
+0;g<b.length;g++){var h=b[g];f=e.getObjectByProperty("uuid",h.object);void 0!==f&&e.addLevel(f,h.distance)}return e}}()};THREE.TextureLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager};THREE.TextureLoader.prototype={constructor:THREE.TextureLoader,load:function(a,b,c,d){var e=new THREE.ImageLoader(this.manager);e.setCrossOrigin(this.crossOrigin);e.load(a,function(a){a=new THREE.Texture(a);a.needsUpdate=!0;void 0!==b&&b(a)},c,d)},setCrossOrigin:function(a){this.crossOrigin=a}};
+THREE.DataTextureLoader=THREE.BinaryTextureLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager;this._parser=null};
 THREE.BinaryTextureLoader.prototype={constructor:THREE.BinaryTextureLoader,load:function(a,b,c,d){var e=this,g=new THREE.DataTexture,f=new THREE.XHRLoader(this.manager);f.setCrossOrigin(this.crossOrigin);f.setResponseType("arraybuffer");f.load(a,function(a){if(a=e._parser(a))void 0!==a.image?g.image=a.image:void 0!==a.data&&(g.image.width=a.width,g.image.height=a.height,g.image.data=a.data),g.wrapS=void 0!==a.wrapS?a.wrapS:THREE.ClampToEdgeWrapping,g.wrapT=void 0!==a.wrapT?a.wrapT:THREE.ClampToEdgeWrapping,
 g.magFilter=void 0!==a.magFilter?a.magFilter:THREE.LinearFilter,g.minFilter=void 0!==a.minFilter?a.minFilter:THREE.LinearMipMapLinearFilter,g.anisotropy=void 0!==a.anisotropy?a.anisotropy:1,void 0!==a.format&&(g.format=a.format),void 0!==a.type&&(g.type=a.type),void 0!==a.mipmaps&&(g.mipmaps=a.mipmaps),1===a.mipmapCount&&(g.minFilter=THREE.LinearFilter),g.needsUpdate=!0,b&&b(g,a)},c,d);return g},setCrossOrigin:function(a){this.crossOrigin=a}};
 THREE.CompressedTextureLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager;this._parser=null};
@@ -371,32 +364,36 @@ THREE.Texture=function(a,b,c,d,e,g,f,h,k){Object.defineProperty(this,"id",{value
 this.anisotropy=void 0!==k?k:1;this.format=void 0!==f?f: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.version=0;this.onUpdate=null};THREE.Texture.DEFAULT_IMAGE=void 0;THREE.Texture.DEFAULT_MAPPING=THREE.UVMapping;
 THREE.Texture.prototype={constructor:THREE.Texture,set needsUpdate(a){!0===a&&this.version++},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.image=a.image;this.mipmaps=a.mipmaps.slice(0);this.mapping=a.mapping;this.wrapS=a.wrapS;this.wrapT=a.wrapT;this.magFilter=a.magFilter;this.minFilter=a.minFilter;this.anisotropy=a.anisotropy;this.format=a.format;this.type=a.type;this.offset.copy(a.offset);this.repeat.copy(a.repeat);this.generateMipmaps=a.generateMipmaps;this.premultiplyAlpha=
 a.premultiplyAlpha;this.flipY=a.flipY;this.unpackAlignment=a.unpackAlignment;return this},toJSON:function(a){if(void 0!==a.textures[this.uuid])return a.textures[this.uuid];var b={metadata:{version:4.4,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,name:this.name,mapping:this.mapping,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],wrap:[this.wrapS,this.wrapT],minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy};if(void 0!==this.image){var c=
-this.image;void 0===c.uuid&&(c.uuid=THREE.Math.generateUUID());if(void 0===a.images[c.uuid]){var d=a.images,e=c.uuid,g=c.uuid,f;void 0!==c.toDataURL?f=c:(f=document.createElement("canvas"),f.width=c.width,f.height=c.height,f.getContext("2d").drawImage(c,0,0,c.width,c.height));f=2048<f.width||2048<f.height?f.toDataURL("image/jpeg",.6):f.toDataURL("image/png");d[e]={uuid:g,url:f}}b.image=c.uuid}return a.textures[this.uuid]=b},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.Texture.prototype);
-THREE.TextureIdCount=0;THREE.CanvasTexture=function(a,b,c,d,e,g,f,h,k){THREE.Texture.call(this,a,b,c,d,e,g,f,h,k);this.needsUpdate=!0};THREE.CanvasTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CanvasTexture.prototype.constructor=THREE.CanvasTexture;THREE.CubeTexture=function(a,b,c,d,e,g,f,h,k){b=void 0!==b?b:THREE.CubeReflectionMapping;THREE.Texture.call(this,a,b,c,d,e,g,f,h,k);this.images=a;this.flipY=!1};THREE.CubeTexture.prototype=Object.create(THREE.Texture.prototype);
-THREE.CubeTexture.prototype.constructor=THREE.CubeTexture;THREE.CubeTexture.prototype.copy=function(a){THREE.Texture.prototype.copy.call(this,a);this.images=a.images;return this};THREE.CompressedTexture=function(a,b,c,d,e,g,f,h,k,l,n){THREE.Texture.call(this,null,g,f,h,k,l,d,e,n);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1};THREE.CompressedTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CompressedTexture.prototype.constructor=THREE.CompressedTexture;
+this.image;void 0===c.uuid&&(c.uuid=THREE.Math.generateUUID());if(void 0===a.images[c.uuid]){var d=a.images,e=c.uuid,g=c.uuid,f;void 0!==c.toDataURL?f=c:(f=document.createElement("canvas"),f.width=c.width,f.height=c.height,f.getContext("2d").drawImage(c,0,0,c.width,c.height));f=2048<f.width||2048<f.height?f.toDataURL("image/jpeg",.6):f.toDataURL("image/png");d[e]={uuid:g,url:f}}b.image=c.uuid}return a.textures[this.uuid]=b},dispose:function(){this.dispatchEvent({type:"dispose"})},transformUv:function(a){if(this.mapping===
+THREE.UVMapping){a.multiply(this.repeat);a.add(this.offset);if(0>a.x||1<a.x)switch(this.wrapS){case THREE.RepeatWrapping:a.x-=Math.floor(a.x);break;case THREE.ClampToEdgeWrapping:a.x=0>a.x?0:1;break;case THREE.MirroredRepeatWrapping:1===Math.abs(Math.floor(a.x)%2)?a.x=Math.ceil(a.x)-a.x:a.x-=Math.floor(a.x)}if(0>a.y||1<a.y)switch(this.wrapT){case THREE.RepeatWrapping:a.y-=Math.floor(a.y);break;case THREE.ClampToEdgeWrapping:a.y=0>a.y?0:1;break;case THREE.MirroredRepeatWrapping:1===Math.abs(Math.floor(a.y)%
+2)?a.y=Math.ceil(a.y)-a.y:a.y-=Math.floor(a.y)}this.flipY&&(a.y=1-a.y)}}};THREE.EventDispatcher.prototype.apply(THREE.Texture.prototype);THREE.TextureIdCount=0;THREE.CanvasTexture=function(a,b,c,d,e,g,f,h,k){THREE.Texture.call(this,a,b,c,d,e,g,f,h,k);this.needsUpdate=!0};THREE.CanvasTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CanvasTexture.prototype.constructor=THREE.CanvasTexture;
+THREE.CubeTexture=function(a,b,c,d,e,g,f,h,k){b=void 0!==b?b:THREE.CubeReflectionMapping;THREE.Texture.call(this,a,b,c,d,e,g,f,h,k);this.images=a;this.flipY=!1};THREE.CubeTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CubeTexture.prototype.constructor=THREE.CubeTexture;THREE.CubeTexture.prototype.copy=function(a){THREE.Texture.prototype.copy.call(this,a);this.images=a.images;return this};
+THREE.CompressedTexture=function(a,b,c,d,e,g,f,h,k,l,n){THREE.Texture.call(this,null,g,f,h,k,l,d,e,n);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1};THREE.CompressedTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CompressedTexture.prototype.constructor=THREE.CompressedTexture;
 THREE.DataTexture=function(a,b,c,d,e,g,f,h,k,l,n){THREE.Texture.call(this,null,g,f,h,k,l,d,e,n);this.image={data:a,width:b,height:c};this.magFilter=void 0!==k?k:THREE.NearestFilter;this.minFilter=void 0!==l?l:THREE.NearestFilter;this.generateMipmaps=this.flipY=!1};THREE.DataTexture.prototype=Object.create(THREE.Texture.prototype);THREE.DataTexture.prototype.constructor=THREE.DataTexture;
 THREE.VideoTexture=function(a,b,c,d,e,g,f,h,k){THREE.Texture.call(this,a,b,c,d,e,g,f,h,k);this.generateMipmaps=!1;var l=this,n=function(){requestAnimationFrame(n);a.readyState===a.HAVE_ENOUGH_DATA&&(l.needsUpdate=!0)};n()};THREE.VideoTexture.prototype=Object.create(THREE.Texture.prototype);THREE.VideoTexture.prototype.constructor=THREE.VideoTexture;THREE.Group=function(){THREE.Object3D.call(this);this.type="Group"};THREE.Group.prototype=Object.create(THREE.Object3D.prototype);
 THREE.Group.prototype.constructor=THREE.Group;THREE.PointCloud=function(a,b){THREE.Object3D.call(this);this.type="PointCloud";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.PointCloudMaterial({color:16777215*Math.random()})};THREE.PointCloud.prototype=Object.create(THREE.Object3D.prototype);THREE.PointCloud.prototype.constructor=THREE.PointCloud;
 THREE.PointCloud.prototype.raycast=function(){var a=new THREE.Matrix4,b=new THREE.Ray;return function(c,d){var e=this,g=e.geometry,f=c.params.PointCloud.threshold;a.getInverse(this.matrixWorld);b.copy(c.ray).applyMatrix4(a);if(null===g.boundingBox||!1!==b.isIntersectionBox(g.boundingBox)){var f=f/((this.scale.x+this.scale.y+this.scale.z)/3),h=f*f,k=new THREE.Vector3,f=function(a,f){var g=b.distanceSqToPoint(a);if(g<h){var k=b.closestPointToPoint(a);k.applyMatrix4(e.matrixWorld);var l=c.ray.origin.distanceTo(k);
-l<c.near||l>c.far||d.push({distance:l,distanceToRay:Math.sqrt(g),point:k.clone(),index:f,face:null,object:e})}};if(g instanceof THREE.BufferGeometry){var l=g.index,n=g.attributes.position.array;if(null!==l){var l=l.array,p=g.groups;0===p.length&&(p=[{start:0,count:l.length}]);for(var m=0,q=p.length;m<q;++m)for(var s=p[m],r=s.start,g=r,s=r+s.count;g<s;g++)r=l[g],k.fromArray(n,3*r),f(k,r)}else for(g=0,l=n.length/3;g<l;g++)k.fromArray(n,3*g),f(k,g)}else for(k=g.vertices,g=0,l=k.length;g<l;g++)f(k[g],
+l<c.near||l>c.far||d.push({distance:l,distanceToRay:Math.sqrt(g),point:k.clone(),index:f,face:null,object:e})}};if(g instanceof THREE.BufferGeometry){var l=g.index,n=g.attributes.position.array;if(null!==l){var l=l.array,p=g.groups;0===p.length&&(p=[{start:0,count:l.length}]);for(var m=0,q=p.length;m<q;++m)for(var t=p[m],r=t.start,g=r,t=r+t.count;g<t;g++)r=l[g],k.fromArray(n,3*r),f(k,r)}else for(g=0,l=n.length/3;g<l;g++)k.fromArray(n,3*g),f(k,g)}else for(k=g.vertices,g=0,l=k.length;g<l;g++)f(k[g],
 g)}}}();THREE.PointCloud.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};THREE.PointCloud.prototype.toJSON=function(a){var b=THREE.Object3D.prototype.toJSON.call(this,a);void 0===a.geometries[this.geometry.uuid]&&(a.geometries[this.geometry.uuid]=this.geometry.toJSON());void 0===a.materials[this.material.uuid]&&(a.materials[this.material.uuid]=this.material.toJSON());b.object.geometry=this.geometry.uuid;b.object.material=this.material.uuid;return b};
 THREE.ParticleSystem=function(a,b){console.warn("THREE.ParticleSystem has been renamed to THREE.PointCloud.");return new THREE.PointCloud(a,b)};THREE.Line=function(a,b,c){if(1===c)return console.warn("THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead."),new THREE.LineSegments(a,b);THREE.Object3D.call(this);this.type="Line";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.LineBasicMaterial({color:16777215*Math.random()})};
 THREE.Line.prototype=Object.create(THREE.Object3D.prototype);THREE.Line.prototype.constructor=THREE.Line;
 THREE.Line.prototype.raycast=function(){var a=new THREE.Matrix4,b=new THREE.Ray,c=new THREE.Sphere;return function(d,e){var g=d.linePrecision,g=g*g,f=this.geometry;null===f.boundingSphere&&f.computeBoundingSphere();c.copy(f.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,n=new THREE.Vector3,p=this instanceof THREE.LineSegments?2:1;if(f instanceof
-THREE.BufferGeometry){var m=f.index,q=f.attributes;if(null!==m){var m=m.array,q=q.position.array,s=f.groups;0===s.length&&(s=[{start:0,count:m.length}]);for(var r=0;r<s.length;r++)for(var f=s[r],u=f.start,x=f.count,f=u;f<u+x-1;f+=p){var v=m[f+1];h.fromArray(q,3*m[f]);k.fromArray(q,3*v);v=b.distanceSqToSegment(h,k,n,l);v>g||(n.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(n),v<d.near||v>d.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld),index:f,offsetIndex:r,face:null,
-faceIndex:null,object:this}))}}else for(q=q.position.array,f=0;f<q.length/3-1;f+=p)h.fromArray(q,3*f),k.fromArray(q,3*f+3),v=b.distanceSqToSegment(h,k,n,l),v>g||(n.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(n),v<d.near||v>d.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld),index:f,face:null,faceIndex:null,object:this}))}else if(f instanceof THREE.Geometry)for(h=f.vertices,k=h.length,f=0;f<k-1;f+=p)v=b.distanceSqToSegment(h[f],h[f+1],n,l),v>g||(n.applyMatrix4(this.matrixWorld),
-v=d.ray.origin.distanceTo(n),v<d.near||v>d.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld),index:f,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};
+THREE.BufferGeometry){var m=f.index,q=f.attributes;if(null!==m){var m=m.array,q=q.position.array,t=f.groups;0===t.length&&(t=[{start:0,count:m.length}]);for(var r=0;r<t.length;r++)for(var f=t[r],v=f.start,w=f.count,f=v;f<v+w-1;f+=p){var u=m[f+1];h.fromArray(q,3*m[f]);k.fromArray(q,3*u);u=b.distanceSqToSegment(h,k,n,l);u>g||(n.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(n),u<d.near||u>d.far||e.push({distance:u,point:l.clone().applyMatrix4(this.matrixWorld),index:f,offsetIndex:r,face:null,
+faceIndex:null,object:this}))}}else for(q=q.position.array,f=0;f<q.length/3-1;f+=p)h.fromArray(q,3*f),k.fromArray(q,3*f+3),u=b.distanceSqToSegment(h,k,n,l),u>g||(n.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(n),u<d.near||u>d.far||e.push({distance:u,point:l.clone().applyMatrix4(this.matrixWorld),index:f,face:null,faceIndex:null,object:this}))}else if(f instanceof THREE.Geometry)for(h=f.vertices,k=h.length,f=0;f<k-1;f+=p)u=b.distanceSqToSegment(h[f],h[f+1],n,l),u>g||(n.applyMatrix4(this.matrixWorld),
+u=d.ray.origin.distanceTo(n),u<d.near||u>d.far||e.push({distance:u,point:l.clone().applyMatrix4(this.matrixWorld),index:f,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};
 THREE.Line.prototype.toJSON=function(a){var b=THREE.Object3D.prototype.toJSON.call(this,a);void 0===a.geometries[this.geometry.uuid]&&(a.geometries[this.geometry.uuid]=this.geometry.toJSON());void 0===a.materials[this.material.uuid]&&(a.materials[this.material.uuid]=this.material.toJSON());b.object.geometry=this.geometry.uuid;b.object.material=this.material.uuid;return b};THREE.LineStrip=0;THREE.LinePieces=1;THREE.LineSegments=function(a,b){THREE.Line.call(this,a,b);this.type="LineSegments"};
 THREE.LineSegments.prototype=Object.create(THREE.Line.prototype);THREE.LineSegments.prototype.constructor=THREE.LineSegments;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&&0<this.geometry.morphTargets.length){this.morphTargetBase=-1;this.morphTargetInfluences=[];this.morphTargetDictionary={};for(var a=0,b=this.geometry.morphTargets.length;a<b;a++)this.morphTargetInfluences.push(0),this.morphTargetDictionary[this.geometry.morphTargets[a].name]=a}};
 THREE.Mesh.prototype.getMorphTargetIndexByName=function(a){if(void 0!==this.morphTargetDictionary[a])return this.morphTargetDictionary[a];console.warn("THREE.Mesh.getMorphTargetIndexByName: morph target "+a+" does not exist. Returning 0.");return 0};
-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,g=new THREE.Vector3,f=new THREE.Vector3,h=new THREE.Vector3,k=new THREE.Vector3;return function(l,n){var p=this.geometry,m=this.material;if(void 0!==m&&(null===p.boundingSphere&&p.computeBoundingSphere(),c.copy(p.boundingSphere),c.applyMatrix4(this.matrixWorld),!1!==l.ray.isIntersectionSphere(c)&&(a.getInverse(this.matrixWorld),b.copy(l.ray).applyMatrix4(a),null===
-p.boundingBox||!1!==b.isIntersectionBox(p.boundingBox)))){var q,s,r;if(p instanceof THREE.BufferGeometry)if(s=p.index,q=p.attributes,null!==s){var u=s.array,x=q.position.array,p=p.groups;0===p.length&&(p=[{start:0,count:u.length}]);for(var v=0,y=p.length;v<y;++v){q=p[v];for(var w=s=q.start,G=s+q.count;w<G;w+=3){q=u[w];s=u[w+1];r=u[w+2];d.fromArray(x,3*q);e.fromArray(x,3*s);g.fromArray(x,3*r);var B=m.side===THREE.BackSide?b.intersectTriangle(g,e,d,!0):b.intersectTriangle(d,e,g,m.side!==THREE.DoubleSide);
-if(null!==B){B.applyMatrix4(this.matrixWorld);var z=l.ray.origin.distanceTo(B);z<l.near||z>l.far||n.push({distance:z,point:B,face:new THREE.Face3(q,s,r,THREE.Triangle.normal(d,e,g)),faceIndex:Math.floor(w/3),object:this})}}}}else for(x=q.position.array,w=0,G=x.length;w<G;w+=9)d.fromArray(x,w),e.fromArray(x,w+3),g.fromArray(x,w+6),B=m.side===THREE.BackSide?b.intersectTriangle(g,e,d,!0):b.intersectTriangle(d,e,g,m.side!==THREE.DoubleSide),null!==B&&(B.applyMatrix4(this.matrixWorld),z=l.ray.origin.distanceTo(B),
-z<l.near||z>l.far||(q=w/3,s=q+1,r=q+2,n.push({distance:z,point:B,face:new THREE.Face3(q,s,r,THREE.Triangle.normal(d,e,g)),index:q,object:this})));else if(p instanceof THREE.Geometry)for(u=m instanceof THREE.MeshFaceMaterial,x=!0===u?m.materials:null,v=p.vertices,y=p.faces,w=0,G=y.length;w<G;w++){var A=y[w],B=!0===u?x[A.materialIndex]:m;if(void 0!==B){q=v[A.a];s=v[A.b];r=v[A.c];if(!0===B.morphTargets){var z=p.morphTargets,O=this.morphTargetInfluences;d.set(0,0,0);e.set(0,0,0);g.set(0,0,0);for(var K=
-0,D=z.length;K<D;K++){var P=O[K];if(0!==P){var J=z[K].vertices;d.addScaledVector(f.subVectors(J[A.a],q),P);e.addScaledVector(h.subVectors(J[A.b],s),P);g.addScaledVector(k.subVectors(J[A.c],r),P)}}d.add(q);e.add(s);g.add(r);q=d;s=e;r=g}B=B.side===THREE.BackSide?b.intersectTriangle(r,s,q,!0):b.intersectTriangle(q,s,r,B.side!==THREE.DoubleSide);null!==B&&(B.applyMatrix4(this.matrixWorld),z=l.ray.origin.distanceTo(B),z<l.near||z>l.far||n.push({distance:z,point:B,face:A,faceIndex:w,object:this}))}}}}}();
-THREE.Mesh.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};THREE.Mesh.prototype.toJSON=function(a){var b=THREE.Object3D.prototype.toJSON.call(this,a);void 0===a.geometries[this.geometry.uuid]&&(a.geometries[this.geometry.uuid]=this.geometry.toJSON(a));void 0===a.materials[this.material.uuid]&&(a.materials[this.material.uuid]=this.material.toJSON(a));b.object.geometry=this.geometry.uuid;b.object.material=this.material.uuid;return b};
-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.Bone.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a);this.skin=a.skin;return this};
+THREE.Mesh.prototype.raycast=function(){function a(a,b,c,d,e,f,g){THREE.Triangle.barycoordFromPoint(a,b,c,d,q);e.multiplyScalar(q.x);f.multiplyScalar(q.y);g.multiplyScalar(q.z);e.add(f).add(g);return e.clone()}var b=new THREE.Matrix4,c=new THREE.Ray,d=new THREE.Sphere,e=new THREE.Vector3,g=new THREE.Vector3,f=new THREE.Vector3,h=new THREE.Vector3,k=new THREE.Vector3,l=new THREE.Vector3,n=new THREE.Vector2,p=new THREE.Vector2,m=new THREE.Vector2,q=new THREE.Vector3,t=new THREE.Vector3,r=new THREE.Vector3;
+return function(q,w){var u=this.geometry,z=this.material;if(void 0!==z&&(null===u.boundingSphere&&u.computeBoundingSphere(),d.copy(u.boundingSphere),d.applyMatrix4(this.matrixWorld),!1!==q.ray.isIntersectionSphere(d)&&(b.getInverse(this.matrixWorld),c.copy(q.ray).applyMatrix4(b),null===u.boundingBox||!1!==c.isIntersectionBox(u.boundingBox)))){var x,D,F;if(u instanceof THREE.BufferGeometry){x=u.index;var y=u.attributes;if(null!==x){var B=x.array,L=y.position.array,u=u.groups;0===u.length&&(u=[{start:0,
+count:B.length}]);for(var N=0,C=u.length;N<C;++N){x=u[N];for(var O=D=x.start,G=D+x.count;O<G;O+=3){x=B[O];D=B[O+1];F=B[O+2];e.fromArray(L,3*x);g.fromArray(L,3*D);f.fromArray(L,3*F);if(z.side===THREE.BackSide){if(null===c.intersectTriangle(f,g,e,!0,t))continue}else if(null===c.intersectTriangle(e,g,f,z.side!==THREE.DoubleSide,t))continue;r.copy(t);r.applyMatrix4(this.matrixWorld);var J=q.ray.origin.distanceTo(r);if(!(J<q.near||J>q.far)){var A;void 0!==y.uv&&(A=y.uv.array,n.fromArray(A,2*x),p.fromArray(A,
+2*D),m.fromArray(A,2*F),A=a(t,e,g,f,n,p,m));w.push({distance:J,point:r.clone(),uv:A,face:new THREE.Face3(x,D,F,THREE.Triangle.normal(e,g,f)),faceIndex:Math.floor(O/3),object:this})}}}}else for(L=y.position.array,O=0,G=L.length;O<G;O+=9){e.fromArray(L,O);g.fromArray(L,O+3);f.fromArray(L,O+6);if(z.side===THREE.BackSide){if(null===c.intersectTriangle(f,g,e,!0,t))continue}else if(null===c.intersectTriangle(e,g,f,z.side!==THREE.DoubleSide,t))continue;r.copy(t);r.applyMatrix4(this.matrixWorld);J=q.ray.origin.distanceTo(r);
+J<q.near||J>q.far||(void 0!==y.uv&&(A=y.uv.array,n.fromArray(A,O),p.fromArray(A,O+2),m.fromArray(A,O+4),A=a(t,e,g,f,n,p,m)),x=O/3,D=x+1,F=x+2,w.push({distance:J,point:r.clone(),uv:A,face:new THREE.Face3(x,D,F,THREE.Triangle.normal(e,g,f)),index:x,object:this}))}}else if(u instanceof THREE.Geometry)for(y=z instanceof THREE.MeshFaceMaterial,B=!0===y?z.materials:null,L=u.vertices,N=u.faces,C=0,O=N.length;C<O;C++)if(G=N[C],J=!0===y?B[G.materialIndex]:z,void 0!==J){x=L[G.a];D=L[G.b];F=L[G.c];if(!0===J.morphTargets){var H=
+u.morphTargets,P=this.morphTargetInfluences;e.set(0,0,0);g.set(0,0,0);f.set(0,0,0);for(var Q=0,V=H.length;Q<V;Q++){var R=P[Q];if(0!==R){var S=H[Q].vertices;e.addScaledVector(h.subVectors(S[G.a],x),R);g.addScaledVector(k.subVectors(S[G.b],D),R);f.addScaledVector(l.subVectors(S[G.c],F),R)}}e.add(x);g.add(D);f.add(F);x=e;D=g;F=f}if(J.side===THREE.BackSide){if(null===c.intersectTriangle(F,D,x,!0,t))continue}else if(null===c.intersectTriangle(x,D,F,J.side!==THREE.DoubleSide,t))continue;r.copy(t);r.applyMatrix4(this.matrixWorld);
+J=q.ray.origin.distanceTo(r);J<q.near||J>q.far||(0<u.faceVertexUvs[0].length&&(A=u.faceVertexUvs[0][C],n.copy(A[0]),p.copy(A[1]),m.copy(A[2]),A=a(t,x,D,F,n,p,m)),w.push({distance:J,point:r.clone(),uv:A,face:G,faceIndex:C,object:this}))}}}}();THREE.Mesh.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};
+THREE.Mesh.prototype.toJSON=function(a){var b=THREE.Object3D.prototype.toJSON.call(this,a);void 0===a.geometries[this.geometry.uuid]&&(a.geometries[this.geometry.uuid]=this.geometry.toJSON(a));void 0===a.materials[this.material.uuid]&&(a.materials[this.material.uuid]=this.material.toJSON(a));b.object.geometry=this.geometry.uuid;b.object.material=this.material.uuid;return b};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.Bone.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a);this.skin=a.skin;return this};
 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?(a=Math.sqrt(4*this.bones.length),a=THREE.Math.nextPowerOfTwo(Math.ceil(a)),this.boneTextureHeight=this.boneTextureWidth=a=Math.max(a,4),this.boneMatrices=new Float32Array(this.boneTextureWidth*this.boneTextureHeight*4),this.boneTexture=new THREE.DataTexture(this.boneMatrices,this.boneTextureWidth,this.boneTextureHeight,THREE.RGBAFormat,THREE.FloatType)):
 this.boneMatrices=new Float32Array(16*this.bones.length);if(void 0===b)this.calculateInverses();else if(this.bones.length===b.length)this.boneInverses=b.slice(0);else for(console.warn("THREE.Skeleton bonInverses is the wrong length."),this.boneInverses=[],b=0,a=this.bones.length;b<a;b++)this.boneInverses.push(new THREE.Matrix4)};
 THREE.Skeleton.prototype.calculateInverses=function(){this.boneInverses=[];for(var a=0,b=this.bones.length;a<b;a++){var c=new THREE.Matrix4;this.bones[a]&&c.getInverse(this.bones[a].matrixWorld);this.boneInverses.push(c)}};
@@ -413,10 +410,11 @@ THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){this.geometry.an
 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);var c=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/b),0,this.length-1);a=this.morphTargetInfluences;
 c!==this.currentKeyframe&&(a[this.lastKeyframe]=0,a[this.currentKeyframe]=1,a[c]=0,this.lastKeyframe=this.currentKeyframe,this.currentKeyframe=c);b=this.time%b/b;this.directionBackwards&&(b=1-b);a[this.currentKeyframe]=b;a[this.lastKeyframe]=1-b};THREE.MorphAnimMesh.prototype.interpolateTargets=function(a,b,c){for(var d=this.morphTargetInfluences,e=0,g=d.length;e<g;e++)d[e]=0;-1<a&&(d[a]=1-c);-1<b&&(d[b]=c)};
 THREE.MorphAnimMesh.prototype.copy=function(a){THREE.Mesh.prototype.copy.call(this,a);this.duration=a.duration;this.mirroredLoop=a.mirroredLoop;this.time=a.time;this.lastKeyframe=a.lastKeyframe;this.currentKeyframe=a.currentKeyframe;this.direction=a.direction;this.directionBackwards=a.directionBackwards;return this};
-THREE.LOD=function(){THREE.Object3D.call(this);Object.defineProperties(this,{levels:{enumerable:!0,value:[]},objects:{get:function(){console.warn("THREE.LOD: .objects has been renamed to .levels.");return this.levels}}})};THREE.LOD.prototype=Object.create(THREE.Object3D.prototype);THREE.LOD.prototype.constructor=THREE.LOD;THREE.LOD.prototype.addLevel=function(a,b){void 0===b&&(b=0);b=Math.abs(b);for(var c=this.levels,d=0;d<c.length&&!(b<c[d].distance);d++);c.splice(d,0,{distance:b,object:a});this.add(a)};
-THREE.LOD.prototype.getObjectForDistance=function(a){for(var b=this.levels,c=1,d=b.length;c<d&&!(a<b[c].distance);c++);return b[c-1].object};THREE.LOD.prototype.raycast=function(){var a=new THREE.Vector3;return function(b,c){a.setFromMatrixPosition(this.matrixWorld);var d=b.ray.origin.distanceTo(a);this.getObjectForDistance(d).raycast(b,c)}}();
+THREE.LOD=function(){THREE.Object3D.call(this);this.type="LOD";Object.defineProperties(this,{levels:{enumerable:!0,value:[]},objects:{get:function(){console.warn("THREE.LOD: .objects has been renamed to .levels.");return this.levels}}})};THREE.LOD.prototype=Object.create(THREE.Object3D.prototype);THREE.LOD.prototype.constructor=THREE.LOD;
+THREE.LOD.prototype.addLevel=function(a,b){void 0===b&&(b=0);b=Math.abs(b);for(var c=this.levels,d=0;d<c.length&&!(b<c[d].distance);d++);c.splice(d,0,{distance:b,object:a});this.add(a)};THREE.LOD.prototype.getObjectForDistance=function(a){for(var b=this.levels,c=1,d=b.length;c<d&&!(a<b[c].distance);c++);return b[c-1].object};
+THREE.LOD.prototype.raycast=function(){var a=new THREE.Vector3;return function(b,c){a.setFromMatrixPosition(this.matrixWorld);var d=b.ray.origin.distanceTo(a);this.getObjectForDistance(d).raycast(b,c)}}();
 THREE.LOD.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c){var d=this.levels;if(1<d.length){a.setFromMatrixPosition(c.matrixWorld);b.setFromMatrixPosition(this.matrixWorld);c=a.distanceTo(b);d[0].object.visible=!0;for(var e=1,g=d.length;e<g;e++)if(c>=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;e<g;e++)d[e].object.visible=!1}}}();
-THREE.LOD.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b<c;b++){var d=a[b];this.addLevel(d.object.clone(),d.distance)}return this};
+THREE.LOD.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b<c;b++){var d=a[b];this.addLevel(d.object.clone(),d.distance)}return this};THREE.LOD.prototype.toJSON=function(a){a=THREE.Object3D.prototype.toJSON.call(this,a);a.object.levels=[];for(var b=this.levels,c=0,d=b.length;c<d;c++){var e=b[c];a.object.levels.push({object:e.object.uuid,distance:e.distance})}return a};
 THREE.Sprite=function(){var a=new Uint16Array([0,1,2,0,2,3]),b=new Float32Array([-.5,-.5,0,.5,-.5,0,.5,.5,0,-.5,.5,0]),c=new Float32Array([0,0,1,0,1,1,0,1]),d=new THREE.BufferGeometry;d.addIndex(new THREE.BufferAttribute(a,1));d.addAttribute("position",new THREE.BufferAttribute(b,3));d.addAttribute("uv",new THREE.BufferAttribute(c,2));return function(a){THREE.Object3D.call(this);this.type="Sprite";this.geometry=d;this.material=void 0!==a?a:new THREE.SpriteMaterial}}();THREE.Sprite.prototype=Object.create(THREE.Object3D.prototype);
 THREE.Sprite.prototype.constructor=THREE.Sprite;THREE.Sprite.prototype.raycast=function(){var a=new THREE.Vector3;return function(b,c){a.setFromMatrixPosition(this.matrixWorld);var d=b.ray.distanceSqToPoint(a);d>this.scale.x*this.scale.y||c.push({distance:Math.sqrt(d),point:this.position,face:null,object:this})}}();THREE.Sprite.prototype.clone=function(){return(new this.constructor(this.material)).copy(this)};
 THREE.Sprite.prototype.toJSON=function(a){var b=THREE.Object3D.prototype.toJSON.call(this,a);void 0===a.materials[this.material.uuid]&&(a.materials[this.material.uuid]=this.material.toJSON());b.object.material=this.material.uuid;return b};THREE.Particle=THREE.Sprite;THREE.LensFlare=function(a,b,c,d,e){THREE.Object3D.call(this);this.lensFlares=[];this.positionScreen=new THREE.Vector3;this.customUpdateCallback=void 0;void 0!==a&&this.add(a,b,c,d,e)};THREE.LensFlare.prototype=Object.create(THREE.Object3D.prototype);
@@ -487,93 +485,93 @@ tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.Sh
 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,b,c,d){!0===Q&&(a*=d,b*=d,c*=d);t.clearColor(a,b,c,d)}function c(){L.init();t.viewport(Ia,Aa,Ba,Ca);b(E.r,E.g,E.b,ha)}function d(){$a=rb=null;va="";ab=-1;jb=!0;L.reset()}function e(a){a.preventDefault();d();c();$.clear()}function g(a){a=a.target;a.removeEventListener("dispose",g);a:{var b=$.get(a);if(a.image&&b.__image__webglTextureCube)t.deleteTexture(b.__image__webglTextureCube);else{if(void 0===b.__webglInit)break a;t.deleteTexture(b.__webglTexture)}$.delete(a)}Da.textures--}
-function f(a){a=a.target;a.removeEventListener("dispose",f);var b=$.get(a);if(a&&void 0!==b.__webglTexture){t.deleteTexture(b.__webglTexture);if(a instanceof THREE.WebGLRenderTargetCube)for(var c=0;6>c;c++)t.deleteFramebuffer(b.__webglFramebuffer[c]),t.deleteRenderbuffer(b.__webglRenderbuffer[c]);else t.deleteFramebuffer(b.__webglFramebuffer),t.deleteRenderbuffer(b.__webglRenderbuffer);$.delete(a)}Da.textures--}function h(a){a=a.target;a.removeEventListener("dispose",h);k(a);$.delete(a)}function k(a){var b=
-$.get(a).program.program;if(void 0!==b){a.program=void 0;a=0;for(var c=ra.length;a!==c;++a){var d=ra[a];if(d.program===b){0===--d.usedTimes&&(c-=1,ra[a]=ra[c],ra.pop(),t.deleteProgram(b),Da.programs=c);break}}}}function l(a,b){return b[0]-a[0]}function n(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 p(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 m(a,b,c,d,e){var f;c.transparent?(d=ya,f=++Ha):(d=ia,f=++za);f=d[f];void 0!==f?(f.id=a.id,f.object=a,f.geometry=b,f.material=c,f.z=ba.z,f.group=e):(f={id:a.id,object:a,geometry:b,material:c,z:ba.z,group:e},d.push(f))}function q(a){if(!1!==a.visible){if(a instanceof THREE.Light)X.push(a);else if(a instanceof THREE.Sprite)Ra.push(a);else if(a instanceof THREE.LensFlare)Sa.push(a);else if(a instanceof THREE.ImmediateRenderObject){var b,
-c;a.material.transparent?(b=Ja,c=++Ka):(b=qa,c=++bb);c<b.length?b[c]=a:b.push(a)}else if(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.PointCloud)if(a instanceof THREE.SkinnedMesh&&a.skeleton.update(),!1===a.frustumCulled||!0===kb.intersectsObject(a)){var d=a.material;if(!0===d.visible)if(!0===la.sortObjects&&(ba.setFromMatrixPosition(a.matrixWorld),ba.applyProjection(Ta)),b=sa.update(a),d instanceof THREE.MeshFaceMaterial){c=b.groups;for(var e=d.materials,d=0,f=c.length;d<
-f;d++){var g=c[d],h=e[g.materialIndex];!0===h.visible&&m(a,b,h,ba.z,g)}}else m(a,b,d,ba.z)}a=a.children;d=0;for(f=a.length;d<f;d++)q(a[d])}}function s(a,b,c,d,e){for(var f=0,g=a.length;f<g;f++){var h=a[f],k=h.object,l=h.geometry,m=void 0===e?h.material:e,h=h.group;k.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,k.matrixWorld);k.normalMatrix.getNormalMatrix(k.modelViewMatrix);la.renderBufferDirect(b,c,d,l,m,k,h)}}function r(a,b,c,d,e){for(var f=e,g=0,h=a.length;g<h;g++){var k=a[g];k.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,
-k.matrixWorld);k.normalMatrix.getNormalMatrix(k.modelViewMatrix);void 0===e&&(f=k.material);u(f);var l=x(b,c,d,f,k);va="";k.render(function(a){la.renderBufferImmediate(a,l,f)})}}function u(a){a.side!==THREE.DoubleSide?L.enable(t.CULL_FACE):L.disable(t.CULL_FACE);L.setFlipSided(a.side===THREE.BackSide);!0===a.transparent?L.setBlending(a.blending,a.blendEquation,a.blendSrc,a.blendDst,a.blendEquationAlpha,a.blendSrcAlpha,a.blendDstAlpha):L.setBlending(THREE.NoBlending);L.setDepthFunc(a.depthFunc);L.setDepthTest(a.depthTest);
-L.setDepthWrite(a.depthWrite);L.setColorWrite(a.colorWrite);L.setPolygonOffset(a.polygonOffset,a.polygonOffsetFactor,a.polygonOffsetUnits)}function x(a,b,c,d,e){var f,l,m,n;lb=0;var q=$.get(d);if(d.needsUpdate||!q.program){a:{for(var p=$.get(d),s=$b[d.type],r=0,x=0,u=0,z=0,O=0,A=b.length;O<A;O++){var C=b[O];C.onlyShadow||!1===C.visible||(C instanceof THREE.DirectionalLight&&r++,C instanceof THREE.PointLight&&x++,C instanceof THREE.SpotLight&&u++,C instanceof THREE.HemisphereLight&&z++)}f=r;l=x;m=
-u;n=z;for(var J,F=0,E=0,H=b.length;E<H;E++){var N=b[E];N.castShadow&&(N instanceof THREE.SpotLight&&F++,N instanceof THREE.DirectionalLight&&F++)}J=F;var R;if(ka.floatVertexTextures&&e&&e.skeleton&&e.skeleton.useVertexTexture)R=1024;else{var za=t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),P=Math.floor((za-20)/4);void 0!==e&&e instanceof THREE.SkinnedMesh&&(P=Math.min(e.skeleton.bones.length,P),P<e.skeleton.bones.length&&console.warn("WebGLRenderer: too many bones - "+e.skeleton.bones.length+", this GPU supports just "+
-P+" (try OpenGL instead of ANGLE)"));R=P}var Q=ka.precision;null!==d.precision&&(Q=ka.getMaxPrecision(d.precision),Q!==d.precision&&console.warn("THREE.WebGLRenderer.initMaterial:",d.precision,"not supported, using",Q,"instead."));var U={precision:Q,supportsVertexTextures:ka.vertexTextures,map:!!d.map,envMap:!!d.envMap,envMapMode:d.envMap&&d.envMap.mapping,lightMap:!!d.lightMap,aoMap:!!d.aoMap,emissiveMap:!!d.emissiveMap,bumpMap:!!d.bumpMap,normalMap:!!d.normalMap,specularMap:!!d.specularMap,alphaMap:!!d.alphaMap,
-combine:d.combine,vertexColors:d.vertexColors,fog:c,useFog:d.fog,fogExp:c instanceof THREE.FogExp2,flatShading:d.shading===THREE.FlatShading,sizeAttenuation:d.sizeAttenuation,logarithmicDepthBuffer:ka.logarithmicDepthBuffer,skinning:d.skinning,maxBones:R,useVertexTexture:ka.floatVertexTextures&&e&&e.skeleton&&e.skeleton.useVertexTexture,morphTargets:d.morphTargets,morphNormals:d.morphNormals,maxMorphTargets:la.maxMorphTargets,maxMorphNormals:la.maxMorphNormals,maxDirLights:f,maxPointLights:l,maxSpotLights:m,
-maxHemiLights:n,maxShadows:J,shadowMapEnabled:ma.enabled&&e.receiveShadow&&0<J,shadowMapType:ma.type,shadowMapDebug:ma.debug,alphaTest:d.alphaTest,metal:d.metal,doubleSided:d.side===THREE.DoubleSide,flipSided:d.side===THREE.BackSide},S=[];s?S.push(s):(S.push(d.fragmentShader),S.push(d.vertexShader));if(void 0!==d.defines)for(var qa in d.defines)S.push(qa),S.push(d.defines[qa]);for(qa in U)S.push(qa),S.push(U[qa]);var W=S.join(),ya=!0;if(p.program)if(p.program.code!==W)k(d);else if(void 0!==s)break a;
-else ya=!1;else d.addEventListener("dispose",h);if(s){var Ha=THREE.ShaderLib[s];p.__webglShader={name:d.type,uniforms:THREE.UniformsUtils.clone(Ha.uniforms),vertexShader:Ha.vertexShader,fragmentShader:Ha.fragmentShader}}else p.__webglShader={name:d.type,uniforms:d.uniforms,vertexShader:d.vertexShader,fragmentShader:d.fragmentShader};for(var X,Ka=0,bb=ra.length;Ka<bb;Ka++){var Ra=ra[Ka];if(Ra.code===W){X=Ra;ya&&X.usedTimes++;break}}void 0===X&&(d.__webglShader=p.__webglShader,X=new THREE.WebGLProgram(la,
-W,d,U),ra.push(X),Da.programs=ra.length);p.program=X;d.program=X;var Ja=X.getAttributes();if(d.morphTargets)for(var ta=d.numSupportedMorphTargets=0;ta<la.maxMorphTargets;ta++)0<=Ja["morphTarget"+ta]&&d.numSupportedMorphTargets++;if(d.morphNormals)for(ta=d.numSupportedMorphNormals=0;ta<la.maxMorphNormals;ta++)0<=Ja["morphNormal"+ta]&&d.numSupportedMorphNormals++;p.uniformsList=[];var ia=p.program.getUniforms(),ha;for(ha in p.__webglShader.uniforms){var Sa=ia[ha];Sa&&p.uniformsList.push([p.__webglShader.uniforms[ha],
-Sa])}}d.needsUpdate=!1}var ua=!1,va=!1,sa=!1,cb=q.program,ca=cb.getUniforms(),I=q.__webglShader.uniforms;cb.id!==rb&&(t.useProgram(cb.program),rb=cb.id,sa=va=ua=!0);d.id!==ab&&(-1===ab&&(sa=!0),ab=d.id,va=!0);if(ua||a!==$a)t.uniformMatrix4fv(ca.projectionMatrix,!1,a.projectionMatrix.elements),ka.logarithmicDepthBuffer&&t.uniform1f(ca.logDepthBufFC,2/(Math.log(a.far+1)/Math.LN2)),a!==$a&&($a=a),(d instanceof THREE.ShaderMaterial||d instanceof THREE.MeshPhongMaterial||d.envMap)&&void 0!==ca.cameraPosition&&
-(ba.setFromMatrixPosition(a.matrixWorld),t.uniform3f(ca.cameraPosition,ba.x,ba.y,ba.z)),(d instanceof THREE.MeshPhongMaterial||d instanceof THREE.MeshLambertMaterial||d instanceof THREE.MeshBasicMaterial||d instanceof THREE.ShaderMaterial||d.skinning)&&void 0!==ca.viewMatrix&&t.uniformMatrix4fv(ca.viewMatrix,!1,a.matrixWorldInverse.elements);if(d.skinning)if(e.bindMatrix&&void 0!==ca.bindMatrix&&t.uniformMatrix4fv(ca.bindMatrix,!1,e.bindMatrix.elements),e.bindMatrixInverse&&void 0!==ca.bindMatrixInverse&&
-t.uniformMatrix4fv(ca.bindMatrixInverse,!1,e.bindMatrixInverse.elements),ka.floatVertexTextures&&e.skeleton&&e.skeleton.useVertexTexture){if(void 0!==ca.boneTexture){var Ia=y();t.uniform1i(ca.boneTexture,Ia);la.setTexture(e.skeleton.boneTexture,Ia)}void 0!==ca.boneTextureWidth&&t.uniform1i(ca.boneTextureWidth,e.skeleton.boneTextureWidth);void 0!==ca.boneTextureHeight&&t.uniform1i(ca.boneTextureHeight,e.skeleton.boneTextureHeight)}else e.skeleton&&e.skeleton.boneMatrices&&void 0!==ca.boneGlobalMatrices&&
-t.uniformMatrix4fv(ca.boneGlobalMatrices,!1,e.skeleton.boneMatrices);if(va){c&&d.fog&&(I.fogColor.value=c.color,c instanceof THREE.Fog?(I.fogNear.value=c.near,I.fogFar.value=c.far):c instanceof THREE.FogExp2&&(I.fogDensity.value=c.density));if(d instanceof THREE.MeshPhongMaterial||d instanceof THREE.MeshLambertMaterial||d.lights){if(jb){var sa=!0,aa,oa,Z,Aa=0,Ba=0,Ca=0,La,Qa,Ta,Ua,sb,da=Pb,db=a.matrixWorldInverse,tb=da.directional.colors,ub=da.directional.positions,vb=da.point.colors,wb=da.point.positions,
-kb=da.point.distances,pb=da.point.decays,xb=da.spot.colors,yb=da.spot.positions,qb=da.spot.distances,zb=da.spot.directions,Kb=da.spot.anglesCos,Lb=da.spot.exponents,Mb=da.spot.decays,Ab=da.hemi.skyColors,Bb=da.hemi.groundColors,Cb=da.hemi.positions,eb=0,Ma=0,wa=0,Va=0,Db=0,Eb=0,Fb=0,mb=0,fb=0,gb=0,Ea=0,Wa=0;aa=0;for(oa=b.length;aa<oa;aa++)Z=b[aa],Z.onlyShadow||(La=Z.color,Ua=Z.intensity,sb=Z.distance,Z instanceof THREE.AmbientLight?Z.visible&&(Aa+=La.r,Ba+=La.g,Ca+=La.b):Z instanceof THREE.DirectionalLight?
-(Db+=1,Z.visible&&(fa.setFromMatrixPosition(Z.matrixWorld),ba.setFromMatrixPosition(Z.target.matrixWorld),fa.sub(ba),fa.transformDirection(db),fb=3*eb,ub[fb+0]=fa.x,ub[fb+1]=fa.y,ub[fb+2]=fa.z,w(tb,fb,La,Ua),eb+=1)):Z instanceof THREE.PointLight?(Eb+=1,Z.visible&&(gb=3*Ma,w(vb,gb,La,Ua),ba.setFromMatrixPosition(Z.matrixWorld),ba.applyMatrix4(db),wb[gb+0]=ba.x,wb[gb+1]=ba.y,wb[gb+2]=ba.z,kb[Ma]=sb,pb[Ma]=0===Z.distance?0:Z.decay,Ma+=1)):Z instanceof THREE.SpotLight?(Fb+=1,Z.visible&&(Ea=3*wa,w(xb,
-Ea,La,Ua),fa.setFromMatrixPosition(Z.matrixWorld),ba.copy(fa).applyMatrix4(db),yb[Ea+0]=ba.x,yb[Ea+1]=ba.y,yb[Ea+2]=ba.z,qb[wa]=sb,ba.setFromMatrixPosition(Z.target.matrixWorld),fa.sub(ba),fa.transformDirection(db),zb[Ea+0]=fa.x,zb[Ea+1]=fa.y,zb[Ea+2]=fa.z,Kb[wa]=Math.cos(Z.angle),Lb[wa]=Z.exponent,Mb[wa]=0===Z.distance?0:Z.decay,wa+=1)):Z instanceof THREE.HemisphereLight&&(mb+=1,Z.visible&&(fa.setFromMatrixPosition(Z.matrixWorld),fa.transformDirection(db),Wa=3*Va,Cb[Wa+0]=fa.x,Cb[Wa+1]=fa.y,Cb[Wa+
-2]=fa.z,Qa=Z.color,Ta=Z.groundColor,w(Ab,Wa,Qa,Ua),w(Bb,Wa,Ta,Ua),Va+=1)));aa=3*eb;for(oa=Math.max(tb.length,3*Db);aa<oa;aa++)tb[aa]=0;aa=3*Ma;for(oa=Math.max(vb.length,3*Eb);aa<oa;aa++)vb[aa]=0;aa=3*wa;for(oa=Math.max(xb.length,3*Fb);aa<oa;aa++)xb[aa]=0;aa=3*Va;for(oa=Math.max(Ab.length,3*mb);aa<oa;aa++)Ab[aa]=0;aa=3*Va;for(oa=Math.max(Bb.length,3*mb);aa<oa;aa++)Bb[aa]=0;da.directional.length=eb;da.point.length=Ma;da.spot.length=wa;da.hemi.length=Va;da.ambient[0]=Aa;da.ambient[1]=Ba;da.ambient[2]=
-Ca;jb=!1}if(sa){var ja=Pb;I.ambientLightColor.value=ja.ambient;I.directionalLightColor.value=ja.directional.colors;I.directionalLightDirection.value=ja.directional.positions;I.pointLightColor.value=ja.point.colors;I.pointLightPosition.value=ja.point.positions;I.pointLightDistance.value=ja.point.distances;I.pointLightDecay.value=ja.point.decays;I.spotLightColor.value=ja.spot.colors;I.spotLightPosition.value=ja.spot.positions;I.spotLightDistance.value=ja.spot.distances;I.spotLightDirection.value=ja.spot.directions;
-I.spotLightAngleCos.value=ja.spot.anglesCos;I.spotLightExponent.value=ja.spot.exponents;I.spotLightDecay.value=ja.spot.decays;I.hemisphereLightSkyColor.value=ja.hemi.skyColors;I.hemisphereLightGroundColor.value=ja.hemi.groundColors;I.hemisphereLightDirection.value=ja.hemi.positions;v(I,!0)}else v(I,!1)}if(d instanceof THREE.MeshBasicMaterial||d instanceof THREE.MeshLambertMaterial||d instanceof THREE.MeshPhongMaterial){I.opacity.value=d.opacity;I.diffuse.value=d.color;I.map.value=d.map;I.specularMap.value=
-d.specularMap;I.alphaMap.value=d.alphaMap;d.bumpMap&&(I.bumpMap.value=d.bumpMap,I.bumpScale.value=d.bumpScale);d.normalMap&&(I.normalMap.value=d.normalMap,I.normalScale.value.copy(d.normalScale));var xa;d.map?xa=d.map:d.specularMap?xa=d.specularMap:d.normalMap?xa=d.normalMap:d.bumpMap?xa=d.bumpMap:d.alphaMap?xa=d.alphaMap:d.emissiveMap&&(xa=d.emissiveMap);if(void 0!==xa){var Qb=xa.offset,Rb=xa.repeat;I.offsetRepeat.value.set(Qb.x,Qb.y,Rb.x,Rb.y)}I.envMap.value=d.envMap;I.flipEnvMap.value=d.envMap instanceof
+THREE.WebGLRenderer=function(a){function b(a,b,c,d){!0===R&&(a*=d,b*=d,c*=d);s.clearColor(a,b,c,d)}function c(){K.init();s.viewport(Ha,za,Aa,Ba);b(E.r,E.g,E.b,ja)}function d(){Za=rb=null;va="";$a=-1;jb=!0;K.reset()}function e(a){a.preventDefault();d();c();$.clear()}function g(a){a=a.target;a.removeEventListener("dispose",g);a:{var b=$.get(a);if(a.image&&b.__image__webglTextureCube)s.deleteTexture(b.__image__webglTextureCube);else{if(void 0===b.__webglInit)break a;s.deleteTexture(b.__webglTexture)}$.delete(a)}Ca.textures--}
+function f(a){a=a.target;a.removeEventListener("dispose",f);var b=$.get(a);if(a&&void 0!==b.__webglTexture){s.deleteTexture(b.__webglTexture);if(a instanceof THREE.WebGLRenderTargetCube)for(var c=0;6>c;c++)s.deleteFramebuffer(b.__webglFramebuffer[c]),s.deleteRenderbuffer(b.__webglRenderbuffer[c]);else s.deleteFramebuffer(b.__webglFramebuffer),s.deleteRenderbuffer(b.__webglRenderbuffer);$.delete(a)}Ca.textures--}function h(a){a=a.target;a.removeEventListener("dispose",h);k(a);$.delete(a)}function k(a){var b=
+$.get(a).program.program;if(void 0!==b){a.program=void 0;a=0;for(var c=qa.length;a!==c;++a){var d=qa[a];if(d.program===b){0===--d.usedTimes&&(c-=1,qa[a]=qa[c],qa.pop(),s.deleteProgram(b),Ca.programs=c);break}}}}function l(a,b){return b[0]-a[0]}function n(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 p(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 m(a,b,c,d,e){var f;c.transparent?(d=Da,f=++Ia):(d=la,f=++wa);f=d[f];void 0!==f?(f.id=a.id,f.object=a,f.geometry=b,f.material=c,f.z=ba.z,f.group=e):(f={id:a.id,object:a,geometry:b,material:c,z:ba.z,group:e},d.push(f))}function q(a){if(!1!==a.visible){if(a instanceof THREE.Light)Y.push(a);else if(a instanceof THREE.Sprite)Ra.push(a);else if(a instanceof THREE.LensFlare)ab.push(a);else if(a instanceof THREE.ImmediateRenderObject){var b,
+c;a.material.transparent?(b=Ja,c=++Ka):(b=ra,c=++bb);c<b.length?b[c]=a:b.push(a)}else if(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.PointCloud)if(a instanceof THREE.SkinnedMesh&&a.skeleton.update(),!1===a.frustumCulled||!0===kb.intersectsObject(a)){var d=a.material;if(!0===d.visible)if(!0===ka.sortObjects&&(ba.setFromMatrixPosition(a.matrixWorld),ba.applyProjection(Sa)),b=sa.update(a),d instanceof THREE.MeshFaceMaterial){c=b.groups;for(var e=d.materials,d=0,f=c.length;d<
+f;d++){var g=c[d],h=e[g.materialIndex];!0===h.visible&&m(a,b,h,ba.z,g)}}else m(a,b,d,ba.z)}a=a.children;d=0;for(f=a.length;d<f;d++)q(a[d])}}function t(a,b,c,d,e){for(var f=0,g=a.length;f<g;f++){var h=a[f],k=h.object,l=h.geometry,m=void 0===e?h.material:e,h=h.group;k.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,k.matrixWorld);k.normalMatrix.getNormalMatrix(k.modelViewMatrix);ka.renderBufferDirect(b,c,d,l,m,k,h)}}function r(a,b,c,d,e){for(var f=e,g=0,h=a.length;g<h;g++){var k=a[g];k.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,
+k.matrixWorld);k.normalMatrix.getNormalMatrix(k.modelViewMatrix);void 0===e&&(f=k.material);v(f);var l=w(b,c,d,f,k);va="";k.render(function(a){ka.renderBufferImmediate(a,l,f)})}}function v(a){a.side!==THREE.DoubleSide?K.enable(s.CULL_FACE):K.disable(s.CULL_FACE);K.setFlipSided(a.side===THREE.BackSide);!0===a.transparent?K.setBlending(a.blending,a.blendEquation,a.blendSrc,a.blendDst,a.blendEquationAlpha,a.blendSrcAlpha,a.blendDstAlpha):K.setBlending(THREE.NoBlending);K.setDepthFunc(a.depthFunc);K.setDepthTest(a.depthTest);
+K.setDepthWrite(a.depthWrite);K.setColorWrite(a.colorWrite);K.setPolygonOffset(a.polygonOffset,a.polygonOffsetFactor,a.polygonOffsetUnits)}function w(a,b,c,d,e){var f,l,m,n;lb=0;var q=$.get(d);if(d.needsUpdate||!q.program){a:{for(var p=$.get(d),t=$b[d.type],r=0,w=0,v=0,L=0,y=0,A=b.length;y<A;y++){var B=b[y];B.onlyShadow||!1===B.visible||(B instanceof THREE.DirectionalLight&&r++,B instanceof THREE.PointLight&&w++,B instanceof THREE.SpotLight&&v++,B instanceof THREE.HemisphereLight&&L++)}f=r;l=w;m=
+v;n=L;for(var G,H=0,J=0,E=b.length;J<E;J++){var P=b[J];P.castShadow&&(P instanceof THREE.SpotLight&&H++,P instanceof THREE.DirectionalLight&&H++)}G=H;var Q;if(ia.floatVertexTextures&&e&&e.skeleton&&e.skeleton.useVertexTexture)Q=1024;else{var O=s.getParameter(s.MAX_VERTEX_UNIFORM_VECTORS),wa=Math.floor((O-20)/4);void 0!==e&&e instanceof THREE.SkinnedMesh&&(wa=Math.min(e.skeleton.bones.length,wa),wa<e.skeleton.bones.length&&console.warn("WebGLRenderer: too many bones - "+e.skeleton.bones.length+", this GPU supports just "+
+wa+" (try OpenGL instead of ANGLE)"));Q=wa}var R=ia.precision;null!==d.precision&&(R=ia.getMaxPrecision(d.precision),R!==d.precision&&console.warn("THREE.WebGLRenderer.initMaterial:",d.precision,"not supported, using",R,"instead."));var V={precision:R,supportsVertexTextures:ia.vertexTextures,map:!!d.map,envMap:!!d.envMap,envMapMode:d.envMap&&d.envMap.mapping,lightMap:!!d.lightMap,aoMap:!!d.aoMap,emissiveMap:!!d.emissiveMap,bumpMap:!!d.bumpMap,normalMap:!!d.normalMap,specularMap:!!d.specularMap,alphaMap:!!d.alphaMap,
+combine:d.combine,vertexColors:d.vertexColors,fog:c,useFog:d.fog,fogExp:c instanceof THREE.FogExp2,flatShading:d.shading===THREE.FlatShading,sizeAttenuation:d.sizeAttenuation,logarithmicDepthBuffer:ia.logarithmicDepthBuffer,skinning:d.skinning,maxBones:Q,useVertexTexture:ia.floatVertexTextures&&e&&e.skeleton&&e.skeleton.useVertexTexture,morphTargets:d.morphTargets,morphNormals:d.morphNormals,maxMorphTargets:ka.maxMorphTargets,maxMorphNormals:ka.maxMorphNormals,maxDirLights:f,maxPointLights:l,maxSpotLights:m,
+maxHemiLights:n,maxShadows:G,shadowMapEnabled:ma.enabled&&e.receiveShadow&&0<G,shadowMapType:ma.type,shadowMapDebug:ma.debug,alphaTest:d.alphaTest,metal:d.metal,doubleSided:d.side===THREE.DoubleSide,flipSided:d.side===THREE.BackSide},S=[];t?S.push(t):(S.push(d.fragmentShader),S.push(d.vertexShader));if(void 0!==d.defines)for(var ra in d.defines)S.push(ra),S.push(d.defines[ra]);for(ra in V)S.push(ra),S.push(V[ra]);var W=S.join(),Da=!0;if(p.program)if(p.program.code!==W)k(d);else if(void 0!==t)break a;
+else Da=!1;else d.addEventListener("dispose",h);if(t){var Ia=THREE.ShaderLib[t];p.__webglShader={name:d.type,uniforms:THREE.UniformsUtils.clone(Ia.uniforms),vertexShader:Ia.vertexShader,fragmentShader:Ia.fragmentShader}}else p.__webglShader={name:d.type,uniforms:d.uniforms,vertexShader:d.vertexShader,fragmentShader:d.fragmentShader};for(var Y,Ka=0,bb=qa.length;Ka<bb;Ka++){var Ra=qa[Ka];if(Ra.code===W){Y=Ra;Da&&Y.usedTimes++;break}}void 0===Y&&(d.__webglShader=p.__webglShader,Y=new THREE.WebGLProgram(ka,
+W,d,V),qa.push(Y),Ca.programs=qa.length);p.program=Y;d.program=Y;var Ja=Y.getAttributes();if(d.morphTargets)for(var ta=d.numSupportedMorphTargets=0;ta<ka.maxMorphTargets;ta++)0<=Ja["morphTarget"+ta]&&d.numSupportedMorphTargets++;if(d.morphNormals)for(ta=d.numSupportedMorphNormals=0;ta<ka.maxMorphNormals;ta++)0<=Ja["morphNormal"+ta]&&d.numSupportedMorphNormals++;p.uniformsList=[];var ab=p.program.getUniforms(),ja;for(ja in p.__webglShader.uniforms){var la=ab[ja];la&&p.uniformsList.push([p.__webglShader.uniforms[ja],
+la])}}d.needsUpdate=!1}var ua=!1,va=!1,sa=!1,cb=q.program,ca=cb.getUniforms(),I=q.__webglShader.uniforms;cb.id!==rb&&(s.useProgram(cb.program),rb=cb.id,sa=va=ua=!0);d.id!==$a&&(-1===$a&&(sa=!0),$a=d.id,va=!0);if(ua||a!==Za)s.uniformMatrix4fv(ca.projectionMatrix,!1,a.projectionMatrix.elements),ia.logarithmicDepthBuffer&&s.uniform1f(ca.logDepthBufFC,2/(Math.log(a.far+1)/Math.LN2)),a!==Za&&(Za=a),(d instanceof THREE.ShaderMaterial||d instanceof THREE.MeshPhongMaterial||d.envMap)&&void 0!==ca.cameraPosition&&
+(ba.setFromMatrixPosition(a.matrixWorld),s.uniform3f(ca.cameraPosition,ba.x,ba.y,ba.z)),(d instanceof THREE.MeshPhongMaterial||d instanceof THREE.MeshLambertMaterial||d instanceof THREE.MeshBasicMaterial||d instanceof THREE.ShaderMaterial||d.skinning)&&void 0!==ca.viewMatrix&&s.uniformMatrix4fv(ca.viewMatrix,!1,a.matrixWorldInverse.elements);if(d.skinning)if(e.bindMatrix&&void 0!==ca.bindMatrix&&s.uniformMatrix4fv(ca.bindMatrix,!1,e.bindMatrix.elements),e.bindMatrixInverse&&void 0!==ca.bindMatrixInverse&&
+s.uniformMatrix4fv(ca.bindMatrixInverse,!1,e.bindMatrixInverse.elements),ia.floatVertexTextures&&e.skeleton&&e.skeleton.useVertexTexture){if(void 0!==ca.boneTexture){var Ha=z();s.uniform1i(ca.boneTexture,Ha);ka.setTexture(e.skeleton.boneTexture,Ha)}void 0!==ca.boneTextureWidth&&s.uniform1i(ca.boneTextureWidth,e.skeleton.boneTextureWidth);void 0!==ca.boneTextureHeight&&s.uniform1i(ca.boneTextureHeight,e.skeleton.boneTextureHeight)}else e.skeleton&&e.skeleton.boneMatrices&&void 0!==ca.boneGlobalMatrices&&
+s.uniformMatrix4fv(ca.boneGlobalMatrices,!1,e.skeleton.boneMatrices);if(va){c&&d.fog&&(I.fogColor.value=c.color,c instanceof THREE.Fog?(I.fogNear.value=c.near,I.fogFar.value=c.far):c instanceof THREE.FogExp2&&(I.fogDensity.value=c.density));if(d instanceof THREE.MeshPhongMaterial||d instanceof THREE.MeshLambertMaterial||d.lights){if(jb){var sa=!0,aa,oa,Z,za=0,Aa=0,Ba=0,La,Qa,Sa,Ta,sb,da=Pb,db=a.matrixWorldInverse,tb=da.directional.colors,ub=da.directional.positions,vb=da.point.colors,wb=da.point.positions,
+kb=da.point.distances,pb=da.point.decays,xb=da.spot.colors,yb=da.spot.positions,qb=da.spot.distances,zb=da.spot.directions,Kb=da.spot.anglesCos,Lb=da.spot.exponents,Mb=da.spot.decays,Ab=da.hemi.skyColors,Bb=da.hemi.groundColors,Cb=da.hemi.positions,eb=0,Ma=0,xa=0,Ua=0,Db=0,Eb=0,Fb=0,mb=0,fb=0,gb=0,Ea=0,Va=0;aa=0;for(oa=b.length;aa<oa;aa++)Z=b[aa],Z.onlyShadow||(La=Z.color,Ta=Z.intensity,sb=Z.distance,Z instanceof THREE.AmbientLight?Z.visible&&(za+=La.r,Aa+=La.g,Ba+=La.b):Z instanceof THREE.DirectionalLight?
+(Db+=1,Z.visible&&(fa.setFromMatrixPosition(Z.matrixWorld),ba.setFromMatrixPosition(Z.target.matrixWorld),fa.sub(ba),fa.transformDirection(db),fb=3*eb,ub[fb+0]=fa.x,ub[fb+1]=fa.y,ub[fb+2]=fa.z,x(tb,fb,La,Ta),eb+=1)):Z instanceof THREE.PointLight?(Eb+=1,Z.visible&&(gb=3*Ma,x(vb,gb,La,Ta),ba.setFromMatrixPosition(Z.matrixWorld),ba.applyMatrix4(db),wb[gb+0]=ba.x,wb[gb+1]=ba.y,wb[gb+2]=ba.z,kb[Ma]=sb,pb[Ma]=0===Z.distance?0:Z.decay,Ma+=1)):Z instanceof THREE.SpotLight?(Fb+=1,Z.visible&&(Ea=3*xa,x(xb,
+Ea,La,Ta),fa.setFromMatrixPosition(Z.matrixWorld),ba.copy(fa).applyMatrix4(db),yb[Ea+0]=ba.x,yb[Ea+1]=ba.y,yb[Ea+2]=ba.z,qb[xa]=sb,ba.setFromMatrixPosition(Z.target.matrixWorld),fa.sub(ba),fa.transformDirection(db),zb[Ea+0]=fa.x,zb[Ea+1]=fa.y,zb[Ea+2]=fa.z,Kb[xa]=Math.cos(Z.angle),Lb[xa]=Z.exponent,Mb[xa]=0===Z.distance?0:Z.decay,xa+=1)):Z instanceof THREE.HemisphereLight&&(mb+=1,Z.visible&&(fa.setFromMatrixPosition(Z.matrixWorld),fa.transformDirection(db),Va=3*Ua,Cb[Va+0]=fa.x,Cb[Va+1]=fa.y,Cb[Va+
+2]=fa.z,Qa=Z.color,Sa=Z.groundColor,x(Ab,Va,Qa,Ta),x(Bb,Va,Sa,Ta),Ua+=1)));aa=3*eb;for(oa=Math.max(tb.length,3*Db);aa<oa;aa++)tb[aa]=0;aa=3*Ma;for(oa=Math.max(vb.length,3*Eb);aa<oa;aa++)vb[aa]=0;aa=3*xa;for(oa=Math.max(xb.length,3*Fb);aa<oa;aa++)xb[aa]=0;aa=3*Ua;for(oa=Math.max(Ab.length,3*mb);aa<oa;aa++)Ab[aa]=0;aa=3*Ua;for(oa=Math.max(Bb.length,3*mb);aa<oa;aa++)Bb[aa]=0;da.directional.length=eb;da.point.length=Ma;da.spot.length=xa;da.hemi.length=Ua;da.ambient[0]=za;da.ambient[1]=Aa;da.ambient[2]=
+Ba;jb=!1}if(sa){var ha=Pb;I.ambientLightColor.value=ha.ambient;I.directionalLightColor.value=ha.directional.colors;I.directionalLightDirection.value=ha.directional.positions;I.pointLightColor.value=ha.point.colors;I.pointLightPosition.value=ha.point.positions;I.pointLightDistance.value=ha.point.distances;I.pointLightDecay.value=ha.point.decays;I.spotLightColor.value=ha.spot.colors;I.spotLightPosition.value=ha.spot.positions;I.spotLightDistance.value=ha.spot.distances;I.spotLightDirection.value=ha.spot.directions;
+I.spotLightAngleCos.value=ha.spot.anglesCos;I.spotLightExponent.value=ha.spot.exponents;I.spotLightDecay.value=ha.spot.decays;I.hemisphereLightSkyColor.value=ha.hemi.skyColors;I.hemisphereLightGroundColor.value=ha.hemi.groundColors;I.hemisphereLightDirection.value=ha.hemi.positions;u(I,!0)}else u(I,!1)}if(d instanceof THREE.MeshBasicMaterial||d instanceof THREE.MeshLambertMaterial||d instanceof THREE.MeshPhongMaterial){I.opacity.value=d.opacity;I.diffuse.value=d.color;I.map.value=d.map;I.specularMap.value=
+d.specularMap;I.alphaMap.value=d.alphaMap;d.bumpMap&&(I.bumpMap.value=d.bumpMap,I.bumpScale.value=d.bumpScale);d.normalMap&&(I.normalMap.value=d.normalMap,I.normalScale.value.copy(d.normalScale));var ya;d.map?ya=d.map:d.specularMap?ya=d.specularMap:d.normalMap?ya=d.normalMap:d.bumpMap?ya=d.bumpMap:d.alphaMap?ya=d.alphaMap:d.emissiveMap&&(ya=d.emissiveMap);if(void 0!==ya){var Qb=ya.offset,Rb=ya.repeat;I.offsetRepeat.value.set(Qb.x,Qb.y,Rb.x,Rb.y)}I.envMap.value=d.envMap;I.flipEnvMap.value=d.envMap instanceof
 THREE.WebGLRenderTargetCube?1:-1;I.reflectivity.value=d.reflectivity;I.refractionRatio.value=d.refractionRatio}if(d instanceof THREE.LineBasicMaterial)I.diffuse.value=d.color,I.opacity.value=d.opacity;else if(d instanceof THREE.LineDashedMaterial)I.diffuse.value=d.color,I.opacity.value=d.opacity,I.dashSize.value=d.dashSize,I.totalSize.value=d.dashSize+d.gapSize,I.scale.value=d.scale;else if(d instanceof THREE.PointCloudMaterial){if(I.psColor.value=d.color,I.opacity.value=d.opacity,I.size.value=d.size,
-I.scale.value=D.height/2,I.map.value=d.map,null!==d.map){var Sb=d.map.offset,Tb=d.map.repeat;I.offsetRepeat.value.set(Sb.x,Sb.y,Tb.x,Tb.y)}}else d instanceof THREE.MeshPhongMaterial?(I.shininess.value=d.shininess,I.emissive.value=d.emissive,I.specular.value=d.specular,I.lightMap.value=d.lightMap,I.lightMapIntensity.value=d.lightMapIntensity,I.aoMap.value=d.aoMap,I.aoMapIntensity.value=d.aoMapIntensity,I.emissiveMap.value=d.emissiveMap):d instanceof THREE.MeshLambertMaterial?I.emissive.value=d.emissive:
-d instanceof THREE.MeshBasicMaterial?(I.aoMap.value=d.aoMap,I.aoMapIntensity.value=d.aoMapIntensity):d instanceof THREE.MeshDepthMaterial?(I.mNear.value=a.near,I.mFar.value=a.far,I.opacity.value=d.opacity):d instanceof THREE.MeshNormalMaterial&&(I.opacity.value=d.opacity);if(e.receiveShadow&&!d._shadowPass&&I.shadowMatrix)for(var Xa=0,Gb=0,Nb=b.length;Gb<Nb;Gb++){var Fa=b[Gb];Fa.castShadow&&(Fa instanceof THREE.SpotLight||Fa instanceof THREE.DirectionalLight)&&(I.shadowMap.value[Xa]=Fa.shadowMap,
-I.shadowMapSize.value[Xa]=Fa.shadowMapSize,I.shadowMatrix.value[Xa]=Fa.shadowMatrix,I.shadowDarkness.value[Xa]=Fa.shadowDarkness,I.shadowBias.value[Xa]=Fa.shadowBias,Xa++)}for(var Hb=q.uniformsList,pa,Na,nb=0,Ob=Hb.length;nb<Ob;nb++){var T=Hb[nb][0];if(!1!==T.needsUpdate){var Ub=T.type,M=T.value,Y=Hb[nb][1];switch(Ub){case "1i":t.uniform1i(Y,M);break;case "1f":t.uniform1f(Y,M);break;case "2f":t.uniform2f(Y,M[0],M[1]);break;case "3f":t.uniform3f(Y,M[0],M[1],M[2]);break;case "4f":t.uniform4f(Y,M[0],
-M[1],M[2],M[3]);break;case "1iv":t.uniform1iv(Y,M);break;case "3iv":t.uniform3iv(Y,M);break;case "1fv":t.uniform1fv(Y,M);break;case "2fv":t.uniform2fv(Y,M);break;case "3fv":t.uniform3fv(Y,M);break;case "4fv":t.uniform4fv(Y,M);break;case "Matrix3fv":t.uniformMatrix3fv(Y,!1,M);break;case "Matrix4fv":t.uniformMatrix4fv(Y,!1,M);break;case "i":t.uniform1i(Y,M);break;case "f":t.uniform1f(Y,M);break;case "v2":t.uniform2f(Y,M.x,M.y);break;case "v3":t.uniform3f(Y,M.x,M.y,M.z);break;case "v4":t.uniform4f(Y,
-M.x,M.y,M.z,M.w);break;case "c":t.uniform3f(Y,M.r,M.g,M.b);break;case "iv1":t.uniform1iv(Y,M);break;case "iv":t.uniform3iv(Y,M);break;case "fv1":t.uniform1fv(Y,M);break;case "fv":t.uniform3fv(Y,M);break;case "v2v":void 0===T._array&&(T._array=new Float32Array(2*M.length));for(var V=0,ob=0,na=M.length;V<na;V++,ob+=2)T._array[ob+0]=M[V].x,T._array[ob+1]=M[V].y;t.uniform2fv(Y,T._array);break;case "v3v":void 0===T._array&&(T._array=new Float32Array(3*M.length));for(var hb=V=0,na=M.length;V<na;V++,hb+=
-3)T._array[hb+0]=M[V].x,T._array[hb+1]=M[V].y,T._array[hb+2]=M[V].z;t.uniform3fv(Y,T._array);break;case "v4v":void 0===T._array&&(T._array=new Float32Array(4*M.length));for(var Ya=V=0,na=M.length;V<na;V++,Ya+=4)T._array[Ya+0]=M[V].x,T._array[Ya+1]=M[V].y,T._array[Ya+2]=M[V].z,T._array[Ya+3]=M[V].w;t.uniform4fv(Y,T._array);break;case "m3":t.uniformMatrix3fv(Y,!1,M.elements);break;case "m3v":void 0===T._array&&(T._array=new Float32Array(9*M.length));V=0;for(na=M.length;V<na;V++)M[V].flattenToArrayOffset(T._array,
-9*V);t.uniformMatrix3fv(Y,!1,T._array);break;case "m4":t.uniformMatrix4fv(Y,!1,M.elements);break;case "m4v":void 0===T._array&&(T._array=new Float32Array(16*M.length));V=0;for(na=M.length;V<na;V++)M[V].flattenToArrayOffset(T._array,16*V);t.uniformMatrix4fv(Y,!1,T._array);break;case "t":pa=M;Na=y();t.uniform1i(Y,Na);if(!pa)continue;if(pa instanceof THREE.CubeTexture||Array.isArray(pa.image)&&6===pa.image.length){var ea=pa,Vb=Na,Za=$.get(ea);if(6===ea.image.length)if(0<ea.version&&Za.__version!==ea.version){Za.__image__webglTextureCube||
-(ea.addEventListener("dispose",g),Za.__image__webglTextureCube=t.createTexture(),Da.textures++);L.activeTexture(t.TEXTURE0+Vb);L.bindTexture(t.TEXTURE_CUBE_MAP,Za.__image__webglTextureCube);t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,ea.flipY);for(var Wb=ea instanceof THREE.CompressedTexture,Ib=ea.image[0]instanceof THREE.DataTexture,Oa=[],ga=0;6>ga;ga++)Oa[ga]=!la.autoScaleCubemaps||Wb||Ib?Ib?ea.image[ga].image:ea.image[ga]:B(ea.image[ga],ka.maxCubemapSize);var Xb=Oa[0],Yb=THREE.Math.isPowerOfTwo(Xb.width)&&
-THREE.Math.isPowerOfTwo(Xb.height),Ga=K(ea.format),Jb=K(ea.type);G(t.TEXTURE_CUBE_MAP,ea,Yb);for(ga=0;6>ga;ga++)if(Wb)for(var Pa,Zb=Oa[ga].mipmaps,ib=0,ac=Zb.length;ib<ac;ib++)Pa=Zb[ib],ea.format!==THREE.RGBAFormat&&ea.format!==THREE.RGBFormat?-1<L.getCompressedTextureFormats().indexOf(Ga)?L.compressedTexImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+ga,ib,Ga,Pa.width,Pa.height,0,Pa.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()"):L.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+
-ga,ib,Ga,Pa.width,Pa.height,0,Ga,Jb,Pa.data);else Ib?L.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+ga,0,Ga,Oa[ga].width,Oa[ga].height,0,Ga,Jb,Oa[ga].data):L.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+ga,0,Ga,Ga,Jb,Oa[ga]);ea.generateMipmaps&&Yb&&t.generateMipmap(t.TEXTURE_CUBE_MAP);Za.__version=ea.version;if(ea.onUpdate)ea.onUpdate(ea)}else L.activeTexture(t.TEXTURE0+Vb),L.bindTexture(t.TEXTURE_CUBE_MAP,Za.__image__webglTextureCube)}else if(pa instanceof THREE.WebGLRenderTargetCube){var bc=pa;L.activeTexture(t.TEXTURE0+
-Na);L.bindTexture(t.TEXTURE_CUBE_MAP,$.get(bc).__webglTexture)}else la.setTexture(pa,Na);break;case "tv":void 0===T._array&&(T._array=[]);V=0;for(na=T.value.length;V<na;V++)T._array[V]=y();t.uniform1iv(Y,T._array);V=0;for(na=T.value.length;V<na;V++)pa=T.value[V],Na=T._array[V],pa&&la.setTexture(pa,Na);break;default:console.warn("THREE.WebGLRenderer: Unknown uniform type: "+Ub)}}}}t.uniformMatrix4fv(ca.modelViewMatrix,!1,e.modelViewMatrix.elements);ca.normalMatrix&&t.uniformMatrix3fv(ca.normalMatrix,
-!1,e.normalMatrix.elements);void 0!==ca.modelMatrix&&t.uniformMatrix4fv(ca.modelMatrix,!1,e.matrixWorld.elements);return cb}function v(a,b){a.ambientLightColor.needsUpdate=b;a.directionalLightColor.needsUpdate=b;a.directionalLightDirection.needsUpdate=b;a.pointLightColor.needsUpdate=b;a.pointLightPosition.needsUpdate=b;a.pointLightDistance.needsUpdate=b;a.pointLightDecay.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.spotLightDecay.needsUpdate=b;a.hemisphereLightSkyColor.needsUpdate=b;a.hemisphereLightGroundColor.needsUpdate=b;a.hemisphereLightDirection.needsUpdate=b}function y(){var a=lb;a>=ka.maxTextures&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+ka.maxTextures);lb+=1;return a}function w(a,b,c,d){a[b+0]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a,b,c){c?(t.texParameteri(a,t.TEXTURE_WRAP_S,
-K(b.wrapS)),t.texParameteri(a,t.TEXTURE_WRAP_T,K(b.wrapT)),t.texParameteri(a,t.TEXTURE_MAG_FILTER,K(b.magFilter)),t.texParameteri(a,t.TEXTURE_MIN_FILTER,K(b.minFilter))):(t.texParameteri(a,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(a,t.TEXTURE_WRAP_T,t.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 should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+
-" )"),t.texParameteri(a,t.TEXTURE_MAG_FILTER,O(b.magFilter)),t.texParameteri(a,t.TEXTURE_MIN_FILTER,O(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));!(c=W.get("EXT_texture_filter_anisotropic"))||b.type===THREE.FloatType&&null===W.get("OES_texture_float_linear")||b.type===THREE.HalfFloatType&&null===
-W.get("OES_texture_half_float_linear")||!(1<b.anisotropy||$.get(b).__currentAnisotropy)||(t.texParameterf(a,c.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(b.anisotropy,la.getMaxAnisotropy())),$.get(b).__currentAnisotropy=b.anisotropy)}function B(a,b){if(a.width>b||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.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 z(a,b,c){t.bindFramebuffer(t.FRAMEBUFFER,a);t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,c,$.get(b).__webglTexture,0)}function A(a,b){t.bindRenderbuffer(t.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_COMPONENT16,b.width,b.height),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(t.renderbufferStorage(t.RENDERBUFFER,
-t.DEPTH_STENCIL,b.width,b.height),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,a)):t.renderbufferStorage(t.RENDERBUFFER,t.RGBA4,b.width,b.height)}function O(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?t.NEAREST:t.LINEAR}function K(a){var b;if(a===THREE.RepeatWrapping)return t.REPEAT;if(a===THREE.ClampToEdgeWrapping)return t.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return t.MIRRORED_REPEAT;
-if(a===THREE.NearestFilter)return t.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return t.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return t.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return t.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return t.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return t.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return t.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return t.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return t.UNSIGNED_SHORT_5_5_5_1;
-if(a===THREE.UnsignedShort565Type)return t.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return t.BYTE;if(a===THREE.ShortType)return t.SHORT;if(a===THREE.UnsignedShortType)return t.UNSIGNED_SHORT;if(a===THREE.IntType)return t.INT;if(a===THREE.UnsignedIntType)return t.UNSIGNED_INT;if(a===THREE.FloatType)return t.FLOAT;b=W.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return t.ALPHA;if(a===THREE.RGBFormat)return t.RGB;if(a===THREE.RGBAFormat)return t.RGBA;
-if(a===THREE.LuminanceFormat)return t.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return t.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return t.FUNC_ADD;if(a===THREE.SubtractEquation)return t.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return t.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return t.ZERO;if(a===THREE.OneFactor)return t.ONE;if(a===THREE.SrcColorFactor)return t.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return t.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return t.SRC_ALPHA;
-if(a===THREE.OneMinusSrcAlphaFactor)return t.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return t.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return t.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return t.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return t.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return t.SRC_ALPHA_SATURATE;b=W.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;
+I.scale.value=C.height/2,I.map.value=d.map,null!==d.map){var Sb=d.map.offset,Tb=d.map.repeat;I.offsetRepeat.value.set(Sb.x,Sb.y,Tb.x,Tb.y)}}else d instanceof THREE.MeshPhongMaterial?(I.shininess.value=d.shininess,I.emissive.value=d.emissive,I.specular.value=d.specular,I.lightMap.value=d.lightMap,I.lightMapIntensity.value=d.lightMapIntensity,I.aoMap.value=d.aoMap,I.aoMapIntensity.value=d.aoMapIntensity,I.emissiveMap.value=d.emissiveMap):d instanceof THREE.MeshLambertMaterial?I.emissive.value=d.emissive:
+d instanceof THREE.MeshBasicMaterial?(I.aoMap.value=d.aoMap,I.aoMapIntensity.value=d.aoMapIntensity):d instanceof THREE.MeshDepthMaterial?(I.mNear.value=a.near,I.mFar.value=a.far,I.opacity.value=d.opacity):d instanceof THREE.MeshNormalMaterial&&(I.opacity.value=d.opacity);if(e.receiveShadow&&!d._shadowPass&&I.shadowMatrix)for(var Wa=0,Gb=0,Nb=b.length;Gb<Nb;Gb++){var Fa=b[Gb];Fa.castShadow&&(Fa instanceof THREE.SpotLight||Fa instanceof THREE.DirectionalLight)&&(I.shadowMap.value[Wa]=Fa.shadowMap,
+I.shadowMapSize.value[Wa]=Fa.shadowMapSize,I.shadowMatrix.value[Wa]=Fa.shadowMatrix,I.shadowDarkness.value[Wa]=Fa.shadowDarkness,I.shadowBias.value[Wa]=Fa.shadowBias,Wa++)}for(var Hb=q.uniformsList,pa,Na,nb=0,Ob=Hb.length;nb<Ob;nb++){var T=Hb[nb][0];if(!1!==T.needsUpdate){var Ub=T.type,M=T.value,X=Hb[nb][1];switch(Ub){case "1i":s.uniform1i(X,M);break;case "1f":s.uniform1f(X,M);break;case "2f":s.uniform2f(X,M[0],M[1]);break;case "3f":s.uniform3f(X,M[0],M[1],M[2]);break;case "4f":s.uniform4f(X,M[0],
+M[1],M[2],M[3]);break;case "1iv":s.uniform1iv(X,M);break;case "3iv":s.uniform3iv(X,M);break;case "1fv":s.uniform1fv(X,M);break;case "2fv":s.uniform2fv(X,M);break;case "3fv":s.uniform3fv(X,M);break;case "4fv":s.uniform4fv(X,M);break;case "Matrix3fv":s.uniformMatrix3fv(X,!1,M);break;case "Matrix4fv":s.uniformMatrix4fv(X,!1,M);break;case "i":s.uniform1i(X,M);break;case "f":s.uniform1f(X,M);break;case "v2":s.uniform2f(X,M.x,M.y);break;case "v3":s.uniform3f(X,M.x,M.y,M.z);break;case "v4":s.uniform4f(X,
+M.x,M.y,M.z,M.w);break;case "c":s.uniform3f(X,M.r,M.g,M.b);break;case "iv1":s.uniform1iv(X,M);break;case "iv":s.uniform3iv(X,M);break;case "fv1":s.uniform1fv(X,M);break;case "fv":s.uniform3fv(X,M);break;case "v2v":void 0===T._array&&(T._array=new Float32Array(2*M.length));for(var U=0,ob=0,na=M.length;U<na;U++,ob+=2)T._array[ob+0]=M[U].x,T._array[ob+1]=M[U].y;s.uniform2fv(X,T._array);break;case "v3v":void 0===T._array&&(T._array=new Float32Array(3*M.length));for(var hb=U=0,na=M.length;U<na;U++,hb+=
+3)T._array[hb+0]=M[U].x,T._array[hb+1]=M[U].y,T._array[hb+2]=M[U].z;s.uniform3fv(X,T._array);break;case "v4v":void 0===T._array&&(T._array=new Float32Array(4*M.length));for(var Xa=U=0,na=M.length;U<na;U++,Xa+=4)T._array[Xa+0]=M[U].x,T._array[Xa+1]=M[U].y,T._array[Xa+2]=M[U].z,T._array[Xa+3]=M[U].w;s.uniform4fv(X,T._array);break;case "m3":s.uniformMatrix3fv(X,!1,M.elements);break;case "m3v":void 0===T._array&&(T._array=new Float32Array(9*M.length));U=0;for(na=M.length;U<na;U++)M[U].flattenToArrayOffset(T._array,
+9*U);s.uniformMatrix3fv(X,!1,T._array);break;case "m4":s.uniformMatrix4fv(X,!1,M.elements);break;case "m4v":void 0===T._array&&(T._array=new Float32Array(16*M.length));U=0;for(na=M.length;U<na;U++)M[U].flattenToArrayOffset(T._array,16*U);s.uniformMatrix4fv(X,!1,T._array);break;case "t":pa=M;Na=z();s.uniform1i(X,Na);if(!pa)continue;if(pa instanceof THREE.CubeTexture||Array.isArray(pa.image)&&6===pa.image.length){var ea=pa,Vb=Na,Ya=$.get(ea);if(6===ea.image.length)if(0<ea.version&&Ya.__version!==ea.version){Ya.__image__webglTextureCube||
+(ea.addEventListener("dispose",g),Ya.__image__webglTextureCube=s.createTexture(),Ca.textures++);K.activeTexture(s.TEXTURE0+Vb);K.bindTexture(s.TEXTURE_CUBE_MAP,Ya.__image__webglTextureCube);s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,ea.flipY);for(var Wb=ea instanceof THREE.CompressedTexture,Ib=ea.image[0]instanceof THREE.DataTexture,Oa=[],ga=0;6>ga;ga++)Oa[ga]=!ka.autoScaleCubemaps||Wb||Ib?Ib?ea.image[ga].image:ea.image[ga]:F(ea.image[ga],ia.maxCubemapSize);var Xb=Oa[0],Yb=THREE.Math.isPowerOfTwo(Xb.width)&&
+THREE.Math.isPowerOfTwo(Xb.height),Ga=N(ea.format),Jb=N(ea.type);D(s.TEXTURE_CUBE_MAP,ea,Yb);for(ga=0;6>ga;ga++)if(Wb)for(var Pa,Zb=Oa[ga].mipmaps,ib=0,ac=Zb.length;ib<ac;ib++)Pa=Zb[ib],ea.format!==THREE.RGBAFormat&&ea.format!==THREE.RGBFormat?-1<K.getCompressedTextureFormats().indexOf(Ga)?K.compressedTexImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+ga,ib,Ga,Pa.width,Pa.height,0,Pa.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()"):K.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+
+ga,ib,Ga,Pa.width,Pa.height,0,Ga,Jb,Pa.data);else Ib?K.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+ga,0,Ga,Oa[ga].width,Oa[ga].height,0,Ga,Jb,Oa[ga].data):K.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+ga,0,Ga,Ga,Jb,Oa[ga]);ea.generateMipmaps&&Yb&&s.generateMipmap(s.TEXTURE_CUBE_MAP);Ya.__version=ea.version;if(ea.onUpdate)ea.onUpdate(ea)}else K.activeTexture(s.TEXTURE0+Vb),K.bindTexture(s.TEXTURE_CUBE_MAP,Ya.__image__webglTextureCube)}else if(pa instanceof THREE.WebGLRenderTargetCube){var bc=pa;K.activeTexture(s.TEXTURE0+
+Na);K.bindTexture(s.TEXTURE_CUBE_MAP,$.get(bc).__webglTexture)}else ka.setTexture(pa,Na);break;case "tv":void 0===T._array&&(T._array=[]);U=0;for(na=T.value.length;U<na;U++)T._array[U]=z();s.uniform1iv(X,T._array);U=0;for(na=T.value.length;U<na;U++)pa=T.value[U],Na=T._array[U],pa&&ka.setTexture(pa,Na);break;default:console.warn("THREE.WebGLRenderer: Unknown uniform type: "+Ub)}}}}s.uniformMatrix4fv(ca.modelViewMatrix,!1,e.modelViewMatrix.elements);ca.normalMatrix&&s.uniformMatrix3fv(ca.normalMatrix,
+!1,e.normalMatrix.elements);void 0!==ca.modelMatrix&&s.uniformMatrix4fv(ca.modelMatrix,!1,e.matrixWorld.elements);return cb}function u(a,b){a.ambientLightColor.needsUpdate=b;a.directionalLightColor.needsUpdate=b;a.directionalLightDirection.needsUpdate=b;a.pointLightColor.needsUpdate=b;a.pointLightPosition.needsUpdate=b;a.pointLightDistance.needsUpdate=b;a.pointLightDecay.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.spotLightDecay.needsUpdate=b;a.hemisphereLightSkyColor.needsUpdate=b;a.hemisphereLightGroundColor.needsUpdate=b;a.hemisphereLightDirection.needsUpdate=b}function z(){var a=lb;a>=ia.maxTextures&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+ia.maxTextures);lb+=1;return a}function x(a,b,c,d){a[b+0]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function D(a,b,c){c?(s.texParameteri(a,s.TEXTURE_WRAP_S,
+N(b.wrapS)),s.texParameteri(a,s.TEXTURE_WRAP_T,N(b.wrapT)),s.texParameteri(a,s.TEXTURE_MAG_FILTER,N(b.magFilter)),s.texParameteri(a,s.TEXTURE_MIN_FILTER,N(b.minFilter))):(s.texParameteri(a,s.TEXTURE_WRAP_S,s.CLAMP_TO_EDGE),s.texParameteri(a,s.TEXTURE_WRAP_T,s.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 should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+
+" )"),s.texParameteri(a,s.TEXTURE_MAG_FILTER,L(b.magFilter)),s.texParameteri(a,s.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 should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));!(c=W.get("EXT_texture_filter_anisotropic"))||b.type===THREE.FloatType&&null===W.get("OES_texture_float_linear")||b.type===THREE.HalfFloatType&&null===
+W.get("OES_texture_half_float_linear")||!(1<b.anisotropy||$.get(b).__currentAnisotropy)||(s.texParameterf(a,c.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(b.anisotropy,ka.getMaxAnisotropy())),$.get(b).__currentAnisotropy=b.anisotropy)}function F(a,b){if(a.width>b||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.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 y(a,b,c){s.bindFramebuffer(s.FRAMEBUFFER,a);s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,c,$.get(b).__webglTexture,0)}function B(a,b){s.bindRenderbuffer(s.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(s.renderbufferStorage(s.RENDERBUFFER,s.DEPTH_COMPONENT16,b.width,b.height),s.framebufferRenderbuffer(s.FRAMEBUFFER,s.DEPTH_ATTACHMENT,s.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(s.renderbufferStorage(s.RENDERBUFFER,
+s.DEPTH_STENCIL,b.width,b.height),s.framebufferRenderbuffer(s.FRAMEBUFFER,s.DEPTH_STENCIL_ATTACHMENT,s.RENDERBUFFER,a)):s.renderbufferStorage(s.RENDERBUFFER,s.RGBA4,b.width,b.height)}function L(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?s.NEAREST:s.LINEAR}function N(a){var b;if(a===THREE.RepeatWrapping)return s.REPEAT;if(a===THREE.ClampToEdgeWrapping)return s.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return s.MIRRORED_REPEAT;
+if(a===THREE.NearestFilter)return s.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return s.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return s.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return s.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return s.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return s.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return s.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return s.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return s.UNSIGNED_SHORT_5_5_5_1;
+if(a===THREE.UnsignedShort565Type)return s.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return s.BYTE;if(a===THREE.ShortType)return s.SHORT;if(a===THREE.UnsignedShortType)return s.UNSIGNED_SHORT;if(a===THREE.IntType)return s.INT;if(a===THREE.UnsignedIntType)return s.UNSIGNED_INT;if(a===THREE.FloatType)return s.FLOAT;b=W.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return s.ALPHA;if(a===THREE.RGBFormat)return s.RGB;if(a===THREE.RGBAFormat)return s.RGBA;
+if(a===THREE.LuminanceFormat)return s.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return s.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return s.FUNC_ADD;if(a===THREE.SubtractEquation)return s.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return s.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return s.ZERO;if(a===THREE.OneFactor)return s.ONE;if(a===THREE.SrcColorFactor)return s.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return s.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return s.SRC_ALPHA;
+if(a===THREE.OneMinusSrcAlphaFactor)return s.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return s.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return s.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return s.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return s.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return s.SRC_ALPHA_SATURATE;b=W.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=W.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=
-W.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 D=void 0!==a.canvas?a.canvas:document.createElement("canvas"),P=void 0!==a.context?a.context:null,J=D.width,H=D.height,C=1,F=void 0!==a.alpha?a.alpha:!1,N=void 0!==a.depth?a.depth:!0,R=void 0!==a.stencil?a.stencil:!0,U=void 0!==a.antialias?a.antialias:!1,Q=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:
-!0,S=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,E=new THREE.Color(0),ha=0,X=[],ia=[],za=-1,ya=[],Ha=-1,qa=[],bb=-1,Ja=[],Ka=-1,ta=new Float32Array(8),Ra=[],Sa=[];this.domElement=D;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.gammaOutput=this.gammaInput=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;var la=this,ra=[],rb=null,Qa=null,ab=-1,va="",$a=null,lb=0,Ia=
-0,Aa=0,Ba=D.width,Ca=D.height,pb=0,qb=0,kb=new THREE.Frustum,Ta=new THREE.Matrix4,ba=new THREE.Vector3,fa=new THREE.Vector3,jb=!0,Pb={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:[]}},Da={programs:0,geometries:0,textures:0},ua={calls:0,vertices:0,faces:0,points:0};
-this.info={render:ua,memory:Da,programs:ra};var t;try{F={alpha:F,depth:N,stencil:R,antialias:U,premultipliedAlpha:Q,preserveDrawingBuffer:S};t=P||D.getContext("webgl",F)||D.getContext("experimental-webgl",F);if(null===t){if(null!==D.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}D.addEventListener("webglcontextlost",e,!1)}catch(Kb){console.error("THREE.WebGLRenderer: "+Kb)}var W=new THREE.WebGLExtensions(t);W.get("OES_texture_float");
-W.get("OES_texture_float_linear");W.get("OES_texture_half_float");W.get("OES_texture_half_float_linear");W.get("OES_standard_derivatives");W.get("ANGLE_instanced_arrays");W.get("OES_element_index_uint")&&(THREE.BufferGeometry.MaxIndex=4294967296);var ka=new THREE.WebGLCapabilities(t,W,a),L=new THREE.WebGLState(t,W,K),$=new THREE.WebGLProperties,sa=new THREE.WebGLObjects(t,$,this.info),Lb=new THREE.WebGLBufferRenderer(t,W,ua),Mb=new THREE.WebGLIndexedBufferRenderer(t,W,ua);c();this.context=t;this.capabilities=
-ka;this.extensions=W;this.state=L;var ma=new THREE.WebGLShadowMap(this,X,sa);this.shadowMap=ma;var Nb=new THREE.SpritePlugin(this,Ra),Ob=new THREE.LensFlarePlugin(this,Sa);this.getContext=function(){return t};this.getContextAttributes=function(){return t.getContextAttributes()};this.forceContextLoss=function(){W.get("WEBGL_lose_context").loseContext()};this.getMaxAnisotropy=function(){var a;return function(){if(void 0!==a)return a;var b=W.get("EXT_texture_filter_anisotropic");return a=null!==b?t.getParameter(b.MAX_TEXTURE_MAX_ANISOTROPY_EXT):
-0}}();this.getPrecision=function(){return ka.precision};this.getPixelRatio=function(){return C};this.setPixelRatio=function(a){void 0!==a&&(C=a)};this.getSize=function(){return{width:J,height:H}};this.setSize=function(a,b,c){J=a;H=b;D.width=a*C;D.height=b*C;!1!==c&&(D.style.width=a+"px",D.style.height=b+"px");this.setViewport(0,0,a,b)};this.setViewport=function(a,b,c,d){Ia=a*C;Aa=b*C;Ba=c*C;Ca=d*C;t.viewport(Ia,Aa,Ba,Ca)};this.setScissor=function(a,b,c,d){t.scissor(a*C,b*C,c*C,d*C)};this.enableScissorTest=
-function(a){L.setScissorTest(a)};this.getClearColor=function(){return E};this.setClearColor=function(a,c){E.set(a);ha=void 0!==c?c:1;b(E.r,E.g,E.b,ha)};this.getClearAlpha=function(){return ha};this.setClearAlpha=function(a){ha=a;b(E.r,E.g,E.b,ha)};this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=t.COLOR_BUFFER_BIT;if(void 0===b||b)d|=t.DEPTH_BUFFER_BIT;if(void 0===c||c)d|=t.STENCIL_BUFFER_BIT;t.clear(d)};this.clearColor=function(){t.clear(t.COLOR_BUFFER_BIT)};this.clearDepth=function(){t.clear(t.DEPTH_BUFFER_BIT)};
-this.clearStencil=function(){t.clear(t.STENCIL_BUFFER_BIT)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=d;this.dispose=function(){D.removeEventListener("webglcontextlost",e,!1)};this.renderBufferImmediate=function(a,b,c){L.initAttributes();var d=$.get(a);a.hasPositions&&!d.position&&(d.position=t.createBuffer());a.hasNormals&&!d.normal&&(d.normal=t.createBuffer());a.hasUvs&&!d.uv&&(d.uv=t.createBuffer());a.hasColors&&!d.color&&(d.color=t.createBuffer());
-b=b.getAttributes();a.hasPositions&&(t.bindBuffer(t.ARRAY_BUFFER,d.position),t.bufferData(t.ARRAY_BUFFER,a.positionArray,t.DYNAMIC_DRAW),L.enableAttribute(b.position),t.vertexAttribPointer(b.position,3,t.FLOAT,!1,0,0));if(a.hasNormals){t.bindBuffer(t.ARRAY_BUFFER,d.normal);if("MeshPhongMaterial"!==c.type&&c.shading===THREE.FlatShading)for(var e=0,f=3*a.count;e<f;e+=9){var g=a.normalArray,h=(g[e+0]+g[e+3]+g[e+6])/3,k=(g[e+1]+g[e+4]+g[e+7])/3,l=(g[e+2]+g[e+5]+g[e+8])/3;g[e+0]=h;g[e+1]=k;g[e+2]=l;g[e+
-3]=h;g[e+4]=k;g[e+5]=l;g[e+6]=h;g[e+7]=k;g[e+8]=l}t.bufferData(t.ARRAY_BUFFER,a.normalArray,t.DYNAMIC_DRAW);L.enableAttribute(b.normal);t.vertexAttribPointer(b.normal,3,t.FLOAT,!1,0,0)}a.hasUvs&&c.map&&(t.bindBuffer(t.ARRAY_BUFFER,d.uv),t.bufferData(t.ARRAY_BUFFER,a.uvArray,t.DYNAMIC_DRAW),L.enableAttribute(b.uv),t.vertexAttribPointer(b.uv,2,t.FLOAT,!1,0,0));a.hasColors&&c.vertexColors!==THREE.NoColors&&(t.bindBuffer(t.ARRAY_BUFFER,d.color),t.bufferData(t.ARRAY_BUFFER,a.colorArray,t.DYNAMIC_DRAW),
-L.enableAttribute(b.color),t.vertexAttribPointer(b.color,3,t.FLOAT,!1,0,0));L.disableUnusedAttributes();t.drawArrays(t.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,b,c,d,e,f,g){u(e);var h=x(a,b,c,e,f),k=!1;a=d.id+"_"+h.id+"_"+e.wireframe;a!==va&&(va=a,k=!0);a=f.morphTargetInfluences;if(void 0!==a){b=[];c=0;for(k=a.length;c<k;c++){var m=a[c];b.push([m,c])}b.sort(l);8<b.length&&(b.length=8);var n=d.morphAttributes;c=0;for(k=b.length;c<k;c++)m=b[c],ta[c]=m[0],0!==m[0]?(a=m[1],!0===
-e.morphTargets&&n.position&&d.addAttribute("morphTarget"+c,n.position[a]),!0===e.morphNormals&&n.normal&&d.addAttribute("morphNormal"+c,n.normal[a])):(!0===e.morphTargets&&d.removeAttribute("morphTarget"+c),!0===e.morphNormals&&d.removeAttribute("morphNormal"+c));a=h.getUniforms();null!==a.morphTargetInfluences&&t.uniform1fv(a.morphTargetInfluences,ta);k=!0}a=d.index;c=d.attributes.position;!0===e.wireframe&&(a=sa.getWireframeAttribute(d));null!==a?(b=Mb,b.setIndex(a)):b=Lb;if(k){a:{var k=void 0,
-q;if(d instanceof THREE.InstancedBufferGeometry&&(q=W.get("ANGLE_instanced_arrays"),null===q)){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");break a}void 0===k&&(k=0);L.initAttributes();var m=d.attributes,h=h.getAttributes(),n=e.defaultAttributeValues,p;for(p in h){var s=h[p];if(0<=s){var r=m[p];if(void 0!==r){L.enableAttribute(s);var v=r.itemSize,w=sa.getAttributeBuffer(r);if(r instanceof
-THREE.InterleavedBufferAttribute){var y=r.data,z=y.stride,r=r.offset;t.bindBuffer(t.ARRAY_BUFFER,w);t.vertexAttribPointer(s,v,t.FLOAT,!1,z*y.array.BYTES_PER_ELEMENT,(k*z+r)*y.array.BYTES_PER_ELEMENT);if(y instanceof THREE.InstancedInterleavedBuffer){if(null===q){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferAttribute but hardware does not support extension ANGLE_instanced_arrays.");break a}q.vertexAttribDivisorANGLE(s,y.meshPerAttribute);void 0===d.maxInstancedCount&&
-(d.maxInstancedCount=y.meshPerAttribute*y.count)}}else if(t.bindBuffer(t.ARRAY_BUFFER,w),t.vertexAttribPointer(s,v,t.FLOAT,!1,0,k*v*4),r instanceof THREE.InstancedBufferAttribute){if(null===q){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferAttribute but hardware does not support extension ANGLE_instanced_arrays.");break a}q.vertexAttribDivisorANGLE(s,r.meshPerAttribute);void 0===d.maxInstancedCount&&(d.maxInstancedCount=r.meshPerAttribute*r.count)}}else if(void 0!==
-n&&(v=n[p],void 0!==v))switch(v.length){case 2:t.vertexAttrib2fv(s,v);break;case 3:t.vertexAttrib3fv(s,v);break;case 4:t.vertexAttrib4fv(s,v);break;default:t.vertexAttrib1fv(s,v)}}}L.disableUnusedAttributes()}null!==a&&t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,sa.getAttributeBuffer(a))}void 0===g&&(g={start:0,count:null!==a?a.array.length:c instanceof THREE.InterleavedBufferAttribute?c.data.array.length/3:c.array.length/3});f instanceof THREE.Mesh?(!0===e.wireframe?(L.setLineWidth(e.wireframeLinewidth*
-C),b.setMode(t.LINES)):b.setMode(t.TRIANGLES),d instanceof THREE.InstancedBufferGeometry&&0<d.maxInstancedCount?b.renderInstances(d):c instanceof THREE.InterleavedBufferAttribute?b.render(0,c.data.count):b.render(g.start,g.count)):f instanceof THREE.Line?(d=e.linewidth,void 0===d&&(d=1),L.setLineWidth(d*C),f instanceof THREE.LineSegments?b.setMode(t.LINES):b.setMode(t.LINE_STRIP),b.render(g.start,g.count)):f instanceof THREE.PointCloud&&(b.setMode(t.POINTS),b.render(g.start,g.count))};this.render=
-function(a,b,c,d){if(!1===b instanceof THREE.Camera)console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");else{var e=a.fog;va="";ab=-1;$a=null;jb=!0;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);Ta.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);kb.setFromMatrix(Ta);X.length=0;Ka=bb=Ha=za=-1;Ra.length=0;Sa.length=0;q(a);ia.length=za+1;ya.length=Ha+1;qa.length=bb+1;Ja.length=
-Ka+1;!0===la.sortObjects&&(ia.sort(n),ya.sort(p));ma.render(a,b);ua.calls=0;ua.vertices=0;ua.faces=0;ua.points=0;this.setRenderTarget(c);(this.autoClear||d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);a.overrideMaterial?(d=a.overrideMaterial,s(ia,b,X,e,d),s(ya,b,X,e,d),r(qa,b,X,e,d),r(Ja,b,X,e,d)):(L.setBlending(THREE.NoBlending),s(ia,b,X,e),r(qa,b,X,e),s(ya,b,X,e),r(Ja,b,X,e));Nb.render(a,b);Ob.render(a,b,pb,qb);c&&c.generateMipmaps&&c.minFilter!==THREE.NearestFilter&&
-c.minFilter!==THREE.LinearFilter&&(c instanceof THREE.WebGLRenderTargetCube?(L.bindTexture(t.TEXTURE_CUBE_MAP,$.get(c).__webglTexture),t.generateMipmap(t.TEXTURE_CUBE_MAP),L.bindTexture(t.TEXTURE_CUBE_MAP,null)):(L.bindTexture(t.TEXTURE_2D,$.get(c).__webglTexture),t.generateMipmap(t.TEXTURE_2D),L.bindTexture(t.TEXTURE_2D,null)));L.setDepthTest(!0);L.setDepthWrite(!0);L.setColorWrite(!0)}};var $b={MeshDepthMaterial:"depth",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",
-MeshPhongMaterial:"phong",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointCloudMaterial:"particle_basic"};this.setFaceCulling=function(a,b){a===THREE.CullFaceNone?L.disable(t.CULL_FACE):(b===THREE.FrontFaceDirectionCW?t.frontFace(t.CW):t.frontFace(t.CCW),a===THREE.CullFaceBack?t.cullFace(t.BACK):a===THREE.CullFaceFront?t.cullFace(t.FRONT):t.cullFace(t.FRONT_AND_BACK),L.enable(t.CULL_FACE))};this.setTexture=function(a,b){var c=$.get(a);if(0<a.version&&c.__version!==a.version){var d=a.image;
-if(void 0===d)console.warn("THREE.WebGLRenderer: Texture marked for update but image is undefined",a);else if(!1===d.complete)console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete",a);else{void 0===c.__webglInit&&(c.__webglInit=!0,a.__webglInit=!0,a.addEventListener("dispose",g),c.__webglTexture=t.createTexture(),Da.textures++);L.activeTexture(t.TEXTURE0+b);L.bindTexture(t.TEXTURE_2D,c.__webglTexture);t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,a.flipY);t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,
-a.premultiplyAlpha);t.pixelStorei(t.UNPACK_ALIGNMENT,a.unpackAlignment);a.image=B(a.image,ka.maxTextureSize);var e=a.image,d=THREE.Math.isPowerOfTwo(e.width)&&THREE.Math.isPowerOfTwo(e.height),f=K(a.format),h=K(a.type);G(t.TEXTURE_2D,a,d);var k=a.mipmaps;if(a instanceof THREE.DataTexture)if(0<k.length&&d){for(var l=0,m=k.length;l<m;l++)e=k[l],L.texImage2D(t.TEXTURE_2D,l,f,e.width,e.height,0,f,h,e.data);a.generateMipmaps=!1}else L.texImage2D(t.TEXTURE_2D,0,f,e.width,e.height,0,f,h,e.data);else if(a instanceof
-THREE.CompressedTexture)for(l=0,m=k.length;l<m;l++)e=k[l],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<L.getCompressedTextureFormats().indexOf(f)?L.compressedTexImage2D(t.TEXTURE_2D,l,f,e.width,e.height,0,e.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):L.texImage2D(t.TEXTURE_2D,l,f,e.width,e.height,0,f,h,e.data);else if(0<k.length&&d){l=0;for(m=k.length;l<m;l++)e=k[l],L.texImage2D(t.TEXTURE_2D,l,f,f,h,e);a.generateMipmaps=
-!1}else L.texImage2D(t.TEXTURE_2D,0,f,f,h,a.image);a.generateMipmaps&&d&&t.generateMipmap(t.TEXTURE_2D);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}}else L.activeTexture(t.TEXTURE0+b),L.bindTexture(t.TEXTURE_2D,c.__webglTexture)};this.setRenderTarget=function(a){var b=a instanceof THREE.WebGLRenderTargetCube;if(a&&void 0===$.get(a).__webglFramebuffer){var c=$.get(a);void 0===a.depthBuffer&&(a.depthBuffer=!0);void 0===a.stencilBuffer&&(a.stencilBuffer=!0);a.addEventListener("dispose",f);c.__webglTexture=
-t.createTexture();Da.textures++;var d=THREE.Math.isPowerOfTwo(a.width)&&THREE.Math.isPowerOfTwo(a.height),e=K(a.format),g=K(a.type);if(b){c.__webglFramebuffer=[];c.__webglRenderbuffer=[];L.bindTexture(t.TEXTURE_CUBE_MAP,c.__webglTexture);G(t.TEXTURE_CUBE_MAP,a,d);for(var h=0;6>h;h++)c.__webglFramebuffer[h]=t.createFramebuffer(),c.__webglRenderbuffer[h]=t.createRenderbuffer(),L.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,e,a.width,a.height,0,e,g,null),z(c.__webglFramebuffer[h],a,t.TEXTURE_CUBE_MAP_POSITIVE_X+
-h),A(c.__webglRenderbuffer[h],a);a.generateMipmaps&&d&&t.generateMipmap(t.TEXTURE_CUBE_MAP)}else c.__webglFramebuffer=t.createFramebuffer(),c.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:t.createRenderbuffer(),L.bindTexture(t.TEXTURE_2D,c.__webglTexture),G(t.TEXTURE_2D,a,d),L.texImage2D(t.TEXTURE_2D,0,e,a.width,a.height,0,e,g,null),z(c.__webglFramebuffer,a,t.TEXTURE_2D),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,
-t.RENDERBUFFER,c.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,c.__webglRenderbuffer):A(c.__webglRenderbuffer,a),a.generateMipmaps&&d&&t.generateMipmap(t.TEXTURE_2D);b?L.bindTexture(t.TEXTURE_CUBE_MAP,null):L.bindTexture(t.TEXTURE_2D,null);t.bindRenderbuffer(t.RENDERBUFFER,null);t.bindFramebuffer(t.FRAMEBUFFER,null)}a?(c=$.get(a),b=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,c=a.width,a=a.height,
-e=d=0):(b=null,c=Ba,a=Ca,d=Ia,e=Aa);b!==Qa&&(t.bindFramebuffer(t.FRAMEBUFFER,b),t.viewport(d,e,c,a),Qa=b);pb=c;qb=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($.get(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;$.get(a).__webglFramebuffer!==Qa&&(t.bindFramebuffer(t.FRAMEBUFFER,$.get(a).__webglFramebuffer),g=!0);t.checkFramebufferStatus(t.FRAMEBUFFER)===t.FRAMEBUFFER_COMPLETE?t.readPixels(b,c,d,e,t.RGBA,t.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&t.bindFramebuffer(t.FRAMEBUFFER,Qa)}};this.supportsFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");
-return W.get("OES_texture_float")};this.supportsHalfFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");return W.get("OES_texture_half_float")};this.supportsStandardDerivatives=function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");return W.get("OES_standard_derivatives")};this.supportsCompressedTextureS3TC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");
-return W.get("WEBGL_compressed_texture_s3tc")};this.supportsCompressedTexturePVRTC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return W.get("WEBGL_compressed_texture_pvrtc")};this.supportsBlendMinMax=function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return W.get("EXT_blend_minmax")};this.supportsVertexTextures=function(){return ka.vertexTextures};
-this.supportsInstancedArrays=function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");return W.get("ANGLE_instanced_arrays")};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.")};Object.defineProperties(this,{shadowMapEnabled:{get:function(){return ma.enabled},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");ma.enabled=a}},shadowMapType:{get:function(){return ma.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");ma.type=a}},shadowMapCullFace:{get:function(){return ma.cullFace},
-set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");ma.cullFace=a}},shadowMapDebug:{get:function(){return ma.debug},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.");ma.debug=a}}})};
-THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();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};
+W.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 C=void 0!==a.canvas?a.canvas:document.createElement("canvas"),O=void 0!==a.context?a.context:null,G=C.width,J=C.height,A=1,H=void 0!==a.alpha?a.alpha:!1,P=void 0!==a.depth?a.depth:!0,Q=void 0!==a.stencil?a.stencil:!0,V=void 0!==a.antialias?a.antialias:!1,R=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:
+!0,S=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,E=new THREE.Color(0),ja=0,Y=[],la=[],wa=-1,Da=[],Ia=-1,ra=[],bb=-1,Ja=[],Ka=-1,ta=new Float32Array(8),Ra=[],ab=[];this.domElement=C;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.gammaOutput=this.gammaInput=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;var ka=this,qa=[],rb=null,Qa=null,$a=-1,va="",Za=null,lb=0,Ha=
+0,za=0,Aa=C.width,Ba=C.height,pb=0,qb=0,kb=new THREE.Frustum,Sa=new THREE.Matrix4,ba=new THREE.Vector3,fa=new THREE.Vector3,jb=!0,Pb={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:[]}},Ca={programs:0,geometries:0,textures:0},ua={calls:0,vertices:0,faces:0,points:0};
+this.info={render:ua,memory:Ca,programs:qa};var s;try{H={alpha:H,depth:P,stencil:Q,antialias:V,premultipliedAlpha:R,preserveDrawingBuffer:S};s=O||C.getContext("webgl",H)||C.getContext("experimental-webgl",H);if(null===s){if(null!==C.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}C.addEventListener("webglcontextlost",e,!1)}catch(Kb){console.error("THREE.WebGLRenderer: "+Kb)}var W=new THREE.WebGLExtensions(s);W.get("OES_texture_float");
+W.get("OES_texture_float_linear");W.get("OES_texture_half_float");W.get("OES_texture_half_float_linear");W.get("OES_standard_derivatives");W.get("ANGLE_instanced_arrays");W.get("OES_element_index_uint")&&(THREE.BufferGeometry.MaxIndex=4294967296);var ia=new THREE.WebGLCapabilities(s,W,a),K=new THREE.WebGLState(s,W,N),$=new THREE.WebGLProperties,sa=new THREE.WebGLObjects(s,$,this.info),Lb=new THREE.WebGLBufferRenderer(s,W,ua),Mb=new THREE.WebGLIndexedBufferRenderer(s,W,ua);c();this.context=s;this.capabilities=
+ia;this.extensions=W;this.state=K;var ma=new THREE.WebGLShadowMap(this,Y,sa);this.shadowMap=ma;var Nb=new THREE.SpritePlugin(this,Ra),Ob=new THREE.LensFlarePlugin(this,ab);this.getContext=function(){return s};this.getContextAttributes=function(){return s.getContextAttributes()};this.forceContextLoss=function(){W.get("WEBGL_lose_context").loseContext()};this.getMaxAnisotropy=function(){var a;return function(){if(void 0!==a)return a;var b=W.get("EXT_texture_filter_anisotropic");return a=null!==b?s.getParameter(b.MAX_TEXTURE_MAX_ANISOTROPY_EXT):
+0}}();this.getPrecision=function(){return ia.precision};this.getPixelRatio=function(){return A};this.setPixelRatio=function(a){void 0!==a&&(A=a)};this.getSize=function(){return{width:G,height:J}};this.setSize=function(a,b,c){G=a;J=b;C.width=a*A;C.height=b*A;!1!==c&&(C.style.width=a+"px",C.style.height=b+"px");this.setViewport(0,0,a,b)};this.setViewport=function(a,b,c,d){Ha=a*A;za=b*A;Aa=c*A;Ba=d*A;s.viewport(Ha,za,Aa,Ba)};this.setScissor=function(a,b,c,d){s.scissor(a*A,b*A,c*A,d*A)};this.enableScissorTest=
+function(a){K.setScissorTest(a)};this.getClearColor=function(){return E};this.setClearColor=function(a,c){E.set(a);ja=void 0!==c?c:1;b(E.r,E.g,E.b,ja)};this.getClearAlpha=function(){return ja};this.setClearAlpha=function(a){ja=a;b(E.r,E.g,E.b,ja)};this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=s.COLOR_BUFFER_BIT;if(void 0===b||b)d|=s.DEPTH_BUFFER_BIT;if(void 0===c||c)d|=s.STENCIL_BUFFER_BIT;s.clear(d)};this.clearColor=function(){s.clear(s.COLOR_BUFFER_BIT)};this.clearDepth=function(){s.clear(s.DEPTH_BUFFER_BIT)};
+this.clearStencil=function(){s.clear(s.STENCIL_BUFFER_BIT)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=d;this.dispose=function(){C.removeEventListener("webglcontextlost",e,!1)};this.renderBufferImmediate=function(a,b,c){K.initAttributes();var d=$.get(a);a.hasPositions&&!d.position&&(d.position=s.createBuffer());a.hasNormals&&!d.normal&&(d.normal=s.createBuffer());a.hasUvs&&!d.uv&&(d.uv=s.createBuffer());a.hasColors&&!d.color&&(d.color=s.createBuffer());
+b=b.getAttributes();a.hasPositions&&(s.bindBuffer(s.ARRAY_BUFFER,d.position),s.bufferData(s.ARRAY_BUFFER,a.positionArray,s.DYNAMIC_DRAW),K.enableAttribute(b.position),s.vertexAttribPointer(b.position,3,s.FLOAT,!1,0,0));if(a.hasNormals){s.bindBuffer(s.ARRAY_BUFFER,d.normal);if("MeshPhongMaterial"!==c.type&&c.shading===THREE.FlatShading)for(var e=0,f=3*a.count;e<f;e+=9){var g=a.normalArray,h=(g[e+0]+g[e+3]+g[e+6])/3,k=(g[e+1]+g[e+4]+g[e+7])/3,l=(g[e+2]+g[e+5]+g[e+8])/3;g[e+0]=h;g[e+1]=k;g[e+2]=l;g[e+
+3]=h;g[e+4]=k;g[e+5]=l;g[e+6]=h;g[e+7]=k;g[e+8]=l}s.bufferData(s.ARRAY_BUFFER,a.normalArray,s.DYNAMIC_DRAW);K.enableAttribute(b.normal);s.vertexAttribPointer(b.normal,3,s.FLOAT,!1,0,0)}a.hasUvs&&c.map&&(s.bindBuffer(s.ARRAY_BUFFER,d.uv),s.bufferData(s.ARRAY_BUFFER,a.uvArray,s.DYNAMIC_DRAW),K.enableAttribute(b.uv),s.vertexAttribPointer(b.uv,2,s.FLOAT,!1,0,0));a.hasColors&&c.vertexColors!==THREE.NoColors&&(s.bindBuffer(s.ARRAY_BUFFER,d.color),s.bufferData(s.ARRAY_BUFFER,a.colorArray,s.DYNAMIC_DRAW),
+K.enableAttribute(b.color),s.vertexAttribPointer(b.color,3,s.FLOAT,!1,0,0));K.disableUnusedAttributes();s.drawArrays(s.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,b,c,d,e,f,g){v(e);var h=w(a,b,c,e,f),k=!1;a=d.id+"_"+h.id+"_"+e.wireframe;a!==va&&(va=a,k=!0);a=f.morphTargetInfluences;if(void 0!==a){b=[];c=0;for(k=a.length;c<k;c++){var m=a[c];b.push([m,c])}b.sort(l);8<b.length&&(b.length=8);var n=d.morphAttributes;c=0;for(k=b.length;c<k;c++)m=b[c],ta[c]=m[0],0!==m[0]?(a=m[1],!0===
+e.morphTargets&&n.position&&d.addAttribute("morphTarget"+c,n.position[a]),!0===e.morphNormals&&n.normal&&d.addAttribute("morphNormal"+c,n.normal[a])):(!0===e.morphTargets&&d.removeAttribute("morphTarget"+c),!0===e.morphNormals&&d.removeAttribute("morphNormal"+c));a=h.getUniforms();null!==a.morphTargetInfluences&&s.uniform1fv(a.morphTargetInfluences,ta);k=!0}a=d.index;c=d.attributes.position;!0===e.wireframe&&(a=sa.getWireframeAttribute(d));null!==a?(b=Mb,b.setIndex(a)):b=Lb;if(k){a:{var k=void 0,
+q;if(d instanceof THREE.InstancedBufferGeometry&&(q=W.get("ANGLE_instanced_arrays"),null===q)){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");break a}void 0===k&&(k=0);K.initAttributes();var m=d.attributes,h=h.getAttributes(),n=e.defaultAttributeValues,p;for(p in h){var t=h[p];if(0<=t){var u=m[p];if(void 0!==u){K.enableAttribute(t);var r=u.itemSize,x=sa.getAttributeBuffer(u);if(u instanceof
+THREE.InterleavedBufferAttribute){var z=u.data,L=z.stride,u=u.offset;s.bindBuffer(s.ARRAY_BUFFER,x);s.vertexAttribPointer(t,r,s.FLOAT,!1,L*z.array.BYTES_PER_ELEMENT,(k*L+u)*z.array.BYTES_PER_ELEMENT);if(z instanceof THREE.InstancedInterleavedBuffer){if(null===q){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferAttribute but hardware does not support extension ANGLE_instanced_arrays.");break a}q.vertexAttribDivisorANGLE(t,z.meshPerAttribute);void 0===d.maxInstancedCount&&
+(d.maxInstancedCount=z.meshPerAttribute*z.count)}}else if(s.bindBuffer(s.ARRAY_BUFFER,x),s.vertexAttribPointer(t,r,s.FLOAT,!1,0,k*r*4),u instanceof THREE.InstancedBufferAttribute){if(null===q){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferAttribute but hardware does not support extension ANGLE_instanced_arrays.");break a}q.vertexAttribDivisorANGLE(t,u.meshPerAttribute);void 0===d.maxInstancedCount&&(d.maxInstancedCount=u.meshPerAttribute*u.count)}}else if(void 0!==
+n&&(r=n[p],void 0!==r))switch(r.length){case 2:s.vertexAttrib2fv(t,r);break;case 3:s.vertexAttrib3fv(t,r);break;case 4:s.vertexAttrib4fv(t,r);break;default:s.vertexAttrib1fv(t,r)}}}K.disableUnusedAttributes()}null!==a&&s.bindBuffer(s.ELEMENT_ARRAY_BUFFER,sa.getAttributeBuffer(a))}void 0===g&&(g={start:0,count:null!==a?a.array.length:c instanceof THREE.InterleavedBufferAttribute?c.data.array.length/3:c.array.length/3});f instanceof THREE.Mesh?(!0===e.wireframe?(K.setLineWidth(e.wireframeLinewidth*
+A),b.setMode(s.LINES)):b.setMode(s.TRIANGLES),d instanceof THREE.InstancedBufferGeometry&&0<d.maxInstancedCount?b.renderInstances(d):b.render(g.start,g.count)):f instanceof THREE.Line?(d=e.linewidth,void 0===d&&(d=1),K.setLineWidth(d*A),f instanceof THREE.LineSegments?b.setMode(s.LINES):b.setMode(s.LINE_STRIP),b.render(g.start,g.count)):f instanceof THREE.PointCloud&&(b.setMode(s.POINTS),b.render(g.start,g.count))};this.render=function(a,b,c,d){if(!1===b instanceof THREE.Camera)console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");
+else{var e=a.fog;va="";$a=-1;Za=null;jb=!0;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);Sa.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);kb.setFromMatrix(Sa);Y.length=0;Ka=bb=Ia=wa=-1;Ra.length=0;ab.length=0;q(a);la.length=wa+1;Da.length=Ia+1;ra.length=bb+1;Ja.length=Ka+1;!0===ka.sortObjects&&(la.sort(n),Da.sort(p));ma.render(a,b);ua.calls=0;ua.vertices=0;ua.faces=0;ua.points=0;this.setRenderTarget(c);(this.autoClear||
+d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);a.overrideMaterial?(d=a.overrideMaterial,t(la,b,Y,e,d),t(Da,b,Y,e,d),r(ra,b,Y,e,d),r(Ja,b,Y,e,d)):(K.setBlending(THREE.NoBlending),t(la,b,Y,e),r(ra,b,Y,e),t(Da,b,Y,e),r(Ja,b,Y,e));Nb.render(a,b);Ob.render(a,b,pb,qb);c&&c.generateMipmaps&&c.minFilter!==THREE.NearestFilter&&c.minFilter!==THREE.LinearFilter&&(c instanceof THREE.WebGLRenderTargetCube?(K.bindTexture(s.TEXTURE_CUBE_MAP,$.get(c).__webglTexture),s.generateMipmap(s.TEXTURE_CUBE_MAP),
+K.bindTexture(s.TEXTURE_CUBE_MAP,null)):(K.bindTexture(s.TEXTURE_2D,$.get(c).__webglTexture),s.generateMipmap(s.TEXTURE_2D),K.bindTexture(s.TEXTURE_2D,null)));K.setDepthTest(!0);K.setDepthWrite(!0);K.setColorWrite(!0)}};var $b={MeshDepthMaterial:"depth",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointCloudMaterial:"particle_basic"};this.setFaceCulling=function(a,b){a===THREE.CullFaceNone?
+K.disable(s.CULL_FACE):(b===THREE.FrontFaceDirectionCW?s.frontFace(s.CW):s.frontFace(s.CCW),a===THREE.CullFaceBack?s.cullFace(s.BACK):a===THREE.CullFaceFront?s.cullFace(s.FRONT):s.cullFace(s.FRONT_AND_BACK),K.enable(s.CULL_FACE))};this.setTexture=function(a,b){var c=$.get(a);if(0<a.version&&c.__version!==a.version){var d=a.image;if(void 0===d)console.warn("THREE.WebGLRenderer: Texture marked for update but image is undefined",a);else if(!1===d.complete)console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete",
+a);else{void 0===c.__webglInit&&(c.__webglInit=!0,a.__webglInit=!0,a.addEventListener("dispose",g),c.__webglTexture=s.createTexture(),Ca.textures++);K.activeTexture(s.TEXTURE0+b);K.bindTexture(s.TEXTURE_2D,c.__webglTexture);s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,a.flipY);s.pixelStorei(s.UNPACK_PREMULTIPLY_ALPHA_WEBGL,a.premultiplyAlpha);s.pixelStorei(s.UNPACK_ALIGNMENT,a.unpackAlignment);a.image=F(a.image,ia.maxTextureSize);var e=a.image,d=THREE.Math.isPowerOfTwo(e.width)&&THREE.Math.isPowerOfTwo(e.height),
+f=N(a.format),h=N(a.type);D(s.TEXTURE_2D,a,d);var k=a.mipmaps;if(a instanceof THREE.DataTexture)if(0<k.length&&d){for(var l=0,m=k.length;l<m;l++)e=k[l],K.texImage2D(s.TEXTURE_2D,l,f,e.width,e.height,0,f,h,e.data);a.generateMipmaps=!1}else K.texImage2D(s.TEXTURE_2D,0,f,e.width,e.height,0,f,h,e.data);else if(a instanceof THREE.CompressedTexture)for(l=0,m=k.length;l<m;l++)e=k[l],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<K.getCompressedTextureFormats().indexOf(f)?K.compressedTexImage2D(s.TEXTURE_2D,
+l,f,e.width,e.height,0,e.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):K.texImage2D(s.TEXTURE_2D,l,f,e.width,e.height,0,f,h,e.data);else if(0<k.length&&d){l=0;for(m=k.length;l<m;l++)e=k[l],K.texImage2D(s.TEXTURE_2D,l,f,f,h,e);a.generateMipmaps=!1}else K.texImage2D(s.TEXTURE_2D,0,f,f,h,a.image);a.generateMipmaps&&d&&s.generateMipmap(s.TEXTURE_2D);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}}else K.activeTexture(s.TEXTURE0+
+b),K.bindTexture(s.TEXTURE_2D,c.__webglTexture)};this.setRenderTarget=function(a){var b=a instanceof THREE.WebGLRenderTargetCube;if(a&&void 0===$.get(a).__webglFramebuffer){var c=$.get(a);void 0===a.depthBuffer&&(a.depthBuffer=!0);void 0===a.stencilBuffer&&(a.stencilBuffer=!0);a.addEventListener("dispose",f);c.__webglTexture=s.createTexture();Ca.textures++;var d=THREE.Math.isPowerOfTwo(a.width)&&THREE.Math.isPowerOfTwo(a.height),e=N(a.format),g=N(a.type);if(b){c.__webglFramebuffer=[];c.__webglRenderbuffer=
+[];K.bindTexture(s.TEXTURE_CUBE_MAP,c.__webglTexture);D(s.TEXTURE_CUBE_MAP,a,d);for(var h=0;6>h;h++)c.__webglFramebuffer[h]=s.createFramebuffer(),c.__webglRenderbuffer[h]=s.createRenderbuffer(),K.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,e,a.width,a.height,0,e,g,null),y(c.__webglFramebuffer[h],a,s.TEXTURE_CUBE_MAP_POSITIVE_X+h),B(c.__webglRenderbuffer[h],a);a.generateMipmaps&&d&&s.generateMipmap(s.TEXTURE_CUBE_MAP)}else c.__webglFramebuffer=s.createFramebuffer(),c.__webglRenderbuffer=a.shareDepthFrom?
+a.shareDepthFrom.__webglRenderbuffer:s.createRenderbuffer(),K.bindTexture(s.TEXTURE_2D,c.__webglTexture),D(s.TEXTURE_2D,a,d),K.texImage2D(s.TEXTURE_2D,0,e,a.width,a.height,0,e,g,null),y(c.__webglFramebuffer,a,s.TEXTURE_2D),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?s.framebufferRenderbuffer(s.FRAMEBUFFER,s.DEPTH_ATTACHMENT,s.RENDERBUFFER,c.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&s.framebufferRenderbuffer(s.FRAMEBUFFER,s.DEPTH_STENCIL_ATTACHMENT,s.RENDERBUFFER,c.__webglRenderbuffer):
+B(c.__webglRenderbuffer,a),a.generateMipmaps&&d&&s.generateMipmap(s.TEXTURE_2D);b?K.bindTexture(s.TEXTURE_CUBE_MAP,null):K.bindTexture(s.TEXTURE_2D,null);s.bindRenderbuffer(s.RENDERBUFFER,null);s.bindFramebuffer(s.FRAMEBUFFER,null)}a?(c=$.get(a),b=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Aa,a=Ba,d=Ha,e=za);b!==Qa&&(s.bindFramebuffer(s.FRAMEBUFFER,b),s.viewport(d,e,c,a),Qa=b);pb=c;qb=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($.get(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;$.get(a).__webglFramebuffer!==Qa&&(s.bindFramebuffer(s.FRAMEBUFFER,$.get(a).__webglFramebuffer),g=!0);s.checkFramebufferStatus(s.FRAMEBUFFER)===s.FRAMEBUFFER_COMPLETE?
+s.readPixels(b,c,d,e,s.RGBA,s.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&s.bindFramebuffer(s.FRAMEBUFFER,Qa)}};this.supportsFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");return W.get("OES_texture_float")};this.supportsHalfFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");
+return W.get("OES_texture_half_float")};this.supportsStandardDerivatives=function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");return W.get("OES_standard_derivatives")};this.supportsCompressedTextureS3TC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");return W.get("WEBGL_compressed_texture_s3tc")};this.supportsCompressedTexturePVRTC=
+function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return W.get("WEBGL_compressed_texture_pvrtc")};this.supportsBlendMinMax=function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return W.get("EXT_blend_minmax")};this.supportsVertexTextures=function(){return ia.vertexTextures};this.supportsInstancedArrays=function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");
+return W.get("ANGLE_instanced_arrays")};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.")};Object.defineProperties(this,{shadowMapEnabled:{get:function(){return ma.enabled},
+set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");ma.enabled=a}},shadowMapType:{get:function(){return ma.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");ma.type=a}},shadowMapCullFace:{get:function(){return ma.cullFace},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");ma.cullFace=a}},shadowMapDebug:{get:function(){return ma.debug},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.");
+ma.debug=a}}})};
+THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();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){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.dispose()},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.wrapS=a.wrapS;this.wrapT=a.wrapT;this.magFilter=a.magFilter;this.minFilter=a.minFilter;this.anisotropy=a.anisotropy;this.offset.copy(a.offset);this.repeat.copy(a.repeat);this.format=a.format;this.type=a.type;this.depthBuffer=
 a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.generateMipmaps=a.generateMipmaps;this.shareDepthFrom=a.shareDepthFrom;return this},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;
@@ -589,73 +587,73 @@ this.maxFragmentUniforms=a.getParameter(a.MAX_FRAGMENT_UNIFORM_VECTORS);this.ver
 THREE.WebGLGeometries=function(a,b,c){function d(a){a=a.target;var h=g[a.id].attributes,k;for(k in h)e(h[k]);a.removeEventListener("dispose",d);delete g[a.id];k=b.get(a);k.wireframe&&e(k.wireframe);c.memory.geometries--}function e(c){var d;d=c instanceof THREE.InterleavedBufferAttribute?b.get(c.data).__webglBuffer:b.get(c).__webglBuffer;void 0!==d&&(a.deleteBuffer(d),c instanceof THREE.InterleavedBufferAttribute?b.delete(c.data):b.delete(c))}var g={};this.get=function(a){var b=a.geometry;if(void 0!==
 g[b.id])return g[b.id];b.addEventListener("dispose",d);var e;b instanceof THREE.BufferGeometry?e=b:b instanceof THREE.Geometry&&(void 0===b._bufferGeometry&&(b._bufferGeometry=(new THREE.BufferGeometry).setFromObject(a)),e=b._bufferGeometry);g[b.id]=e;c.memory.geometries++;return e}};
 THREE.WebGLObjects=function(a,b,c){function d(c,d){var e=c instanceof THREE.InterleavedBufferAttribute?c.data:c,g=b.get(e);void 0===g.__webglBuffer?(g.__webglBuffer=a.createBuffer(),a.bindBuffer(d,g.__webglBuffer),a.bufferData(d,e.array,e.dynamic?a.DYNAMIC_DRAW:a.STATIC_DRAW),g.version=e.version):g.version!==e.version&&(a.bindBuffer(d,g.__webglBuffer),!1===e.dynamic||-1===e.updateRange.count?a.bufferSubData(d,0,e.array):0===e.updateRange.count?console.error("THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually."):
-(a.bufferSubData(d,e.updateRange.offset*e.array.BYTES_PER_ELEMENT,e.array.subarray(e.updateRange.offset,e.updateRange.offset+e.updateRange.count)),e.updateRange.count=0),g.version=e.version)}function e(a,b,c){b=b<c?b+"_"+c:c+"_"+b;if(a.hasOwnProperty(b))return!1;a[b]=1;return!0}var g=new THREE.WebGLGeometries(a,b,c);this.getAttributeBuffer=function(a){return a instanceof THREE.InterleavedBufferAttribute?b.get(a.data).__webglBuffer:b.get(a).__webglBuffer};this.getWireframeAttribute=function(c){var g=
-b.get(c);if(void 0!==g.wireframe)return g.wireframe;var k=[],l=c.index,n=c.attributes;c=n.position;if(null!==l)for(var n={},l=l.array,p=0,m=l.length;p<m;p+=3){var q=l[p+0],s=l[p+1],r=l[p+2];e(n,q,s)&&k.push(q,s);e(n,s,r)&&k.push(s,r);e(n,r,q)&&k.push(r,q)}else for(l=n.position.array,p=0,m=l.length/3-1;p<m;p+=3)q=p+0,s=p+1,r=p+2,k.push(q,s,s,r,r,q);k=new THREE.BufferAttribute(new (65535<c.count?Uint32Array:Uint16Array)(k),1);d(k,a.ELEMENT_ARRAY_BUFFER);return g.wireframe=k};this.update=function(b){var c=
-g.get(b);b.geometry instanceof THREE.Geometry&&c.updateFromObject(b);b=c.index;var e=c.attributes;null!==b&&d(b,a.ELEMENT_ARRAY_BUFFER);for(var l in e)d(e[l],a.ARRAY_BUFFER);b=c.morphAttributes;for(l in b)for(var e=b[l],n=0,p=e.length;n<p;n++)d(e[n],a.ARRAY_BUFFER);return c}};
-THREE.WebGLProgram=function(){function a(a){var b=[],c;for(c in a){var f=a[c];!1!==f&&b.push("#define "+c+" "+f)}return b.join("\n")}function b(a){return""!==a}var c=0;return function(d,e,g,f){var h=d.context,k=g.defines,l=g.__webglShader.vertexShader,n=g.__webglShader.fragmentShader,p="SHADOWMAP_TYPE_BASIC";f.shadowMapType===THREE.PCFShadowMap?p="SHADOWMAP_TYPE_PCF":f.shadowMapType===THREE.PCFSoftShadowMap&&(p="SHADOWMAP_TYPE_PCF_SOFT");var m="ENVMAP_TYPE_CUBE",q="ENVMAP_MODE_REFLECTION",s="ENVMAP_BLENDING_MULTIPLY";
-if(f.envMap){switch(g.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:m="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:m="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:m="ENVMAP_TYPE_SPHERE"}switch(g.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:q="ENVMAP_MODE_REFRACTION"}switch(g.combine){case THREE.MultiplyOperation:s="ENVMAP_BLENDING_MULTIPLY";
-break;case THREE.MixOperation:s="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:s="ENVMAP_BLENDING_ADD"}}var r=0<d.gammaFactor?d.gammaFactor:1,u=a(k),x=h.createProgram();g instanceof THREE.RawShaderMaterial?d=k="":(k=["precision "+f.precision+" float;","precision "+f.precision+" int;","#define SHADER_NAME "+g.__webglShader.name,u,f.supportsVertexTextures?"#define VERTEX_TEXTURES":"",d.gammaInput?"#define GAMMA_INPUT":"",d.gammaOutput?"#define GAMMA_OUTPUT":"","#define GAMMA_FACTOR "+r,"#define MAX_DIR_LIGHTS "+
+(a.bufferSubData(d,e.updateRange.offset*e.array.BYTES_PER_ELEMENT,e.array.subarray(e.updateRange.offset,e.updateRange.offset+e.updateRange.count)),e.updateRange.count=0),g.version=e.version)}function e(a,b,c){if(b>c){var d=b;b=c;c=d}d=a[b];return void 0===d?(a[b]=[c],!0):-1===d.indexOf(c)?(d.push(c),!0):!1}var g=new THREE.WebGLGeometries(a,b,c);this.getAttributeBuffer=function(a){return a instanceof THREE.InterleavedBufferAttribute?b.get(a.data).__webglBuffer:b.get(a).__webglBuffer};this.getWireframeAttribute=
+function(c){var g=b.get(c);if(void 0!==g.wireframe)return g.wireframe;var k=[],l=c.index,n=c.attributes;c=n.position;if(null!==l)for(var n={},l=l.array,p=0,m=l.length;p<m;p+=3){var q=l[p+0],t=l[p+1],r=l[p+2];e(n,q,t)&&k.push(q,t);e(n,t,r)&&k.push(t,r);e(n,r,q)&&k.push(r,q)}else for(l=n.position.array,p=0,m=l.length/3-1;p<m;p+=3)q=p+0,t=p+1,r=p+2,k.push(q,t,t,r,r,q);k=new THREE.BufferAttribute(new (65535<c.count?Uint32Array:Uint16Array)(k),1);d(k,a.ELEMENT_ARRAY_BUFFER);return g.wireframe=k};this.update=
+function(b){var c=g.get(b);b.geometry instanceof THREE.Geometry&&c.updateFromObject(b);b=c.index;var e=c.attributes;null!==b&&d(b,a.ELEMENT_ARRAY_BUFFER);for(var l in e)d(e[l],a.ARRAY_BUFFER);b=c.morphAttributes;for(l in b)for(var e=b[l],n=0,p=e.length;n<p;n++)d(e[n],a.ARRAY_BUFFER);return c}};
+THREE.WebGLProgram=function(){function a(a){var b=[],c;for(c in a){var f=a[c];!1!==f&&b.push("#define "+c+" "+f)}return b.join("\n")}function b(a){return""!==a}var c=0;return function(d,e,g,f){var h=d.context,k=g.defines,l=g.__webglShader.vertexShader,n=g.__webglShader.fragmentShader,p="SHADOWMAP_TYPE_BASIC";f.shadowMapType===THREE.PCFShadowMap?p="SHADOWMAP_TYPE_PCF":f.shadowMapType===THREE.PCFSoftShadowMap&&(p="SHADOWMAP_TYPE_PCF_SOFT");var m="ENVMAP_TYPE_CUBE",q="ENVMAP_MODE_REFLECTION",t="ENVMAP_BLENDING_MULTIPLY";
+if(f.envMap){switch(g.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:m="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:m="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:m="ENVMAP_TYPE_SPHERE"}switch(g.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:q="ENVMAP_MODE_REFRACTION"}switch(g.combine){case THREE.MultiplyOperation:t="ENVMAP_BLENDING_MULTIPLY";
+break;case THREE.MixOperation:t="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:t="ENVMAP_BLENDING_ADD"}}var r=0<d.gammaFactor?d.gammaFactor:1,v=a(k),w=h.createProgram();g instanceof THREE.RawShaderMaterial?d=k="":(k=["precision "+f.precision+" float;","precision "+f.precision+" int;","#define SHADER_NAME "+g.__webglShader.name,v,f.supportsVertexTextures?"#define VERTEX_TEXTURES":"",d.gammaInput?"#define GAMMA_INPUT":"",d.gammaOutput?"#define GAMMA_OUTPUT":"","#define GAMMA_FACTOR "+r,"#define MAX_DIR_LIGHTS "+
 f.maxDirLights,"#define MAX_POINT_LIGHTS "+f.maxPointLights,"#define MAX_SPOT_LIGHTS "+f.maxSpotLights,"#define MAX_HEMI_LIGHTS "+f.maxHemiLights,"#define MAX_SHADOWS "+f.maxShadows,"#define MAX_BONES "+f.maxBones,f.map?"#define USE_MAP":"",f.envMap?"#define USE_ENVMAP":"",f.envMap?"#define "+q:"",f.lightMap?"#define USE_LIGHTMAP":"",f.aoMap?"#define USE_AOMAP":"",f.emissiveMap?"#define USE_EMISSIVEMAP":"",f.bumpMap?"#define USE_BUMPMAP":"",f.normalMap?"#define USE_NORMALMAP":"",f.specularMap?"#define USE_SPECULARMAP":
 "",f.alphaMap?"#define USE_ALPHAMAP":"",f.vertexColors?"#define USE_COLOR":"",f.flatShading?"#define FLAT_SHADED":"",f.skinning?"#define USE_SKINNING":"",f.useVertexTexture?"#define BONE_TEXTURE":"",f.morphTargets?"#define USE_MORPHTARGETS":"",f.morphNormals&&!1===f.flatShading?"#define USE_MORPHNORMALS":"",f.doubleSided?"#define DOUBLE_SIDED":"",f.flipSided?"#define FLIP_SIDED":"",f.shadowMapEnabled?"#define USE_SHADOWMAP":"",f.shadowMapEnabled?"#define "+p:"",f.shadowMapDebug?"#define SHADOWMAP_DEBUG":
 "",f.sizeAttenuation?"#define USE_SIZEATTENUATION":"",f.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",f.logarithmicDepthBuffer&&d.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"","uniform mat4 modelMatrix;","uniform mat4 modelViewMatrix;","uniform mat4 projectionMatrix;","uniform mat4 viewMatrix;","uniform mat3 normalMatrix;","uniform vec3 cameraPosition;","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_COLOR","\tattribute vec3 color;","#endif",
 "#ifdef USE_MORPHTARGETS","\tattribute vec3 morphTarget0;","\tattribute vec3 morphTarget1;","\tattribute vec3 morphTarget2;","\tattribute vec3 morphTarget3;","\t#ifdef USE_MORPHNORMALS","\t\tattribute vec3 morphNormal0;","\t\tattribute vec3 morphNormal1;","\t\tattribute vec3 morphNormal2;","\t\tattribute vec3 morphNormal3;","\t#else","\t\tattribute vec3 morphTarget4;","\t\tattribute vec3 morphTarget5;","\t\tattribute vec3 morphTarget6;","\t\tattribute vec3 morphTarget7;","\t#endif","#endif","#ifdef USE_SKINNING",
-"\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(b).join("\n"),d=[f.bumpMap||f.normalMap||f.flatShading||g.derivatives?"#extension GL_OES_standard_derivatives : enable":"",f.logarithmicDepthBuffer&&d.extensions.get("EXT_frag_depth")?"#extension GL_EXT_frag_depth : enable":"","precision "+f.precision+" float;","precision "+f.precision+" int;","#define SHADER_NAME "+g.__webglShader.name,u,"#define MAX_DIR_LIGHTS "+f.maxDirLights,"#define MAX_POINT_LIGHTS "+f.maxPointLights,
-"#define MAX_SPOT_LIGHTS "+f.maxSpotLights,"#define MAX_HEMI_LIGHTS "+f.maxHemiLights,"#define MAX_SHADOWS "+f.maxShadows,f.alphaTest?"#define ALPHATEST "+f.alphaTest:"",d.gammaInput?"#define GAMMA_INPUT":"",d.gammaOutput?"#define GAMMA_OUTPUT":"","#define GAMMA_FACTOR "+r,f.useFog&&f.fog?"#define USE_FOG":"",f.useFog&&f.fogExp?"#define FOG_EXP2":"",f.map?"#define USE_MAP":"",f.envMap?"#define USE_ENVMAP":"",f.envMap?"#define "+m:"",f.envMap?"#define "+q:"",f.envMap?"#define "+s:"",f.lightMap?"#define USE_LIGHTMAP":
+"\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(b).join("\n"),d=[f.bumpMap||f.normalMap||f.flatShading||g.derivatives?"#extension GL_OES_standard_derivatives : enable":"",f.logarithmicDepthBuffer&&d.extensions.get("EXT_frag_depth")?"#extension GL_EXT_frag_depth : enable":"","precision "+f.precision+" float;","precision "+f.precision+" int;","#define SHADER_NAME "+g.__webglShader.name,v,"#define MAX_DIR_LIGHTS "+f.maxDirLights,"#define MAX_POINT_LIGHTS "+f.maxPointLights,
+"#define MAX_SPOT_LIGHTS "+f.maxSpotLights,"#define MAX_HEMI_LIGHTS "+f.maxHemiLights,"#define MAX_SHADOWS "+f.maxShadows,f.alphaTest?"#define ALPHATEST "+f.alphaTest:"",d.gammaInput?"#define GAMMA_INPUT":"",d.gammaOutput?"#define GAMMA_OUTPUT":"","#define GAMMA_FACTOR "+r,f.useFog&&f.fog?"#define USE_FOG":"",f.useFog&&f.fogExp?"#define FOG_EXP2":"",f.map?"#define USE_MAP":"",f.envMap?"#define USE_ENVMAP":"",f.envMap?"#define "+m:"",f.envMap?"#define "+q:"",f.envMap?"#define "+t:"",f.lightMap?"#define USE_LIGHTMAP":
 "",f.aoMap?"#define USE_AOMAP":"",f.emissiveMap?"#define USE_EMISSIVEMAP":"",f.bumpMap?"#define USE_BUMPMAP":"",f.normalMap?"#define USE_NORMALMAP":"",f.specularMap?"#define USE_SPECULARMAP":"",f.alphaMap?"#define USE_ALPHAMAP":"",f.vertexColors?"#define USE_COLOR":"",f.flatShading?"#define FLAT_SHADED":"",f.metal?"#define METAL":"",f.doubleSided?"#define DOUBLE_SIDED":"",f.flipSided?"#define FLIP_SIDED":"",f.shadowMapEnabled?"#define USE_SHADOWMAP":"",f.shadowMapEnabled?"#define "+p:"",f.shadowMapDebug?
-"#define SHADOWMAP_DEBUG":"",f.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",f.logarithmicDepthBuffer&&d.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","\n"].filter(b).join("\n"));n=d+n;l=THREE.WebGLShader(h,h.VERTEX_SHADER,k+l);n=THREE.WebGLShader(h,h.FRAGMENT_SHADER,n);h.attachShader(x,l);h.attachShader(x,n);void 0!==g.index0AttributeName?h.bindAttribLocation(x,0,g.index0AttributeName):!0===f.morphTargets&&h.bindAttribLocation(x,
-0,"position");h.linkProgram(x);f=h.getProgramInfoLog(x);p=h.getShaderInfoLog(l);m=h.getShaderInfoLog(n);s=q=!0;if(!1===h.getProgramParameter(x,h.LINK_STATUS))q=!1,console.error("THREE.WebGLProgram: shader error: ",h.getError(),"gl.VALIDATE_STATUS",h.getProgramParameter(x,h.VALIDATE_STATUS),"gl.getProgramInfoLog",f,p,m);else if(""!==f)console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",f);else if(""===p||""===m)s=!1;s&&(this.diagnostics={runnable:q,material:g,programLog:f,vertexShader:{log:p,
-prefix:k},fragmentShader:{log:m,prefix:d}});h.deleteShader(l);h.deleteShader(n);var v;this.getUniforms=function(){if(void 0===v){for(var a={},b=h.getProgramParameter(x,h.ACTIVE_UNIFORMS),c=0;c<b;c++){var d=h.getActiveUniform(x,c).name,e=h.getUniformLocation(x,d),f=d.lastIndexOf("[0]");-1!==f&&f===d.length-3&&(a[d.substr(0,f)]=e);a[d]=e}v=a}return v};var y;this.getAttributes=function(){if(void 0===y){for(var a={},b=h.getProgramParameter(x,h.ACTIVE_ATTRIBUTES),c=0;c<b;c++){var d=h.getActiveAttrib(x,
-c).name;a[d]=h.getAttribLocation(x,d)}y=a}return y};Object.defineProperties(this,{uniforms:{get:function(){console.warn("THREE.WebGLProgram: .uniforms is now .getUniforms().");return this.getUniforms()}},attributes:{get:function(){console.warn("THREE.WebGLProgram: .attributes is now .getAttributes().");return this.getAttributes()}}});this.id=c++;this.code=e;this.usedTimes=1;this.program=x;this.vertexShader=l;this.fragmentShader=n;return this}}();
+"#define SHADOWMAP_DEBUG":"",f.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",f.logarithmicDepthBuffer&&d.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","\n"].filter(b).join("\n"));n=d+n;l=THREE.WebGLShader(h,h.VERTEX_SHADER,k+l);n=THREE.WebGLShader(h,h.FRAGMENT_SHADER,n);h.attachShader(w,l);h.attachShader(w,n);void 0!==g.index0AttributeName?h.bindAttribLocation(w,0,g.index0AttributeName):!0===f.morphTargets&&h.bindAttribLocation(w,
+0,"position");h.linkProgram(w);f=h.getProgramInfoLog(w);p=h.getShaderInfoLog(l);m=h.getShaderInfoLog(n);t=q=!0;if(!1===h.getProgramParameter(w,h.LINK_STATUS))q=!1,console.error("THREE.WebGLProgram: shader error: ",h.getError(),"gl.VALIDATE_STATUS",h.getProgramParameter(w,h.VALIDATE_STATUS),"gl.getProgramInfoLog",f,p,m);else if(""!==f)console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",f);else if(""===p||""===m)t=!1;t&&(this.diagnostics={runnable:q,material:g,programLog:f,vertexShader:{log:p,
+prefix:k},fragmentShader:{log:m,prefix:d}});h.deleteShader(l);h.deleteShader(n);var u;this.getUniforms=function(){if(void 0===u){for(var a={},b=h.getProgramParameter(w,h.ACTIVE_UNIFORMS),c=0;c<b;c++){var d=h.getActiveUniform(w,c).name,e=h.getUniformLocation(w,d),f=d.lastIndexOf("[0]");-1!==f&&f===d.length-3&&(a[d.substr(0,f)]=e);a[d]=e}u=a}return u};var z;this.getAttributes=function(){if(void 0===z){for(var a={},b=h.getProgramParameter(w,h.ACTIVE_ATTRIBUTES),c=0;c<b;c++){var d=h.getActiveAttrib(w,
+c).name;a[d]=h.getAttribLocation(w,d)}z=a}return z};Object.defineProperties(this,{uniforms:{get:function(){console.warn("THREE.WebGLProgram: .uniforms is now .getUniforms().");return this.getUniforms()}},attributes:{get:function(){console.warn("THREE.WebGLProgram: .attributes is now .getAttributes().");return this.getAttributes()}}});this.id=c++;this.code=e;this.usedTimes=1;this.program=w;this.vertexShader=l;this.fragmentShader=n;return this}}();
 THREE.WebGLProperties=function(){var a={};this.get=function(b){b=b.uuid;var c=a[b];void 0===c&&(c={},a[b]=c);return c};this.delete=function(b){delete a[b.uuid]};this.clear=function(){a={}}};
 THREE.WebGLShader=function(){var a=function(a){a=a.split("\n");for(var c=0;c<a.length;c++)a[c]=c+1+": "+a[c];return a.join("\n")};return function(b,c,d){var e=b.createShader(c);b.shaderSource(e,d);b.compileShader(e);!1===b.getShaderParameter(e,b.COMPILE_STATUS)&&console.error("THREE.WebGLShader: Shader couldn't compile.");""!==b.getShaderInfoLog(e)&&console.warn("THREE.WebGLShader: gl.getShaderInfoLog()",c===b.VERTEX_SHADER?"vertex":"fragment",b.getShaderInfoLog(e),a(d));return e}}();
-THREE.WebGLShadowMap=function(a,b,c){function d(a,b){var c=a.geometry,c=void 0!==c.morphTargets&&0<c.morphTargets.length&&b.morphTargets,d=a instanceof THREE.SkinnedMesh&&b.skinning,c=a.customDepthMaterial?a.customDepthMaterial:d?c?u:r:c?s:q;c.visible=b.visible;c.wireframe=b.wireframe;c.wireframeLinewidth=b.wireframeLinewidth;return c}function e(a,b){if(!1!==a.visible){(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.PointCloud)&&a.castShadow&&(!1===a.frustumCulled||!0===h.intersectsObject(a))&&
-!0===a.material.visible&&(a.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld),n.push(a));for(var c=a.children,d=0,f=c.length;d<f;d++)e(c[d],b)}}var g=a.context,f=a.state,h=new THREE.Frustum,k=new THREE.Matrix4;new THREE.Vector3;new THREE.Vector3;var l=new THREE.Vector3,n=[],p=THREE.ShaderLib.depthRGBA,m=THREE.UniformsUtils.clone(p.uniforms),q=new THREE.ShaderMaterial({uniforms:m,vertexShader:p.vertexShader,fragmentShader:p.fragmentShader}),s=new THREE.ShaderMaterial({uniforms:m,
-vertexShader:p.vertexShader,fragmentShader:p.fragmentShader,morphTargets:!0}),r=new THREE.ShaderMaterial({uniforms:m,vertexShader:p.vertexShader,fragmentShader:p.fragmentShader,skinning:!0}),u=new THREE.ShaderMaterial({uniforms:m,vertexShader:p.vertexShader,fragmentShader:p.fragmentShader,morphTargets:!0,skinning:!0});q._shadowPass=!0;s._shadowPass=!0;r._shadowPass=!0;u._shadowPass=!0;var x=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=THREE.PCFShadowMap;this.cullFace=THREE.CullFaceFront;
-this.render=function(m,q){if(!1!==x.enabled&&(!1!==x.autoUpdate||!1!==x.needsUpdate)){g.clearColor(1,1,1,1);f.disable(g.BLEND);f.enable(g.CULL_FACE);g.frontFace(g.CCW);x.cullFace===THREE.CullFaceFront?g.cullFace(g.FRONT):g.cullFace(g.BACK);f.setDepthTest(!0);for(var p=0,s=b.length;p<s;p++){var r=b[p];if(r.castShadow){if(!r.shadowMap){var u=THREE.LinearFilter;x.type===THREE.PCFSoftShadowMap&&(u=THREE.NearestFilter);r.shadowMap=new THREE.WebGLRenderTarget(r.shadowMapWidth,r.shadowMapHeight,{minFilter:u,
-magFilter:u,format:THREE.RGBAFormat});r.shadowMapSize=new THREE.Vector2(r.shadowMapWidth,r.shadowMapHeight);r.shadowMatrix=new THREE.Matrix4}if(!r.shadowCamera){if(r instanceof THREE.SpotLight)r.shadowCamera=new THREE.PerspectiveCamera(r.shadowCameraFov,r.shadowMapWidth/r.shadowMapHeight,r.shadowCameraNear,r.shadowCameraFar);else if(r instanceof THREE.DirectionalLight)r.shadowCamera=new THREE.OrthographicCamera(r.shadowCameraLeft,r.shadowCameraRight,r.shadowCameraTop,r.shadowCameraBottom,r.shadowCameraNear,
-r.shadowCameraFar);else{console.error("THREE.ShadowMapPlugin: Unsupported light type for shadow",r);continue}m.add(r.shadowCamera);!0===m.autoUpdate&&m.updateMatrixWorld()}r.shadowCameraVisible&&!r.cameraHelper&&(r.cameraHelper=new THREE.CameraHelper(r.shadowCamera),m.add(r.cameraHelper));var A=r.shadowMap,O=r.shadowMatrix,u=r.shadowCamera;u.position.setFromMatrixPosition(r.matrixWorld);l.setFromMatrixPosition(r.target.matrixWorld);u.lookAt(l);u.updateMatrixWorld();u.matrixWorldInverse.getInverse(u.matrixWorld);
-r.cameraHelper&&(r.cameraHelper.visible=r.shadowCameraVisible);r.shadowCameraVisible&&r.cameraHelper.update();O.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);O.multiply(u.projectionMatrix);O.multiply(u.matrixWorldInverse);k.multiplyMatrices(u.projectionMatrix,u.matrixWorldInverse);h.setFromMatrix(k);a.setRenderTarget(A);a.clear();n.length=0;e(m,u);r=0;for(A=n.length;r<A;r++){var O=n[r],K=c.update(O),D=O.material;if(D instanceof THREE.MeshFaceMaterial)for(var P=K.groups,D=D.materials,J=0,H=P.length;J<
-H;J++){var C=P[J],F=D[C.materialIndex];!0===F.visible&&a.renderBufferDirect(u,b,null,K,d(O,F),O,C)}else a.renderBufferDirect(u,b,null,K,d(O,D),O)}}}p=a.getClearColor();s=a.getClearAlpha();g.clearColor(p.r,p.g,p.b,s);f.enable(g.BLEND);x.cullFace===THREE.CullFaceFront&&g.cullFace(g.BACK);a.resetGLState();x.needsUpdate=!1}}};
-THREE.WebGLState=function(a,b,c){var d=this,e=new Uint8Array(16),g=new Uint8Array(16),f={},h=null,k=null,l=null,n=null,p=null,m=null,q=null,s=null,r=null,u=null,x=null,v=null,y=null,w=null,G=null,B=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),z=void 0,A={};this.init=function(){a.clearColor(0,0,0,1);a.clearDepth(1);a.clearStencil(0);this.enable(a.DEPTH_TEST);a.depthFunc(a.LEQUAL);a.frontFace(a.CCW);a.cullFace(a.BACK);this.enable(a.CULL_FACE);this.enable(a.BLEND);a.blendEquation(a.FUNC_ADD);a.blendFunc(a.SRC_ALPHA,
+THREE.WebGLShadowMap=function(a,b,c){function d(a,b){var c=a.geometry,c=void 0!==c.morphTargets&&0<c.morphTargets.length&&b.morphTargets,d=a instanceof THREE.SkinnedMesh&&b.skinning,c=a.customDepthMaterial?a.customDepthMaterial:d?c?v:r:c?t:q;c.visible=b.visible;c.wireframe=b.wireframe;c.wireframeLinewidth=b.wireframeLinewidth;return c}function e(a,b){if(!1!==a.visible){(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.PointCloud)&&a.castShadow&&(!1===a.frustumCulled||!0===h.intersectsObject(a))&&
+!0===a.material.visible&&(a.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld),n.push(a));for(var c=a.children,d=0,f=c.length;d<f;d++)e(c[d],b)}}var g=a.context,f=a.state,h=new THREE.Frustum,k=new THREE.Matrix4;new THREE.Vector3;new THREE.Vector3;var l=new THREE.Vector3,n=[],p=THREE.ShaderLib.depthRGBA,m=THREE.UniformsUtils.clone(p.uniforms),q=new THREE.ShaderMaterial({uniforms:m,vertexShader:p.vertexShader,fragmentShader:p.fragmentShader}),t=new THREE.ShaderMaterial({uniforms:m,
+vertexShader:p.vertexShader,fragmentShader:p.fragmentShader,morphTargets:!0}),r=new THREE.ShaderMaterial({uniforms:m,vertexShader:p.vertexShader,fragmentShader:p.fragmentShader,skinning:!0}),v=new THREE.ShaderMaterial({uniforms:m,vertexShader:p.vertexShader,fragmentShader:p.fragmentShader,morphTargets:!0,skinning:!0});q._shadowPass=!0;t._shadowPass=!0;r._shadowPass=!0;v._shadowPass=!0;var w=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=THREE.PCFShadowMap;this.cullFace=THREE.CullFaceFront;
+this.render=function(m,q){if(!1!==w.enabled&&(!1!==w.autoUpdate||!1!==w.needsUpdate)){g.clearColor(1,1,1,1);f.disable(g.BLEND);f.enable(g.CULL_FACE);g.frontFace(g.CCW);w.cullFace===THREE.CullFaceFront?g.cullFace(g.FRONT):g.cullFace(g.BACK);f.setDepthTest(!0);for(var p=0,t=b.length;p<t;p++){var r=b[p];if(r.castShadow){if(!r.shadowMap){var v=THREE.LinearFilter;w.type===THREE.PCFSoftShadowMap&&(v=THREE.NearestFilter);r.shadowMap=new THREE.WebGLRenderTarget(r.shadowMapWidth,r.shadowMapHeight,{minFilter:v,
+magFilter:v,format:THREE.RGBAFormat});r.shadowMapSize=new THREE.Vector2(r.shadowMapWidth,r.shadowMapHeight);r.shadowMatrix=new THREE.Matrix4}if(!r.shadowCamera){if(r instanceof THREE.SpotLight)r.shadowCamera=new THREE.PerspectiveCamera(r.shadowCameraFov,r.shadowMapWidth/r.shadowMapHeight,r.shadowCameraNear,r.shadowCameraFar);else if(r instanceof THREE.DirectionalLight)r.shadowCamera=new THREE.OrthographicCamera(r.shadowCameraLeft,r.shadowCameraRight,r.shadowCameraTop,r.shadowCameraBottom,r.shadowCameraNear,
+r.shadowCameraFar);else{console.error("THREE.ShadowMapPlugin: Unsupported light type for shadow",r);continue}m.add(r.shadowCamera);!0===m.autoUpdate&&m.updateMatrixWorld()}r.shadowCameraVisible&&!r.cameraHelper&&(r.cameraHelper=new THREE.CameraHelper(r.shadowCamera),m.add(r.cameraHelper));var B=r.shadowMap,L=r.shadowMatrix,v=r.shadowCamera;v.position.setFromMatrixPosition(r.matrixWorld);l.setFromMatrixPosition(r.target.matrixWorld);v.lookAt(l);v.updateMatrixWorld();v.matrixWorldInverse.getInverse(v.matrixWorld);
+r.cameraHelper&&(r.cameraHelper.visible=r.shadowCameraVisible);r.shadowCameraVisible&&r.cameraHelper.update();L.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);L.multiply(v.projectionMatrix);L.multiply(v.matrixWorldInverse);k.multiplyMatrices(v.projectionMatrix,v.matrixWorldInverse);h.setFromMatrix(k);a.setRenderTarget(B);a.clear();n.length=0;e(m,v);r=0;for(B=n.length;r<B;r++){var L=n[r],N=c.update(L),C=L.material;if(C instanceof THREE.MeshFaceMaterial)for(var O=N.groups,C=C.materials,G=0,J=O.length;G<
+J;G++){var A=O[G],H=C[A.materialIndex];!0===H.visible&&a.renderBufferDirect(v,b,null,N,d(L,H),L,A)}else a.renderBufferDirect(v,b,null,N,d(L,C),L)}}}p=a.getClearColor();t=a.getClearAlpha();g.clearColor(p.r,p.g,p.b,t);f.enable(g.BLEND);w.cullFace===THREE.CullFaceFront&&g.cullFace(g.BACK);a.resetGLState();w.needsUpdate=!1}}};
+THREE.WebGLState=function(a,b,c){var d=this,e=new Uint8Array(16),g=new Uint8Array(16),f={},h=null,k=null,l=null,n=null,p=null,m=null,q=null,t=null,r=null,v=null,w=null,u=null,z=null,x=null,D=null,F=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),y=void 0,B={};this.init=function(){a.clearColor(0,0,0,1);a.clearDepth(1);a.clearStencil(0);this.enable(a.DEPTH_TEST);a.depthFunc(a.LEQUAL);a.frontFace(a.CCW);a.cullFace(a.BACK);this.enable(a.CULL_FACE);this.enable(a.BLEND);a.blendEquation(a.FUNC_ADD);a.blendFunc(a.SRC_ALPHA,
 a.ONE_MINUS_SRC_ALPHA)};this.initAttributes=function(){for(var a=0,b=e.length;a<b;a++)e[a]=0};this.enableAttribute=function(b){e[b]=1;0===g[b]&&(a.enableVertexAttribArray(b),g[b]=1)};this.disableUnusedAttributes=function(){for(var b=0,c=g.length;b<c;b++)g[b]!==e[b]&&(a.disableVertexAttribArray(b),g[b]=0)};this.enable=function(b){!0!==f[b]&&(a.enable(b),f[b]=!0)};this.disable=function(b){!1!==f[b]&&(a.disable(b),f[b]=!1)};this.getCompressedTextureFormats=function(){if(null===h&&(h=[],b.get("WEBGL_compressed_texture_pvrtc")||
 b.get("WEBGL_compressed_texture_s3tc")))for(var c=a.getParameter(a.COMPRESSED_TEXTURE_FORMATS),d=0;d<c.length;d++)h.push(c[d]);return h};this.setBlending=function(b,d,e,f,g,h,r){b!==k&&(b===THREE.NoBlending?this.disable(a.BLEND):b===THREE.AdditiveBlending?(this.enable(a.BLEND),a.blendEquation(a.FUNC_ADD),a.blendFunc(a.SRC_ALPHA,a.ONE)):b===THREE.SubtractiveBlending?(this.enable(a.BLEND),a.blendEquation(a.FUNC_ADD),a.blendFunc(a.ZERO,a.ONE_MINUS_SRC_COLOR)):b===THREE.MultiplyBlending?(this.enable(a.BLEND),
-a.blendEquation(a.FUNC_ADD),a.blendFunc(a.ZERO,a.SRC_COLOR)):b===THREE.CustomBlending?this.enable(a.BLEND):(this.enable(a.BLEND),a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.SRC_ALPHA,a.ONE_MINUS_SRC_ALPHA,a.ONE,a.ONE_MINUS_SRC_ALPHA)),k=b);if(b===THREE.CustomBlending){g=g||d;h=h||e;r=r||f;if(d!==l||g!==m)a.blendEquationSeparate(c(d),c(g)),l=d,m=g;if(e!==n||f!==p||h!==q||r!==s)a.blendFuncSeparate(c(e),c(f),c(h),c(r)),n=e,p=f,q=h,s=r}else s=q=m=p=n=l=null};this.setDepthFunc=
+a.blendEquation(a.FUNC_ADD),a.blendFunc(a.ZERO,a.SRC_COLOR)):b===THREE.CustomBlending?this.enable(a.BLEND):(this.enable(a.BLEND),a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.SRC_ALPHA,a.ONE_MINUS_SRC_ALPHA,a.ONE,a.ONE_MINUS_SRC_ALPHA)),k=b);if(b===THREE.CustomBlending){g=g||d;h=h||e;r=r||f;if(d!==l||g!==m)a.blendEquationSeparate(c(d),c(g)),l=d,m=g;if(e!==n||f!==p||h!==q||r!==t)a.blendFuncSeparate(c(e),c(f),c(h),c(r)),n=e,p=f,q=h,t=r}else t=q=m=p=n=l=null};this.setDepthFunc=
 function(b){if(r!==b){if(b)switch(b){case THREE.NeverDepth:a.depthFunc(a.NEVER);break;case THREE.AlwaysDepth:a.depthFunc(a.ALWAYS);break;case THREE.LessDepth:a.depthFunc(a.LESS);break;case THREE.LessEqualDepth:a.depthFunc(a.LEQUAL);break;case THREE.EqualDepth:a.depthFunc(a.EQUAL);break;case THREE.GreaterEqualDepth:a.depthFunc(a.GEQUAL);break;case THREE.GreaterDepth:a.depthFunc(a.GREATER);break;case THREE.NotEqualDepth:a.depthFunc(a.NOTEQUAL);break;default:a.depthFunc(a.LEQUAL)}else a.depthFunc(a.LEQUAL);
-r=b}};this.setDepthTest=function(b){b?this.enable(a.DEPTH_TEST):this.disable(a.DEPTH_TEST)};this.setDepthWrite=function(b){u!==b&&(a.depthMask(b),u=b)};this.setColorWrite=function(b){x!==b&&(a.colorMask(b,b,b,b),x=b)};this.setFlipSided=function(b){v!==b&&(b?a.frontFace(a.CW):a.frontFace(a.CCW),v=b)};this.setLineWidth=function(b){b!==y&&(a.lineWidth(b),y=b)};this.setPolygonOffset=function(b,c,d){b?this.enable(a.POLYGON_OFFSET_FILL):this.disable(a.POLYGON_OFFSET_FILL);!b||w===c&&G===d||(a.polygonOffset(c,
-d),w=c,G=d)};this.setScissorTest=function(b){b?this.enable(a.SCISSOR_TEST):this.disable(a.SCISSOR_TEST)};this.activeTexture=function(b){void 0===b&&(b=a.TEXTURE0+B-1);z!==b&&(a.activeTexture(b),z=b)};this.bindTexture=function(b,c){void 0===z&&d.activeTexture();var e=A[z];void 0===e&&(e={type:void 0,texture:void 0},A[z]=e);if(e.type!==b||e.texture!==c)a.bindTexture(b,c),e.type=b,e.texture=c};this.compressedTexImage2D=function(){try{a.compressedTexImage2D.apply(a,arguments)}catch(b){console.error(b)}};
-this.texImage2D=function(){try{a.texImage2D.apply(a,arguments)}catch(b){console.error(b)}};this.reset=function(){for(var b=0;b<g.length;b++)1===g[b]&&(a.disableVertexAttribArray(b),g[b]=0);f={};v=x=u=k=h=null}};
-THREE.LensFlarePlugin=function(a,b){var c,d,e,g,f,h,k,l,n,p,m=a.context,q=a.state,s,r,u,x,v,y;this.render=function(w,G,B,z){if(0!==b.length){w=new THREE.Vector3;var A=z/B,O=.5*B,K=.5*z,D=16/z,P=new THREE.Vector2(D*A,D),J=new THREE.Vector3(1,1,0),H=new THREE.Vector2(1,1);if(void 0===u){var D=new Float32Array([-1,-1,0,0,1,-1,1,0,1,1,1,1,-1,1,0,1]),C=new Uint16Array([0,1,2,0,2,3]);s=m.createBuffer();r=m.createBuffer();m.bindBuffer(m.ARRAY_BUFFER,s);m.bufferData(m.ARRAY_BUFFER,D,m.STATIC_DRAW);m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,
-r);m.bufferData(m.ELEMENT_ARRAY_BUFFER,C,m.STATIC_DRAW);v=m.createTexture();y=m.createTexture();q.bindTexture(m.TEXTURE_2D,v);m.texImage2D(m.TEXTURE_2D,0,m.RGB,16,16,0,m.RGB,m.UNSIGNED_BYTE,null);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MAG_FILTER,m.NEAREST);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MIN_FILTER,m.NEAREST);q.bindTexture(m.TEXTURE_2D,y);m.texImage2D(m.TEXTURE_2D,0,
-m.RGBA,16,16,0,m.RGBA,m.UNSIGNED_BYTE,null);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MAG_FILTER,m.NEAREST);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MIN_FILTER,m.NEAREST);var D=(x=0<m.getParameter(m.MAX_VERTEX_TEXTURE_IMAGE_UNITS))?{vertexShader:"uniform lowp int renderType;\nuniform vec3 screenPosition;\nuniform vec2 scale;\nuniform float rotation;\nuniform sampler2D occlusionMap;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nvUV = uv;\nvec2 pos = position;\nif( renderType == 2 ) {\nvec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\nvVisibility =        visibility.r / 9.0;\nvVisibility *= 1.0 - visibility.g / 9.0;\nvVisibility *=       visibility.b / 9.0;\nvVisibility *= 1.0 - visibility.a / 9.0;\npos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\npos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\n}\ngl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n}",
+r=b}};this.setDepthTest=function(b){b?this.enable(a.DEPTH_TEST):this.disable(a.DEPTH_TEST)};this.setDepthWrite=function(b){v!==b&&(a.depthMask(b),v=b)};this.setColorWrite=function(b){w!==b&&(a.colorMask(b,b,b,b),w=b)};this.setFlipSided=function(b){u!==b&&(b?a.frontFace(a.CW):a.frontFace(a.CCW),u=b)};this.setLineWidth=function(b){b!==z&&(a.lineWidth(b),z=b)};this.setPolygonOffset=function(b,c,d){b?this.enable(a.POLYGON_OFFSET_FILL):this.disable(a.POLYGON_OFFSET_FILL);!b||x===c&&D===d||(a.polygonOffset(c,
+d),x=c,D=d)};this.setScissorTest=function(b){b?this.enable(a.SCISSOR_TEST):this.disable(a.SCISSOR_TEST)};this.activeTexture=function(b){void 0===b&&(b=a.TEXTURE0+F-1);y!==b&&(a.activeTexture(b),y=b)};this.bindTexture=function(b,c){void 0===y&&d.activeTexture();var e=B[y];void 0===e&&(e={type:void 0,texture:void 0},B[y]=e);if(e.type!==b||e.texture!==c)a.bindTexture(b,c),e.type=b,e.texture=c};this.compressedTexImage2D=function(){try{a.compressedTexImage2D.apply(a,arguments)}catch(b){console.error(b)}};
+this.texImage2D=function(){try{a.texImage2D.apply(a,arguments)}catch(b){console.error(b)}};this.reset=function(){for(var b=0;b<g.length;b++)1===g[b]&&(a.disableVertexAttribArray(b),g[b]=0);f={};u=w=v=k=h=null}};
+THREE.LensFlarePlugin=function(a,b){var c,d,e,g,f,h,k,l,n,p,m=a.context,q=a.state,t,r,v,w,u,z;this.render=function(x,D,F,y){if(0!==b.length){x=new THREE.Vector3;var B=y/F,L=.5*F,N=.5*y,C=16/y,O=new THREE.Vector2(C*B,C),G=new THREE.Vector3(1,1,0),J=new THREE.Vector2(1,1);if(void 0===v){var C=new Float32Array([-1,-1,0,0,1,-1,1,0,1,1,1,1,-1,1,0,1]),A=new Uint16Array([0,1,2,0,2,3]);t=m.createBuffer();r=m.createBuffer();m.bindBuffer(m.ARRAY_BUFFER,t);m.bufferData(m.ARRAY_BUFFER,C,m.STATIC_DRAW);m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,
+r);m.bufferData(m.ELEMENT_ARRAY_BUFFER,A,m.STATIC_DRAW);u=m.createTexture();z=m.createTexture();q.bindTexture(m.TEXTURE_2D,u);m.texImage2D(m.TEXTURE_2D,0,m.RGB,16,16,0,m.RGB,m.UNSIGNED_BYTE,null);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MAG_FILTER,m.NEAREST);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MIN_FILTER,m.NEAREST);q.bindTexture(m.TEXTURE_2D,z);m.texImage2D(m.TEXTURE_2D,0,
+m.RGBA,16,16,0,m.RGBA,m.UNSIGNED_BYTE,null);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MAG_FILTER,m.NEAREST);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MIN_FILTER,m.NEAREST);var C=(w=0<m.getParameter(m.MAX_VERTEX_TEXTURE_IMAGE_UNITS))?{vertexShader:"uniform lowp int renderType;\nuniform vec3 screenPosition;\nuniform vec2 scale;\nuniform float rotation;\nuniform sampler2D occlusionMap;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nvUV = uv;\nvec2 pos = position;\nif( renderType == 2 ) {\nvec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\nvVisibility =        visibility.r / 9.0;\nvVisibility *= 1.0 - visibility.g / 9.0;\nvVisibility *=       visibility.b / 9.0;\nvVisibility *= 1.0 - visibility.a / 9.0;\npos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\npos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\n}\ngl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n}",
 fragmentShader:"uniform lowp int renderType;\nuniform sampler2D map;\nuniform float opacity;\nuniform vec3 color;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nif( renderType == 0 ) {\ngl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\n} else if( renderType == 1 ) {\ngl_FragColor = texture2D( map, vUV );\n} else {\nvec4 texture = texture2D( map, vUV );\ntexture.a *= opacity * vVisibility;\ngl_FragColor = texture;\ngl_FragColor.rgb *= color;\n}\n}"}:{vertexShader:"uniform lowp int renderType;\nuniform vec3 screenPosition;\nuniform vec2 scale;\nuniform float rotation;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvoid main() {\nvUV = uv;\nvec2 pos = position;\nif( renderType == 2 ) {\npos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\npos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\n}\ngl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n}",
 fragmentShader:"precision mediump float;\nuniform lowp int renderType;\nuniform sampler2D map;\nuniform sampler2D occlusionMap;\nuniform float opacity;\nuniform vec3 color;\nvarying vec2 vUV;\nvoid main() {\nif( renderType == 0 ) {\ngl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );\n} else if( renderType == 1 ) {\ngl_FragColor = texture2D( map, vUV );\n} else {\nfloat visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a;\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a;\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a;\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;\nvisibility = ( 1.0 - visibility / 4.0 );\nvec4 texture = texture2D( map, vUV );\ntexture.a *= opacity * visibility;\ngl_FragColor = texture;\ngl_FragColor.rgb *= color;\n}\n}"},
-C=m.createProgram(),F=m.createShader(m.FRAGMENT_SHADER),N=m.createShader(m.VERTEX_SHADER),R="precision "+a.getPrecision()+" float;\n";m.shaderSource(F,R+D.fragmentShader);m.shaderSource(N,R+D.vertexShader);m.compileShader(F);m.compileShader(N);m.attachShader(C,F);m.attachShader(C,N);m.linkProgram(C);u=C;n=m.getAttribLocation(u,"position");p=m.getAttribLocation(u,"uv");c=m.getUniformLocation(u,"renderType");d=m.getUniformLocation(u,"map");e=m.getUniformLocation(u,"occlusionMap");g=m.getUniformLocation(u,
-"opacity");f=m.getUniformLocation(u,"color");h=m.getUniformLocation(u,"scale");k=m.getUniformLocation(u,"rotation");l=m.getUniformLocation(u,"screenPosition")}m.useProgram(u);q.initAttributes();q.enableAttribute(n);q.enableAttribute(p);q.disableUnusedAttributes();m.uniform1i(e,0);m.uniform1i(d,1);m.bindBuffer(m.ARRAY_BUFFER,s);m.vertexAttribPointer(n,2,m.FLOAT,!1,16,0);m.vertexAttribPointer(p,2,m.FLOAT,!1,16,8);m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,r);q.disable(m.CULL_FACE);m.depthMask(!1);C=0;for(F=
-b.length;C<F;C++)if(D=16/z,P.set(D*A,D),N=b[C],w.set(N.matrixWorld.elements[12],N.matrixWorld.elements[13],N.matrixWorld.elements[14]),w.applyMatrix4(G.matrixWorldInverse),w.applyProjection(G.projectionMatrix),J.copy(w),H.x=J.x*O+O,H.y=J.y*K+K,x||0<H.x&&H.x<B&&0<H.y&&H.y<z){q.activeTexture(m.TEXTURE0);q.bindTexture(m.TEXTURE_2D,null);q.activeTexture(m.TEXTURE1);q.bindTexture(m.TEXTURE_2D,v);m.copyTexImage2D(m.TEXTURE_2D,0,m.RGB,H.x-8,H.y-8,16,16,0);m.uniform1i(c,0);m.uniform2f(h,P.x,P.y);m.uniform3f(l,
-J.x,J.y,J.z);q.disable(m.BLEND);q.enable(m.DEPTH_TEST);m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0);q.activeTexture(m.TEXTURE0);q.bindTexture(m.TEXTURE_2D,y);m.copyTexImage2D(m.TEXTURE_2D,0,m.RGBA,H.x-8,H.y-8,16,16,0);m.uniform1i(c,1);q.disable(m.DEPTH_TEST);q.activeTexture(m.TEXTURE1);q.bindTexture(m.TEXTURE_2D,v);m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0);N.positionScreen.copy(J);N.customUpdateCallback?N.customUpdateCallback(N):N.updateLensFlares();m.uniform1i(c,2);q.enable(m.BLEND);for(var R=
-0,U=N.lensFlares.length;R<U;R++){var Q=N.lensFlares[R];.001<Q.opacity&&.001<Q.scale&&(J.x=Q.x,J.y=Q.y,J.z=Q.z,D=Q.size*Q.scale/z,P.x=D*A,P.y=D,m.uniform3f(l,J.x,J.y,J.z),m.uniform2f(h,P.x,P.y),m.uniform1f(k,Q.rotation),m.uniform1f(g,Q.opacity),m.uniform3f(f,Q.color.r,Q.color.g,Q.color.b),q.setBlending(Q.blending,Q.blendEquation,Q.blendSrc,Q.blendDst),a.setTexture(Q.texture,1),m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0))}}q.enable(m.CULL_FACE);q.enable(m.DEPTH_TEST);m.depthMask(!0);a.resetGLState()}}};
-THREE.SpritePlugin=function(a,b){var c,d,e,g,f,h,k,l,n,p,m,q,s,r,u,x,v;function y(a,b){return a.z!==b.z?b.z-a.z:b.id-a.id}var w=a.context,G=a.state,B,z,A,O,K=new THREE.Vector3,D=new THREE.Quaternion,P=new THREE.Vector3;this.render=function(J,H){if(0!==b.length){if(void 0===A){var C=new Float32Array([-.5,-.5,0,0,.5,-.5,1,0,.5,.5,1,1,-.5,.5,0,1]),F=new Uint16Array([0,1,2,0,2,3]);B=w.createBuffer();z=w.createBuffer();w.bindBuffer(w.ARRAY_BUFFER,B);w.bufferData(w.ARRAY_BUFFER,C,w.STATIC_DRAW);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,
-z);w.bufferData(w.ELEMENT_ARRAY_BUFFER,F,w.STATIC_DRAW);var C=w.createProgram(),F=w.createShader(w.VERTEX_SHADER),N=w.createShader(w.FRAGMENT_SHADER);w.shaderSource(F,["precision "+a.getPrecision()+" float;","uniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform float rotation;\nuniform vec2 scale;\nuniform vec2 uvOffset;\nuniform vec2 uvScale;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvoid main() {\nvUV = uvOffset + uv * uvScale;\nvec2 alignedPosition = position * scale;\nvec2 rotatedPosition;\nrotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\nrotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\nvec4 finalPosition;\nfinalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\nfinalPosition.xy += rotatedPosition;\nfinalPosition = projectionMatrix * finalPosition;\ngl_Position = finalPosition;\n}"].join("\n"));
-w.shaderSource(N,["precision "+a.getPrecision()+" float;","uniform vec3 color;\nuniform sampler2D map;\nuniform float opacity;\nuniform int fogType;\nuniform vec3 fogColor;\nuniform float fogDensity;\nuniform float fogNear;\nuniform float fogFar;\nuniform float alphaTest;\nvarying vec2 vUV;\nvoid main() {\nvec4 texture = texture2D( map, vUV );\nif ( texture.a < alphaTest ) discard;\ngl_FragColor = vec4( color * texture.xyz, texture.a * opacity );\nif ( fogType > 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;\nfogFactor = 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(F);w.compileShader(N);w.attachShader(C,F);w.attachShader(C,N);w.linkProgram(C);A=C;x=w.getAttribLocation(A,"position");v=w.getAttribLocation(A,"uv");c=w.getUniformLocation(A,"uvOffset");d=w.getUniformLocation(A,"uvScale");e=w.getUniformLocation(A,"rotation");g=w.getUniformLocation(A,"scale");f=w.getUniformLocation(A,"color");h=w.getUniformLocation(A,"map");k=w.getUniformLocation(A,"opacity");l=w.getUniformLocation(A,"modelViewMatrix");n=w.getUniformLocation(A,"projectionMatrix");p=
-w.getUniformLocation(A,"fogType");m=w.getUniformLocation(A,"fogDensity");q=w.getUniformLocation(A,"fogNear");s=w.getUniformLocation(A,"fogFar");r=w.getUniformLocation(A,"fogColor");u=w.getUniformLocation(A,"alphaTest");C=document.createElement("canvas");C.width=8;C.height=8;F=C.getContext("2d");F.fillStyle="white";F.fillRect(0,0,8,8);O=new THREE.Texture(C);O.needsUpdate=!0}w.useProgram(A);G.initAttributes();G.enableAttribute(x);G.enableAttribute(v);G.disableUnusedAttributes();G.disable(w.CULL_FACE);
-G.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER,B);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,z);w.uniformMatrix4fv(n,!1,H.projectionMatrix.elements);G.activeTexture(w.TEXTURE0);w.uniform1i(h,0);F=C=0;(N=J.fog)?(w.uniform3f(r,N.color.r,N.color.g,N.color.b),N instanceof THREE.Fog?(w.uniform1f(q,N.near),w.uniform1f(s,N.far),w.uniform1i(p,1),F=C=1):N instanceof THREE.FogExp2&&(w.uniform1f(m,N.density),w.uniform1i(p,2),F=C=2)):
-(w.uniform1i(p,0),F=C=0);for(var N=0,R=b.length;N<R;N++){var U=b[N];U.modelViewMatrix.multiplyMatrices(H.matrixWorldInverse,U.matrixWorld);U.z=-U.modelViewMatrix.elements[14]}b.sort(y);for(var Q=[],N=0,R=b.length;N<R;N++){var U=b[N],S=U.material;w.uniform1f(u,S.alphaTest);w.uniformMatrix4fv(l,!1,U.modelViewMatrix.elements);U.matrixWorld.decompose(K,D,P);Q[0]=P.x;Q[1]=P.y;U=0;J.fog&&S.fog&&(U=F);C!==U&&(w.uniform1i(p,U),C=U);null!==S.map?(w.uniform2f(c,S.map.offset.x,S.map.offset.y),w.uniform2f(d,
-S.map.repeat.x,S.map.repeat.y)):(w.uniform2f(c,0,0),w.uniform2f(d,1,1));w.uniform1f(k,S.opacity);w.uniform3f(f,S.color.r,S.color.g,S.color.b);w.uniform1f(e,S.rotation);w.uniform2fv(g,Q);G.setBlending(S.blending,S.blendEquation,S.blendSrc,S.blendDst);G.setDepthTest(S.depthTest);G.setDepthWrite(S.depthWrite);S.map&&S.map.image&&S.map.image.width?a.setTexture(S.map,0):a.setTexture(O,0);w.drawElements(w.TRIANGLES,6,w.UNSIGNED_SHORT,0)}G.enable(w.CULL_FACE);a.resetGLState()}}};
+A=m.createProgram(),H=m.createShader(m.FRAGMENT_SHADER),P=m.createShader(m.VERTEX_SHADER),Q="precision "+a.getPrecision()+" float;\n";m.shaderSource(H,Q+C.fragmentShader);m.shaderSource(P,Q+C.vertexShader);m.compileShader(H);m.compileShader(P);m.attachShader(A,H);m.attachShader(A,P);m.linkProgram(A);v=A;n=m.getAttribLocation(v,"position");p=m.getAttribLocation(v,"uv");c=m.getUniformLocation(v,"renderType");d=m.getUniformLocation(v,"map");e=m.getUniformLocation(v,"occlusionMap");g=m.getUniformLocation(v,
+"opacity");f=m.getUniformLocation(v,"color");h=m.getUniformLocation(v,"scale");k=m.getUniformLocation(v,"rotation");l=m.getUniformLocation(v,"screenPosition")}m.useProgram(v);q.initAttributes();q.enableAttribute(n);q.enableAttribute(p);q.disableUnusedAttributes();m.uniform1i(e,0);m.uniform1i(d,1);m.bindBuffer(m.ARRAY_BUFFER,t);m.vertexAttribPointer(n,2,m.FLOAT,!1,16,0);m.vertexAttribPointer(p,2,m.FLOAT,!1,16,8);m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,r);q.disable(m.CULL_FACE);m.depthMask(!1);A=0;for(H=
+b.length;A<H;A++)if(C=16/y,O.set(C*B,C),P=b[A],x.set(P.matrixWorld.elements[12],P.matrixWorld.elements[13],P.matrixWorld.elements[14]),x.applyMatrix4(D.matrixWorldInverse),x.applyProjection(D.projectionMatrix),G.copy(x),J.x=G.x*L+L,J.y=G.y*N+N,w||0<J.x&&J.x<F&&0<J.y&&J.y<y){q.activeTexture(m.TEXTURE0);q.bindTexture(m.TEXTURE_2D,null);q.activeTexture(m.TEXTURE1);q.bindTexture(m.TEXTURE_2D,u);m.copyTexImage2D(m.TEXTURE_2D,0,m.RGB,J.x-8,J.y-8,16,16,0);m.uniform1i(c,0);m.uniform2f(h,O.x,O.y);m.uniform3f(l,
+G.x,G.y,G.z);q.disable(m.BLEND);q.enable(m.DEPTH_TEST);m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0);q.activeTexture(m.TEXTURE0);q.bindTexture(m.TEXTURE_2D,z);m.copyTexImage2D(m.TEXTURE_2D,0,m.RGBA,J.x-8,J.y-8,16,16,0);m.uniform1i(c,1);q.disable(m.DEPTH_TEST);q.activeTexture(m.TEXTURE1);q.bindTexture(m.TEXTURE_2D,u);m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0);P.positionScreen.copy(G);P.customUpdateCallback?P.customUpdateCallback(P):P.updateLensFlares();m.uniform1i(c,2);q.enable(m.BLEND);for(var Q=
+0,V=P.lensFlares.length;Q<V;Q++){var R=P.lensFlares[Q];.001<R.opacity&&.001<R.scale&&(G.x=R.x,G.y=R.y,G.z=R.z,C=R.size*R.scale/y,O.x=C*B,O.y=C,m.uniform3f(l,G.x,G.y,G.z),m.uniform2f(h,O.x,O.y),m.uniform1f(k,R.rotation),m.uniform1f(g,R.opacity),m.uniform3f(f,R.color.r,R.color.g,R.color.b),q.setBlending(R.blending,R.blendEquation,R.blendSrc,R.blendDst),a.setTexture(R.texture,1),m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0))}}q.enable(m.CULL_FACE);q.enable(m.DEPTH_TEST);m.depthMask(!0);a.resetGLState()}}};
+THREE.SpritePlugin=function(a,b){var c,d,e,g,f,h,k,l,n,p,m,q,t,r,v,w,u;function z(a,b){return a.z!==b.z?b.z-a.z:b.id-a.id}var x=a.context,D=a.state,F,y,B,L,N=new THREE.Vector3,C=new THREE.Quaternion,O=new THREE.Vector3;this.render=function(G,J){if(0!==b.length){if(void 0===B){var A=new Float32Array([-.5,-.5,0,0,.5,-.5,1,0,.5,.5,1,1,-.5,.5,0,1]),H=new Uint16Array([0,1,2,0,2,3]);F=x.createBuffer();y=x.createBuffer();x.bindBuffer(x.ARRAY_BUFFER,F);x.bufferData(x.ARRAY_BUFFER,A,x.STATIC_DRAW);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,
+y);x.bufferData(x.ELEMENT_ARRAY_BUFFER,H,x.STATIC_DRAW);var A=x.createProgram(),H=x.createShader(x.VERTEX_SHADER),P=x.createShader(x.FRAGMENT_SHADER);x.shaderSource(H,["precision "+a.getPrecision()+" float;","uniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform float rotation;\nuniform vec2 scale;\nuniform vec2 uvOffset;\nuniform vec2 uvScale;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvoid main() {\nvUV = uvOffset + uv * uvScale;\nvec2 alignedPosition = position * scale;\nvec2 rotatedPosition;\nrotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\nrotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\nvec4 finalPosition;\nfinalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\nfinalPosition.xy += rotatedPosition;\nfinalPosition = projectionMatrix * finalPosition;\ngl_Position = finalPosition;\n}"].join("\n"));
+x.shaderSource(P,["precision "+a.getPrecision()+" float;","uniform vec3 color;\nuniform sampler2D map;\nuniform float opacity;\nuniform int fogType;\nuniform vec3 fogColor;\nuniform float fogDensity;\nuniform float fogNear;\nuniform float fogFar;\nuniform float alphaTest;\nvarying vec2 vUV;\nvoid main() {\nvec4 texture = texture2D( map, vUV );\nif ( texture.a < alphaTest ) discard;\ngl_FragColor = vec4( color * texture.xyz, texture.a * opacity );\nif ( fogType > 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;\nfogFactor = 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(H);x.compileShader(P);x.attachShader(A,H);x.attachShader(A,P);x.linkProgram(A);B=A;w=x.getAttribLocation(B,"position");u=x.getAttribLocation(B,"uv");c=x.getUniformLocation(B,"uvOffset");d=x.getUniformLocation(B,"uvScale");e=x.getUniformLocation(B,"rotation");g=x.getUniformLocation(B,"scale");f=x.getUniformLocation(B,"color");h=x.getUniformLocation(B,"map");k=x.getUniformLocation(B,"opacity");l=x.getUniformLocation(B,"modelViewMatrix");n=x.getUniformLocation(B,"projectionMatrix");p=
+x.getUniformLocation(B,"fogType");m=x.getUniformLocation(B,"fogDensity");q=x.getUniformLocation(B,"fogNear");t=x.getUniformLocation(B,"fogFar");r=x.getUniformLocation(B,"fogColor");v=x.getUniformLocation(B,"alphaTest");A=document.createElement("canvas");A.width=8;A.height=8;H=A.getContext("2d");H.fillStyle="white";H.fillRect(0,0,8,8);L=new THREE.Texture(A);L.needsUpdate=!0}x.useProgram(B);D.initAttributes();D.enableAttribute(w);D.enableAttribute(u);D.disableUnusedAttributes();D.disable(x.CULL_FACE);
+D.enable(x.BLEND);x.bindBuffer(x.ARRAY_BUFFER,F);x.vertexAttribPointer(w,2,x.FLOAT,!1,16,0);x.vertexAttribPointer(u,2,x.FLOAT,!1,16,8);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,y);x.uniformMatrix4fv(n,!1,J.projectionMatrix.elements);D.activeTexture(x.TEXTURE0);x.uniform1i(h,0);H=A=0;(P=G.fog)?(x.uniform3f(r,P.color.r,P.color.g,P.color.b),P instanceof THREE.Fog?(x.uniform1f(q,P.near),x.uniform1f(t,P.far),x.uniform1i(p,1),H=A=1):P instanceof THREE.FogExp2&&(x.uniform1f(m,P.density),x.uniform1i(p,2),H=A=2)):
+(x.uniform1i(p,0),H=A=0);for(var P=0,Q=b.length;P<Q;P++){var V=b[P];V.modelViewMatrix.multiplyMatrices(J.matrixWorldInverse,V.matrixWorld);V.z=-V.modelViewMatrix.elements[14]}b.sort(z);for(var R=[],P=0,Q=b.length;P<Q;P++){var V=b[P],S=V.material;x.uniform1f(v,S.alphaTest);x.uniformMatrix4fv(l,!1,V.modelViewMatrix.elements);V.matrixWorld.decompose(N,C,O);R[0]=O.x;R[1]=O.y;V=0;G.fog&&S.fog&&(V=H);A!==V&&(x.uniform1i(p,V),A=V);null!==S.map?(x.uniform2f(c,S.map.offset.x,S.map.offset.y),x.uniform2f(d,
+S.map.repeat.x,S.map.repeat.y)):(x.uniform2f(c,0,0),x.uniform2f(d,1,1));x.uniform1f(k,S.opacity);x.uniform3f(f,S.color.r,S.color.g,S.color.b);x.uniform1f(e,S.rotation);x.uniform2fv(g,R);D.setBlending(S.blending,S.blendEquation,S.blendSrc,S.blendDst);D.setDepthTest(S.depthTest);D.setDepthWrite(S.depthWrite);S.map&&S.map.image&&S.map.image.width?a.setTexture(S.map,0):a.setTexture(L,0);x.drawElements(x.TRIANGLES,6,x.UNSIGNED_SHORT,0)}D.enable(x.CULL_FACE);a.resetGLState()}}};
 THREE.GeometryUtils={merge:function(a,b,c){console.warn("THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.");var d;b instanceof THREE.Mesh&&(b.matrixAutoUpdate&&b.updateMatrix(),d=b.matrix,b=b.geometry);a.merge(b,d,c)},center:function(a){console.warn("THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.");return a.center()}};
 THREE.ImageUtils={crossOrigin:void 0,loadTexture:function(a,b,c,d){var e=new THREE.ImageLoader;e.crossOrigin=this.crossOrigin;var g=new THREE.Texture(void 0,b);e.load(a,function(a){g.image=a;g.needsUpdate=!0;c&&c(g)},void 0,function(a){d&&d(a)});g.sourceFile=a;return g},loadTextureCube:function(a,b,c,d){var e=new THREE.ImageLoader;e.crossOrigin=this.crossOrigin;var g=new THREE.CubeTexture([],b),f=0;b=function(b){e.load(a[b],function(a){g.images[b]=a;f+=1;6===f&&(g.needsUpdate=!0,c&&c(g))},void 0,
 d)};for(var h=0,k=a.length;h<k;++h)b(h);return g},loadCompressedTexture:function(){console.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.")},getNormalMap:function(a,b){var c=function(a){var b=Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);return[a[0]/b,a[1]/b,a[2]/b]};b|=1;var d=a.width,e=a.height,g=document.createElement("canvas");
-g.width=d;g.height=e;var f=g.getContext("2d");f.drawImage(a,0,0);for(var h=f.getImageData(0,0,d,e).data,k=f.createImageData(d,e),l=k.data,n=0;n<d;n++)for(var p=0;p<e;p++){var m=0>p-1?0:p-1,q=p+1>e-1?e-1:p+1,s=0>n-1?0:n-1,r=n+1>d-1?d-1:n+1,u=[],x=[0,0,h[4*(p*d+n)]/255*b];u.push([-1,0,h[4*(p*d+s)]/255*b]);u.push([-1,-1,h[4*(m*d+s)]/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*(p*d+r)]/255*b]);u.push([1,1,h[4*(q*d+r)]/255*b]);u.push([0,1,h[4*(q*d+n)]/255*
-b]);u.push([-1,1,h[4*(q*d+s)]/255*b]);m=[];s=u.length;for(q=0;q<s;q++){var r=u[q],v=u[(q+1)%s],r=[r[0]-x[0],r[1]-x[1],r[2]-x[2]],v=[v[0]-x[0],v[1]-x[1],v[2]-x[2]];m.push(c([r[1]*v[2]-r[2]*v[1],r[2]*v[0]-r[0]*v[2],r[0]*v[1]-r[1]*v[0]]))}u=[0,0,0];for(q=0;q<m.length;q++)u[0]+=m[q][0],u[1]+=m[q][1],u[2]+=m[q][2];u[0]/=m.length;u[1]/=m.length;u[2]/=m.length;x=4*(p*d+n);l[x]=(u[0]+1)/2*255|0;l[x+1]=(u[1]+1)/2*255|0;l[x+2]=255*u[2]|0;l[x+3]=255}f.putImageData(k,0,0);return g},generateDataTexture:function(a,
+g.width=d;g.height=e;var f=g.getContext("2d");f.drawImage(a,0,0);for(var h=f.getImageData(0,0,d,e).data,k=f.createImageData(d,e),l=k.data,n=0;n<d;n++)for(var p=0;p<e;p++){var m=0>p-1?0:p-1,q=p+1>e-1?e-1:p+1,t=0>n-1?0:n-1,r=n+1>d-1?d-1:n+1,v=[],w=[0,0,h[4*(p*d+n)]/255*b];v.push([-1,0,h[4*(p*d+t)]/255*b]);v.push([-1,-1,h[4*(m*d+t)]/255*b]);v.push([0,-1,h[4*(m*d+n)]/255*b]);v.push([1,-1,h[4*(m*d+r)]/255*b]);v.push([1,0,h[4*(p*d+r)]/255*b]);v.push([1,1,h[4*(q*d+r)]/255*b]);v.push([0,1,h[4*(q*d+n)]/255*
+b]);v.push([-1,1,h[4*(q*d+t)]/255*b]);m=[];t=v.length;for(q=0;q<t;q++){var r=v[q],u=v[(q+1)%t],r=[r[0]-w[0],r[1]-w[1],r[2]-w[2]],u=[u[0]-w[0],u[1]-w[1],u[2]-w[2]];m.push(c([r[1]*u[2]-r[2]*u[1],r[2]*u[0]-r[0]*u[2],r[0]*u[1]-r[1]*u[0]]))}v=[0,0,0];for(q=0;q<m.length;q++)v[0]+=m[q][0],v[1]+=m[q][1],v[2]+=m[q][2];v[0]/=m.length;v[1]/=m.length;v[2]/=m.length;w=4*(p*d+n);l[w]=(v[0]+1)/2*255|0;l[w+1]=(v[1]+1)/2*255|0;l[w+2]=255*v[2]|0;l[w+3]=255}f.putImageData(k,0,0);return g},generateDataTexture:function(a,
 b,c){var d=a*b,e=new Uint8Array(3*d),g=Math.floor(255*c.r),f=Math.floor(255*c.g);c=Math.floor(255*c.b);for(var h=0;h<d;h++)e[3*h]=g,e[3*h+1]=f,e[3*h+2]=c;a=new THREE.DataTexture(e,a,b,THREE.RGBFormat);a.needsUpdate=!0;return a}};
 THREE.SceneUtils={createMultiMaterialObject:function(a,b){for(var c=new THREE.Object3D,d=0,e=b.length;d<e;d++)c.add(new THREE.Mesh(a,b[d]));return c},detach:function(a,b,c){a.applyMatrix(b.matrixWorld);b.remove(a);c.add(a)},attach:function(a,b,c){var d=new THREE.Matrix4;d.getInverse(c.matrixWorld);a.applyMatrix(d);b.remove(a);c.add(a)}};
 THREE.FontUtils={faces:{},face:"helvetiker",weight:"normal",style:"normal",size:150,divisions:10,getFace:function(){try{return this.faces[this.face.toLowerCase()][this.weight][this.style]}catch(a){throw"The font "+this.face+" with "+this.weight+" weight and "+this.style+" style is missing.";}},loadFace:function(a){var b=a.familyName.toLowerCase();this.faces[b]=this.faces[b]||{};this.faces[b][a.cssFontWeight]=this.faces[b][a.cssFontWeight]||{};this.faces[b][a.cssFontWeight][a.cssFontStyle]=a;return this.faces[b][a.cssFontWeight][a.cssFontStyle]=
-a},drawText:function(a){var b=this.getFace(),c=this.size/b.resolution,d=0,e=String(a).split(""),g=e.length,f=[];for(a=0;a<g;a++){var h=new THREE.Path,h=this.extractGlyphPoints(e[a],b,c,d,h),d=d+h.offset;f.push(h.path)}return{paths:f,offset:d/2}},extractGlyphPoints:function(a,b,c,d,e){var g=[],f,h,k,l,n,p,m,q,s,r,u,x=b.glyphs[a]||b.glyphs["?"];if(x){if(x.o)for(b=x._cachedOutline||(x._cachedOutline=x.o.split(" ")),l=b.length,a=0;a<l;)switch(k=b[a++],k){case "m":k=b[a++]*c+d;n=b[a++]*c;e.moveTo(k,n);
-break;case "l":k=b[a++]*c+d;n=b[a++]*c;e.lineTo(k,n);break;case "q":k=b[a++]*c+d;n=b[a++]*c;q=b[a++]*c+d;s=b[a++]*c;e.quadraticCurveTo(q,s,k,n);if(f=g[g.length-1])for(p=f.x,m=f.y,f=1,h=this.divisions;f<=h;f++){var v=f/h;THREE.Shape.Utils.b2(v,p,q,k);THREE.Shape.Utils.b2(v,m,s,n)}break;case "b":if(k=b[a++]*c+d,n=b[a++]*c,q=b[a++]*c+d,s=b[a++]*c,r=b[a++]*c+d,u=b[a++]*c,e.bezierCurveTo(q,s,r,u,k,n),f=g[g.length-1])for(p=f.x,m=f.y,f=1,h=this.divisions;f<=h;f++)v=f/h,THREE.Shape.Utils.b3(v,p,q,r,k),THREE.Shape.Utils.b3(v,
-m,s,u,n)}return{offset:x.ha*c,path:e}}}};
+a},drawText:function(a){var b=this.getFace(),c=this.size/b.resolution,d=0,e=String(a).split(""),g=e.length,f=[];for(a=0;a<g;a++){var h=new THREE.Path,h=this.extractGlyphPoints(e[a],b,c,d,h),d=d+h.offset;f.push(h.path)}return{paths:f,offset:d/2}},extractGlyphPoints:function(a,b,c,d,e){var g=[],f,h,k,l,n,p,m,q,t,r,v,w=b.glyphs[a]||b.glyphs["?"];if(w){if(w.o)for(b=w._cachedOutline||(w._cachedOutline=w.o.split(" ")),l=b.length,a=0;a<l;)switch(k=b[a++],k){case "m":k=b[a++]*c+d;n=b[a++]*c;e.moveTo(k,n);
+break;case "l":k=b[a++]*c+d;n=b[a++]*c;e.lineTo(k,n);break;case "q":k=b[a++]*c+d;n=b[a++]*c;q=b[a++]*c+d;t=b[a++]*c;e.quadraticCurveTo(q,t,k,n);if(f=g[g.length-1])for(p=f.x,m=f.y,f=1,h=this.divisions;f<=h;f++){var u=f/h;THREE.Shape.Utils.b2(u,p,q,k);THREE.Shape.Utils.b2(u,m,t,n)}break;case "b":if(k=b[a++]*c+d,n=b[a++]*c,q=b[a++]*c+d,t=b[a++]*c,r=b[a++]*c+d,v=b[a++]*c,e.bezierCurveTo(q,t,r,v,k,n),f=g[g.length-1])for(p=f.x,m=f.y,f=1,h=this.divisions;f<=h;f++)u=f/h,THREE.Shape.Utils.b3(u,p,q,r,k),THREE.Shape.Utils.b3(u,
+m,t,v,n)}return{offset:w.ha*c,path:e}}}};
 THREE.FontUtils.generateShapes=function(a,b){b=b||{};var c=void 0!==b.curveSegments?b.curveSegments:4,d=void 0!==b.font?b.font:"helvetiker",e=void 0!==b.weight?b.weight:"normal",g=void 0!==b.style?b.style:"normal";THREE.FontUtils.size=void 0!==b.size?b.size:100;THREE.FontUtils.divisions=c;THREE.FontUtils.face=d;THREE.FontUtils.weight=e;THREE.FontUtils.style=g;c=THREE.FontUtils.drawText(a).paths;d=[];e=0;for(g=c.length;e<g;e++)Array.prototype.push.apply(d,c[e].toShapes());return d};
-(function(a){var b=function(a){for(var b=a.length,e=0,g=b-1,f=0;f<b;g=f++)e+=a[g].x*a[f].y-a[f].x*a[g].y;return.5*e};a.Triangulate=function(a,d){var e=a.length;if(3>e)return null;var g=[],f=[],h=[],k,l,n;if(0<b(a))for(l=0;l<e;l++)f[l]=l;else for(l=0;l<e;l++)f[l]=e-1-l;var p=2*e;for(l=e-1;2<e;){if(0>=p--){console.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);n=l+1;e<=n&&(n=0);var m;a:{var q=m=void 0,s=void 0,r=void 0,
-u=void 0,x=void 0,v=void 0,y=void 0,w=void 0,q=a[f[k]].x,s=a[f[k]].y,r=a[f[l]].x,u=a[f[l]].y,x=a[f[n]].x,v=a[f[n]].y;if(1E-10>(r-q)*(v-s)-(u-s)*(x-q))m=!1;else{var G=void 0,B=void 0,z=void 0,A=void 0,O=void 0,K=void 0,D=void 0,P=void 0,J=void 0,H=void 0,J=P=D=w=y=void 0,G=x-r,B=v-u,z=q-x,A=s-v,O=r-q,K=u-s;for(m=0;m<e;m++)if(y=a[f[m]].x,w=a[f[m]].y,!(y===q&&w===s||y===r&&w===u||y===x&&w===v)&&(D=y-q,P=w-s,J=y-r,H=w-u,y-=x,w-=v,J=G*H-B*J,D=O*P-K*D,P=z*w-A*y,-1E-10<=J&&-1E-10<=P&&-1E-10<=D)){m=!1;break a}m=
+(function(a){var b=function(a){for(var b=a.length,e=0,g=b-1,f=0;f<b;g=f++)e+=a[g].x*a[f].y-a[f].x*a[g].y;return.5*e};a.Triangulate=function(a,d){var e=a.length;if(3>e)return null;var g=[],f=[],h=[],k,l,n;if(0<b(a))for(l=0;l<e;l++)f[l]=l;else for(l=0;l<e;l++)f[l]=e-1-l;var p=2*e;for(l=e-1;2<e;){if(0>=p--){console.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);n=l+1;e<=n&&(n=0);var m;a:{var q=m=void 0,t=void 0,r=void 0,
+v=void 0,w=void 0,u=void 0,z=void 0,x=void 0,q=a[f[k]].x,t=a[f[k]].y,r=a[f[l]].x,v=a[f[l]].y,w=a[f[n]].x,u=a[f[n]].y;if(1E-10>(r-q)*(u-t)-(v-t)*(w-q))m=!1;else{var D=void 0,F=void 0,y=void 0,B=void 0,L=void 0,N=void 0,C=void 0,O=void 0,G=void 0,J=void 0,G=O=C=x=z=void 0,D=w-r,F=u-v,y=q-w,B=t-u,L=r-q,N=v-t;for(m=0;m<e;m++)if(z=a[f[m]].x,x=a[f[m]].y,!(z===q&&x===t||z===r&&x===v||z===w&&x===u)&&(C=z-q,O=x-t,G=z-r,J=x-v,z-=w,x-=u,G=D*J-F*G,C=L*O-N*C,O=y*x-B*z,-1E-10<=G&&-1E-10<=O&&-1E-10<=C)){m=!1;break a}m=
 !0}}if(m){g.push([a[f[k]],a[f[l]],a[f[n]]]);h.push([f[k],f[l],f[n]]);k=l;for(n=l+1;n<e;k++,n++)f[k]=f[n];e--;p=2*e}}return d?h:g};a.Triangulate.area=b;return a})(THREE.FontUtils);THREE.typeface_js={faces:THREE.FontUtils.faces,loadFace:THREE.FontUtils.loadFace};"undefined"!==typeof self&&(self._typeface_js=THREE.typeface_js);
 THREE.Audio=function(a){THREE.Object3D.call(this);this.type="Audio";this.context=a.context;this.source=this.context.createBufferSource();this.source.onended=this.onEnded.bind(this);this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.panner=this.context.createPanner();this.panner.connect(this.gain);this.autoplay=!1;this.startTime=0;this.playbackRate=1;this.isPlaying=!1};THREE.Audio.prototype=Object.create(THREE.Object3D.prototype);
 THREE.Audio.prototype.constructor=THREE.Audio;THREE.Audio.prototype.load=function(a){var b=this,c=new XMLHttpRequest;c.open("GET",a,!0);c.responseType="arraybuffer";c.onload=function(a){b.context.decodeAudioData(this.response,function(a){b.source.buffer=a;b.autoplay&&b.play()})};c.send();return this};
@@ -685,21 +683,21 @@ THREE.Path.prototype.bezierCurveTo=function(a,b,c,d,e,g){var f=Array.prototype.s
 THREE.Path.prototype.splineThru=function(a){var b=Array.prototype.slice.call(arguments),c=this.actions[this.actions.length-1].args,c=[new THREE.Vector2(c[c.length-2],c[c.length-1])];Array.prototype.push.apply(c,a);c=new THREE.SplineCurve(c);this.curves.push(c);this.actions.push({action:THREE.PathActions.CSPLINE_THRU,args:b})};THREE.Path.prototype.arc=function(a,b,c,d,e,g){var f=this.actions[this.actions.length-1].args;this.absarc(a+f[f.length-2],b+f[f.length-1],c,d,e,g)};
 THREE.Path.prototype.absarc=function(a,b,c,d,e,g){this.absellipse(a,b,c,c,d,e,g)};THREE.Path.prototype.ellipse=function(a,b,c,d,e,g,f,h){var k=this.actions[this.actions.length-1].args;this.absellipse(a+k[k.length-2],b+k[k.length-1],c,d,e,g,f,h)};THREE.Path.prototype.absellipse=function(a,b,c,d,e,g,f,h){var k=[a,b,c,d,e,g,f,h||0];a=new THREE.EllipseCurve(a,b,c,d,e,g,f,h);this.curves.push(a);a=a.getPoint(1);k.push(a.x);k.push(a.y);this.actions.push({action:THREE.PathActions.ELLIPSE,args:k})};
 THREE.Path.prototype.getSpacedPoints=function(a,b){a||(a=40);for(var c=[],d=0;d<a;d++)c.push(this.getPoint(d/a));return c};
-THREE.Path.prototype.getPoints=function(a,b){if(this.useSpacedPoints)return this.getSpacedPoints(a,b);a=a||12;var c=[],d,e,g,f,h,k,l,n,p,m,q,s,r;d=0;for(e=this.actions.length;d<e;d++)switch(g=this.actions[d],f=g.action,g=g.args,f){case THREE.PathActions.MOVE_TO:c.push(new THREE.Vector2(g[0],g[1]));break;case THREE.PathActions.LINE_TO:c.push(new THREE.Vector2(g[0],g[1]));break;case THREE.PathActions.QUADRATIC_CURVE_TO:h=g[2];k=g[3];p=g[0];m=g[1];0<c.length?(f=c[c.length-1],q=f.x,s=f.y):(f=this.actions[d-
-1].args,q=f[f.length-2],s=f[f.length-1]);for(g=1;g<=a;g++)r=g/a,f=THREE.Shape.Utils.b2(r,q,p,h),r=THREE.Shape.Utils.b2(r,s,m,k),c.push(new THREE.Vector2(f,r));break;case THREE.PathActions.BEZIER_CURVE_TO:h=g[4];k=g[5];p=g[0];m=g[1];l=g[2];n=g[3];0<c.length?(f=c[c.length-1],q=f.x,s=f.y):(f=this.actions[d-1].args,q=f[f.length-2],s=f[f.length-1]);for(g=1;g<=a;g++)r=g/a,f=THREE.Shape.Utils.b3(r,q,p,l,h),r=THREE.Shape.Utils.b3(r,s,m,n,k),c.push(new THREE.Vector2(f,r));break;case THREE.PathActions.CSPLINE_THRU:f=
-this.actions[d-1].args;r=[new THREE.Vector2(f[f.length-2],f[f.length-1])];f=a*g[0].length;r=r.concat(g[0]);r=new THREE.SplineCurve(r);for(g=1;g<=f;g++)c.push(r.getPointAt(g/f));break;case THREE.PathActions.ARC:h=g[0];k=g[1];m=g[2];l=g[3];f=g[4];p=!!g[5];q=f-l;s=2*a;for(g=1;g<=s;g++)r=g/s,p||(r=1-r),r=l+r*q,f=h+m*Math.cos(r),r=k+m*Math.sin(r),c.push(new THREE.Vector2(f,r));break;case THREE.PathActions.ELLIPSE:h=g[0];k=g[1];m=g[2];n=g[3];l=g[4];f=g[5];p=!!g[6];var u=g[7];q=f-l;s=2*a;var x,v;0!==u&&
-(x=Math.cos(u),v=Math.sin(u));for(g=1;g<=s;g++){r=g/s;p||(r=1-r);r=l+r*q;f=h+m*Math.cos(r);r=k+n*Math.sin(r);if(0!==u){var y=f;f=(y-h)*x-(r-k)*v+h;r=(y-h)*v+(r-k)*x+k}c.push(new THREE.Vector2(f,r))}}d=c[c.length-1];1E-10>Math.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 this.getSpacedPoints(a,b);a=a||12;var c=[],d,e,g,f,h,k,l,n,p,m,q,t,r;d=0;for(e=this.actions.length;d<e;d++)switch(g=this.actions[d],f=g.action,g=g.args,f){case THREE.PathActions.MOVE_TO:c.push(new THREE.Vector2(g[0],g[1]));break;case THREE.PathActions.LINE_TO:c.push(new THREE.Vector2(g[0],g[1]));break;case THREE.PathActions.QUADRATIC_CURVE_TO:h=g[2];k=g[3];p=g[0];m=g[1];0<c.length?(f=c[c.length-1],q=f.x,t=f.y):(f=this.actions[d-
+1].args,q=f[f.length-2],t=f[f.length-1]);for(g=1;g<=a;g++)r=g/a,f=THREE.Shape.Utils.b2(r,q,p,h),r=THREE.Shape.Utils.b2(r,t,m,k),c.push(new THREE.Vector2(f,r));break;case THREE.PathActions.BEZIER_CURVE_TO:h=g[4];k=g[5];p=g[0];m=g[1];l=g[2];n=g[3];0<c.length?(f=c[c.length-1],q=f.x,t=f.y):(f=this.actions[d-1].args,q=f[f.length-2],t=f[f.length-1]);for(g=1;g<=a;g++)r=g/a,f=THREE.Shape.Utils.b3(r,q,p,l,h),r=THREE.Shape.Utils.b3(r,t,m,n,k),c.push(new THREE.Vector2(f,r));break;case THREE.PathActions.CSPLINE_THRU:f=
+this.actions[d-1].args;r=[new THREE.Vector2(f[f.length-2],f[f.length-1])];f=a*g[0].length;r=r.concat(g[0]);r=new THREE.SplineCurve(r);for(g=1;g<=f;g++)c.push(r.getPointAt(g/f));break;case THREE.PathActions.ARC:h=g[0];k=g[1];m=g[2];l=g[3];f=g[4];p=!!g[5];q=f-l;t=2*a;for(g=1;g<=t;g++)r=g/t,p||(r=1-r),r=l+r*q,f=h+m*Math.cos(r),r=k+m*Math.sin(r),c.push(new THREE.Vector2(f,r));break;case THREE.PathActions.ELLIPSE:h=g[0];k=g[1];m=g[2];n=g[3];l=g[4];f=g[5];p=!!g[6];var v=g[7];q=f-l;t=2*a;var w,u;0!==v&&
+(w=Math.cos(v),u=Math.sin(v));for(g=1;g<=t;g++){r=g/t;p||(r=1-r);r=l+r*q;f=h+m*Math.cos(r);r=k+n*Math.sin(r);if(0!==v){var z=f;f=(z-h)*w-(r-k)*u+h;r=(z-h)*u+(r-k)*w+k}c.push(new THREE.Vector2(f,r))}}d=c[c.length-1];1E-10>Math.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;c<d;c++){var e=a[c],f=new THREE.Shape;f.actions=e.actions;f.curves=e.curves;b.push(f)}return b}function d(a,b){for(var c=b.length,d=!1,e=c-1,f=0;f<c;e=f++){var g=b[e],h=b[f],k=h.x-g.x,l=h.y-g.y;if(1E-10<Math.abs(l)){if(0>l&&(g=b[f],k=-k,h=b[e],l=-l),!(a.y<g.y||a.y>h.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;b<c;b++)d=a[b],e=d.args,d=d.action,d===THREE.PathActions.MOVE_TO&&0!==g.actions.length&&(f.push(g),g=new THREE.Path),g[d].apply(g,e);0!==g.actions.length&&f.push(g);return f}(this.actions);if(0===e.length)return[];if(!0===b)return c(e);var g,f,h,k=[];if(1===e.length)return f=e[0],h=new THREE.Shape,h.actions=f.actions,h.curves=f.curves,k.push(h),k;var l=!THREE.Shape.Utils.isClockWise(e[0].getPoints()),
-l=a?!l:l;h=[];var n=[],p=[],m=0,q;n[m]=void 0;p[m]=[];var s,r;s=0;for(r=e.length;s<r;s++)f=e[s],q=f.getPoints(),g=THREE.Shape.Utils.isClockWise(q),(g=a?!g:g)?(!l&&n[m]&&m++,n[m]={s:new THREE.Shape,p:q},n[m].s.actions=f.actions,n[m].s.curves=f.curves,l&&m++,p[m]=[]):p[m].push({h:f,p:q[0]});if(!n[0])return c(e);if(1<n.length){s=!1;r=[];f=0;for(e=n.length;f<e;f++)h[f]=[];f=0;for(e=n.length;f<e;f++)for(g=p[f],l=0;l<g.length;l++){m=g[l];q=!0;for(var u=0;u<n.length;u++)d(m.p,n[u].p)&&(f!==u&&r.push({froms:f,
-tos:u,hole:l}),q?(q=!1,h[u].push(m)):s=!0);q&&h[f].push(m)}0<r.length&&(s||(p=h))}s=0;for(r=n.length;s<r;s++)for(h=n[s].s,k.push(h),f=p[s],e=0,g=f.length;e<g;e++)h.holes.push(f[e].h);return k};THREE.Shape=function(){THREE.Path.apply(this,arguments);this.holes=[]};THREE.Shape.prototype=Object.create(THREE.Path.prototype);THREE.Shape.prototype.constructor=THREE.Shape;THREE.Shape.prototype.extrude=function(a){return new THREE.ExtrudeGeometry(this,a)};
+l=a?!l:l;h=[];var n=[],p=[],m=0,q;n[m]=void 0;p[m]=[];var t,r;t=0;for(r=e.length;t<r;t++)f=e[t],q=f.getPoints(),g=THREE.Shape.Utils.isClockWise(q),(g=a?!g:g)?(!l&&n[m]&&m++,n[m]={s:new THREE.Shape,p:q},n[m].s.actions=f.actions,n[m].s.curves=f.curves,l&&m++,p[m]=[]):p[m].push({h:f,p:q[0]});if(!n[0])return c(e);if(1<n.length){t=!1;r=[];f=0;for(e=n.length;f<e;f++)h[f]=[];f=0;for(e=n.length;f<e;f++)for(g=p[f],l=0;l<g.length;l++){m=g[l];q=!0;for(var v=0;v<n.length;v++)d(m.p,n[v].p)&&(f!==v&&r.push({froms:f,
+tos:v,hole:l}),q?(q=!1,h[v].push(m)):t=!0);q&&h[f].push(m)}0<r.length&&(t||(p=h))}t=0;for(r=n.length;t<r;t++)for(h=n[t].s,k.push(h),f=p[t],e=0,g=f.length;e<g;e++)h.holes.push(f[e].h);return k};THREE.Shape=function(){THREE.Path.apply(this,arguments);this.holes=[]};THREE.Shape.prototype=Object.create(THREE.Path.prototype);THREE.Shape.prototype.constructor=THREE.Shape;THREE.Shape.prototype.extrude=function(a){return new THREE.ExtrudeGeometry(this,a)};
 THREE.Shape.prototype.makeGeometry=function(a){return new THREE.ShapeGeometry(this,a)};THREE.Shape.prototype.getPointsHoles=function(a){var b,c=this.holes.length,d=[];for(b=0;b<c;b++)d[b]=this.holes[b].getTransformedPoints(a,this.bends);return d};THREE.Shape.prototype.getSpacedPointsHoles=function(a){var b,c=this.holes.length,d=[];for(b=0;b<c;b++)d[b]=this.holes[b].getTransformedSpacedPoints(a,this.bends);return d};
 THREE.Shape.prototype.extractAllPoints=function(a){return{shape:this.getTransformedPoints(a),holes:this.getPointsHoles(a)}};THREE.Shape.prototype.extractPoints=function(a){return this.useSpacedPoints?this.extractAllSpacedPoints(a):this.extractAllPoints(a)};THREE.Shape.prototype.extractAllSpacedPoints=function(a){return{shape:this.getTransformedSpacedPoints(a),holes:this.getSpacedPointsHoles(a)}};
-THREE.Shape.Utils={triangulateShape:function(a,b){function c(a,b,c){return a.x!==b.x?a.x<b.x?a.x<=c.x&&c.x<=b.x:b.x<=c.x&&c.x<=a.x:a.y<b.y?a.y<=c.y&&c.y<=b.y:b.y<=c.y&&c.y<=a.y}function d(a,b,d,e,f){var g=b.x-a.x,h=b.y-a.y,k=e.x-d.x,l=e.y-d.y,n=a.x-d.x,p=a.y-d.y,z=h*k-g*l,A=h*n-g*p;if(1E-10<Math.abs(z)){if(0<z){if(0>A||A>z)return[];k=l*n-k*p;if(0>k||k>z)return[]}else{if(0<A||A<z)return[];k=l*n-k*p;if(0<k||k<z)return[]}if(0===k)return!f||0!==A&&A!==z?[a]:[];if(k===z)return!f||0!==A&&A!==z?[b]:[];if(0===
-A)return[d];if(A===z)return[e];f=k/z;return[{x:a.x+f*g,y:a.y+f*h}]}if(0!==A||l*n!==k*p)return[];h=0===g&&0===h;k=0===k&&0===l;if(h&&k)return a.x!==d.x||a.y!==d.y?[]:[a];if(h)return c(d,e,a)?[a]:[];if(k)return c(a,b,d)?[d]:[];0!==g?(a.x<b.x?(g=a,k=a.x,h=b,a=b.x):(g=b,k=b.x,h=a,a=a.x),d.x<e.x?(b=d,z=d.x,l=e,d=e.x):(b=e,z=e.x,l=d,d=d.x)):(a.y<b.y?(g=a,k=a.y,h=b,a=b.y):(g=b,k=b.y,h=a,a=a.y),d.y<e.y?(b=d,z=d.y,l=e,d=e.y):(b=e,z=e.y,l=d,d=d.y));return k<=z?a<z?[]:a===z?f?[]:[b]:a<=d?[b,h]:[b,l]:k>d?[]:
+THREE.Shape.Utils={triangulateShape:function(a,b){function c(a,b,c){return a.x!==b.x?a.x<b.x?a.x<=c.x&&c.x<=b.x:b.x<=c.x&&c.x<=a.x:a.y<b.y?a.y<=c.y&&c.y<=b.y:b.y<=c.y&&c.y<=a.y}function d(a,b,d,e,f){var g=b.x-a.x,h=b.y-a.y,k=e.x-d.x,l=e.y-d.y,n=a.x-d.x,p=a.y-d.y,y=h*k-g*l,B=h*n-g*p;if(1E-10<Math.abs(y)){if(0<y){if(0>B||B>y)return[];k=l*n-k*p;if(0>k||k>y)return[]}else{if(0<B||B<y)return[];k=l*n-k*p;if(0<k||k<y)return[]}if(0===k)return!f||0!==B&&B!==y?[a]:[];if(k===y)return!f||0!==B&&B!==y?[b]:[];if(0===
+B)return[d];if(B===y)return[e];f=k/y;return[{x:a.x+f*g,y:a.y+f*h}]}if(0!==B||l*n!==k*p)return[];h=0===g&&0===h;k=0===k&&0===l;if(h&&k)return a.x!==d.x||a.y!==d.y?[]:[a];if(h)return c(d,e,a)?[a]:[];if(k)return c(a,b,d)?[d]:[];0!==g?(a.x<b.x?(g=a,k=a.x,h=b,a=b.x):(g=b,k=b.x,h=a,a=a.x),d.x<e.x?(b=d,y=d.x,l=e,d=e.x):(b=e,y=e.x,l=d,d=d.x)):(a.y<b.y?(g=a,k=a.y,h=b,a=b.y):(g=b,k=b.y,h=a,a=a.y),d.y<e.y?(b=d,y=d.y,l=e,d=e.y):(b=e,y=e.y,l=d,d=d.y));return k<=y?a<y?[]:a===y?f?[]:[b]:a<=d?[b,h]:[b,l]:k>d?[]:
 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-10<Math.abs(a)?(b=g*c-d*b,0<a?0<=e&&0<=b:0<=e||0<=b):0<e}var g,f,h,k,l,n={};h=a.concat();g=0;for(f=b.length;g<f;g++)Array.prototype.push.apply(h,b[g]);g=0;for(f=h.length;g<f;g++)l=h[g].x+":"+h[g].y,void 0!==n[l]&&console.warn("THREE.Shape: Duplicate point",l),n[l]=g;g=function(a,b){function c(a,b){var d=h.length-1,f=a-1;0>f&&(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.length;c++)if(e=c+1,e%=h.length,e=d(a,b,h[c],h[e],!0),0<e.length)return!0;return!1}function g(a,c){var e,f,h,k;for(e=0;e<l.length;e++)for(f=b[l[e]],h=0;h<f.length;h++)if(k=h+1,k%=f.length,k=d(a,c,f[h],f[k],!0),0<k.length)return!0;return!1}var h=a.concat(),k,l=[],n,p,B,z,A,O=[],K,D,P,J=0;for(n=b.length;J<n;J++)l.push(J);K=0;for(var H=2*
-l.length;0<l.length;){H--;if(0>H){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(p=K;p<h.length;p++){B=h[p];n=-1;for(J=0;J<l.length;J++)if(z=l[J],A=B.x+":"+B.y+":"+z,void 0===O[A]){k=b[z];for(D=0;D<k.length;D++)if(z=k[D],c(p,D)&&!f(B,z)&&!g(B,z)){n=D;l.splice(J,1);K=h.slice(0,p+1);z=h.slice(p);D=k.slice(n);P=k.slice(0,n+1);h=K.concat(D).concat(P).concat(z);K=p;break}if(0<=n)break;O[A]=!0}if(0<=n)break}}return h}(a,b);var p=THREE.FontUtils.Triangulate(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.length;c++)if(e=c+1,e%=h.length,e=d(a,b,h[c],h[e],!0),0<e.length)return!0;return!1}function g(a,c){var e,f,h,k;for(e=0;e<l.length;e++)for(f=b[l[e]],h=0;h<f.length;h++)if(k=h+1,k%=f.length,k=d(a,c,f[h],f[k],!0),0<k.length)return!0;return!1}var h=a.concat(),k,l=[],n,p,F,y,B,L=[],N,C,O,G=0;for(n=b.length;G<n;G++)l.push(G);N=0;for(var J=2*
+l.length;0<l.length;){J--;if(0>J){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(p=N;p<h.length;p++){F=h[p];n=-1;for(G=0;G<l.length;G++)if(y=l[G],B=F.x+":"+F.y+":"+y,void 0===L[B]){k=b[y];for(C=0;C<k.length;C++)if(y=k[C],c(p,C)&&!f(F,y)&&!g(F,y)){n=C;l.splice(G,1);N=h.slice(0,p+1);y=h.slice(p);C=k.slice(n);O=k.slice(0,n+1);h=N.concat(C).concat(O).concat(y);N=p;break}if(0<=n)break;L[B]=!0}if(0<=n)break}}return h}(a,b);var p=THREE.FontUtils.Triangulate(g,
 !1);g=0;for(f=p.length;g<f;g++)for(k=p[g],h=0;3>h;h++)l=k[h].x+":"+k[h].y,l=n[l],void 0!==l&&(k[h]=l);return p.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;
@@ -725,12 +723,12 @@ THREE.AnimationHandler={LINEAR:0,CATMULLROM:1,CATMULLROM_FORWARD:2,add:function(
 for(b=0;b<this.animations.length;b++)this.animations[b].update(a)}};THREE.Animation=function(a,b){this.root=a;this.data=THREE.AnimationHandler.init(b);this.hierarchy=THREE.AnimationHandler.parse(a);this.currentTime=0;this.timeScale=1;this.isPlaying=!1;this.loop=!0;this.weight=0;this.interpolationType=THREE.AnimationHandler.LINEAR};
 THREE.Animation.prototype={constructor:THREE.Animation,keyTypes:["pos","rot","scl"],play:function(a,b){this.currentTime=void 0!==a?a:0;this.weight=void 0!==b?b:1;this.isPlaying=!0;this.reset();THREE.AnimationHandler.play(this)},stop:function(){this.isPlaying=!1;THREE.AnimationHandler.stop(this)},reset:function(){for(var a=0,b=this.hierarchy.length;a<b;a++){var c=this.hierarchy[a];void 0===c.animationCache&&(c.animationCache={animations:{},blending:{positionWeight:0,quaternionWeight:0,scaleWeight:0}});
 var d=this.data.name,e=c.animationCache.animations,g=e[d];void 0===g&&(g={prevKey:{pos:0,rot:0,scl:0},nextKey:{pos:0,rot:0,scl:0},originalMatrix:c.matrix},e[d]=g);for(c=0;3>c;c++){for(var d=this.keyTypes[c],e=this.data.hierarchy[a].keys[0],f=this.getNextKeyWith(d,a,1);f.time<this.currentTime&&f.index>e.index;)e=f,f=this.getNextKeyWith(d,a,f.index+1);g.prevKey[d]=e;g.nextKey[d]=f}}},resetBlendWeights:function(){for(var a=0,b=this.hierarchy.length;a<b;a++){var c=this.hierarchy[a].animationCache;void 0!==
-c&&(c=c.blending,c.positionWeight=0,c.quaternionWeight=0,c.scaleWeight=0)}},update:function(){var a=[],b=new THREE.Vector3,c=new THREE.Vector3,d=new THREE.Quaternion,e=function(a,b){var c=[],d=[],e,p,m,q,s,r;e=(a.length-1)*b;p=Math.floor(e);e-=p;c[0]=0===p?p:p-1;c[1]=p;c[2]=p>a.length-2?p:p+1;c[3]=p>a.length-3?p:p+2;p=a[c[0]];q=a[c[1]];s=a[c[2]];r=a[c[3]];c=e*e;m=e*c;d[0]=g(p[0],q[0],s[0],r[0],e,c,m);d[1]=g(p[1],q[1],s[1],r[1],e,c,m);d[2]=g(p[2],q[2],s[2],r[2],e,c,m);return d},g=function(a,b,c,d,
+c&&(c=c.blending,c.positionWeight=0,c.quaternionWeight=0,c.scaleWeight=0)}},update:function(){var a=[],b=new THREE.Vector3,c=new THREE.Vector3,d=new THREE.Quaternion,e=function(a,b){var c=[],d=[],e,p,m,q,t,r;e=(a.length-1)*b;p=Math.floor(e);e-=p;c[0]=0===p?p:p-1;c[1]=p;c[2]=p>a.length-2?p:p+1;c[3]=p>a.length-3?p:p+2;p=a[c[0]];q=a[c[1]];t=a[c[2]];r=a[c[3]];c=e*e;m=e*c;d[0]=g(p[0],q[0],t[0],r[0],e,c,m);d[1]=g(p[1],q[1],t[1],r[1],e,c,m);d[2]=g(p[2],q[2],t[2],r[2],e,c,m);return d},g=function(a,b,c,d,
 e,g,m){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*m+(-3*(b-c)-2*a-d)*g+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 g=this.hierarchy.length;f<g;f++)for(var k=this.hierarchy[f],l=k.animationCache.animations[this.data.name],n=k.animationCache.blending,p=0;3>p;p++){var m=this.keyTypes[p],
-q=l.prevKey[m],s=l.nextKey[m];if(0<this.timeScale&&s.time<=this.currentTime||0>this.timeScale&&q.time>=this.currentTime){q=this.data.hierarchy[f].keys[0];for(s=this.getNextKeyWith(m,f,1);s.time<this.currentTime&&s.index>q.index;)q=s,s=this.getNextKeyWith(m,f,s.index+1);l.prevKey[m]=q;l.nextKey[m]=s}var r=(this.currentTime-q.time)/(s.time-q.time),u=q[m],x=s[m];0>r&&(r=0);1<r&&(r=1);if("pos"===m)if(this.interpolationType===THREE.AnimationHandler.LINEAR)c.x=u[0]+(x[0]-u[0])*r,c.y=u[1]+(x[1]-u[1])*r,
-c.z=u[2]+(x[2]-u[2])*r,q=this.weight/(this.weight+n.positionWeight),k.position.lerp(c,q),n.positionWeight+=this.weight;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)a[0]=this.getPrevKeyWith("pos",f,q.index-1).pos,a[1]=u,a[2]=x,a[3]=this.getNextKeyWith("pos",f,s.index+1).pos,r=.33*r+.33,s=e(a,r),q=this.weight/(this.weight+n.positionWeight),n.positionWeight+=this.weight,m=k.position,m.x+=(s[0]-m.x)*q,m.y+=(s[1]-
-m.y)*q,m.z+=(s[2]-m.z)*q,this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD&&(r=e(a,1.01*r),b.set(r[0],r[1],r[2]),b.sub(m),b.y=0,b.normalize(),r=Math.atan2(b.x,b.z),k.rotation.set(0,r,0))}else"rot"===m?(THREE.Quaternion.slerp(u,x,d,r),0===n.quaternionWeight?(k.quaternion.copy(d),n.quaternionWeight=this.weight):(q=this.weight/(this.weight+n.quaternionWeight),THREE.Quaternion.slerp(k.quaternion,d,k.quaternion,q),n.quaternionWeight+=this.weight)):"scl"===m&&(c.x=u[0]+(x[0]-u[0])*r,c.y=
-u[1]+(x[1]-u[1])*r,c.z=u[2]+(x[2]-u[2])*r,q=this.weight/(this.weight+n.scaleWeight),k.scale.lerp(c,q),n.scaleWeight+=this.weight)}return!0}}}(),getNextKeyWith:function(a,b,c){var d=this.data.hierarchy[b].keys;for(c=this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD?c<d.length-1?c:d.length-1:c%d.length;c<d.length;c++)if(void 0!==d[c][a])return d[c];return this.data.hierarchy[b].keys[0]},getPrevKeyWith:function(a,b,c){var d=
+q=l.prevKey[m],t=l.nextKey[m];if(0<this.timeScale&&t.time<=this.currentTime||0>this.timeScale&&q.time>=this.currentTime){q=this.data.hierarchy[f].keys[0];for(t=this.getNextKeyWith(m,f,1);t.time<this.currentTime&&t.index>q.index;)q=t,t=this.getNextKeyWith(m,f,t.index+1);l.prevKey[m]=q;l.nextKey[m]=t}var r=(this.currentTime-q.time)/(t.time-q.time),v=q[m],w=t[m];0>r&&(r=0);1<r&&(r=1);if("pos"===m)if(this.interpolationType===THREE.AnimationHandler.LINEAR)c.x=v[0]+(w[0]-v[0])*r,c.y=v[1]+(w[1]-v[1])*r,
+c.z=v[2]+(w[2]-v[2])*r,q=this.weight/(this.weight+n.positionWeight),k.position.lerp(c,q),n.positionWeight+=this.weight;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)a[0]=this.getPrevKeyWith("pos",f,q.index-1).pos,a[1]=v,a[2]=w,a[3]=this.getNextKeyWith("pos",f,t.index+1).pos,r=.33*r+.33,t=e(a,r),q=this.weight/(this.weight+n.positionWeight),n.positionWeight+=this.weight,m=k.position,m.x+=(t[0]-m.x)*q,m.y+=(t[1]-
+m.y)*q,m.z+=(t[2]-m.z)*q,this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD&&(r=e(a,1.01*r),b.set(r[0],r[1],r[2]),b.sub(m),b.y=0,b.normalize(),r=Math.atan2(b.x,b.z),k.rotation.set(0,r,0))}else"rot"===m?(THREE.Quaternion.slerp(v,w,d,r),0===n.quaternionWeight?(k.quaternion.copy(d),n.quaternionWeight=this.weight):(q=this.weight/(this.weight+n.quaternionWeight),THREE.Quaternion.slerp(k.quaternion,d,k.quaternion,q),n.quaternionWeight+=this.weight)):"scl"===m&&(c.x=v[0]+(w[0]-v[0])*r,c.y=
+v[1]+(w[1]-v[1])*r,c.z=v[2]+(w[2]-v[2])*r,q=this.weight/(this.weight+n.scaleWeight),k.scale.lerp(c,q),n.scaleWeight+=this.weight)}return!0}}}(),getNextKeyWith:function(a,b,c){var d=this.data.hierarchy[b].keys;for(c=this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD?c<d.length-1?c:d.length-1:c%d.length;c<d.length;c++)if(void 0!==d[c][a])return d[c];return this.data.hierarchy[b].keys[0]},getPrevKeyWith:function(a,b,c){var d=
 this.data.hierarchy[b].keys;for(c=this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD?0<c?c:0:0<=c?c:c+d.length;0<=c;c--)if(void 0!==d[c][a])return d[c];return this.data.hierarchy[b].keys[d.length-1]}};
 THREE.KeyFrameAnimation=function(a){this.root=a.node;this.data=THREE.AnimationHandler.init(a);this.hierarchy=THREE.AnimationHandler.parse(this.root);this.currentTime=0;this.timeScale=.001;this.isPlaying=!1;this.loop=this.isPaused=!0;a=0;for(var b=this.hierarchy.length;a<b;a++){var c=this.data.hierarchy[a].sids,d=this.hierarchy[a];if(this.data.hierarchy[a].keys.length&&c){for(var e=0;e<c.length;e++){var g=c[e],f=this.getNextKeyWith(g,a,0);f&&f.apply(g)}d.matrixAutoUpdate=!1;this.data.hierarchy[a].node.updateMatrix();
 d.matrixWorldNeedsUpdate=!0}}};
@@ -741,9 +739,9 @@ g.interpolate(f,f.time);this.data.hierarchy[a].node.updateMatrix();c.matrixWorld
 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);var b=this.duration/this.frames;a=Math.floor(this.currentTime/b);var c=this.mesh.morphTargetInfluences;a!==this.currentFrame&&(c[this.lastFrame]=0,c[this.currentFrame]=
 1,c[a]=0,this.lastFrame=this.currentFrame,this.currentFrame=a);b=this.currentTime%b/b;c[a]=b;c[this.lastFrame]=1-b}}};
-THREE.BoxGeometry=function(a,b,c,d,e,g){function f(a,b,c,d,e,f,g,r){var u,x=h.widthSegments,v=h.heightSegments,y=e/2,w=f/2,G=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",v=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",x=h.depthSegments;var B=x+1,z=v+1,A=e/x,O=f/v,K=new THREE.Vector3;K[u]=0<g?1:-1;for(e=0;e<z;e++)for(f=0;f<B;f++){var D=new THREE.Vector3;D[a]=(f*A-y)*c;D[b]=(e*O-w)*d;D[u]=g;h.vertices.push(D)}for(e=
-0;e<v;e++)for(f=0;f<x;f++)w=f+B*e,a=f+B*(e+1),b=f+1+B*(e+1),c=f+1+B*e,d=new THREE.Vector2(f/x,1-e/v),g=new THREE.Vector2(f/x,1-(e+1)/v),u=new THREE.Vector2((f+1)/x,1-(e+1)/v),y=new THREE.Vector2((f+1)/x,1-e/v),w=new THREE.Face3(w+G,a+G,c+G),w.normal.copy(K),w.vertexNormals.push(K.clone(),K.clone(),K.clone()),w.materialIndex=r,h.faces.push(w),h.faceVertexUvs[0].push([d,g,y]),w=new THREE.Face3(a+G,b+G,c+G),w.normal.copy(K),w.vertexNormals.push(K.clone(),K.clone(),K.clone()),w.materialIndex=r,h.faces.push(w),
-h.faceVertexUvs[0].push([g.clone(),u,y.clone()])}THREE.Geometry.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:g};this.widthSegments=d||1;this.heightSegments=e||1;this.depthSegments=g||1;var h=this;d=a/2;e=b/2;g=c/2;f("z","y",-1,-1,c,b,d,0);f("z","y",1,-1,c,b,-d,1);f("x","z",1,1,a,c,e,2);f("x","z",1,-1,a,c,-e,3);f("x","y",1,-1,a,b,g,4);f("x","y",-1,-1,a,b,-g,5);this.mergeVertices()};THREE.BoxGeometry.prototype=Object.create(THREE.Geometry.prototype);
+THREE.BoxGeometry=function(a,b,c,d,e,g){function f(a,b,c,d,e,f,g,r){var v,w=h.widthSegments,u=h.heightSegments,z=e/2,x=f/2,D=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)v="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)v="y",u=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)v="x",w=h.depthSegments;var F=w+1,y=u+1,B=e/w,L=f/u,N=new THREE.Vector3;N[v]=0<g?1:-1;for(e=0;e<y;e++)for(f=0;f<F;f++){var C=new THREE.Vector3;C[a]=(f*B-z)*c;C[b]=(e*L-x)*d;C[v]=g;h.vertices.push(C)}for(e=
+0;e<u;e++)for(f=0;f<w;f++)x=f+F*e,a=f+F*(e+1),b=f+1+F*(e+1),c=f+1+F*e,d=new THREE.Vector2(f/w,1-e/u),g=new THREE.Vector2(f/w,1-(e+1)/u),v=new THREE.Vector2((f+1)/w,1-(e+1)/u),z=new THREE.Vector2((f+1)/w,1-e/u),x=new THREE.Face3(x+D,a+D,c+D),x.normal.copy(N),x.vertexNormals.push(N.clone(),N.clone(),N.clone()),x.materialIndex=r,h.faces.push(x),h.faceVertexUvs[0].push([d,g,z]),x=new THREE.Face3(a+D,b+D,c+D),x.normal.copy(N),x.vertexNormals.push(N.clone(),N.clone(),N.clone()),x.materialIndex=r,h.faces.push(x),
+h.faceVertexUvs[0].push([g.clone(),v,z.clone()])}THREE.Geometry.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:g};this.widthSegments=d||1;this.heightSegments=e||1;this.depthSegments=g||1;var h=this;d=a/2;e=b/2;g=c/2;f("z","y",-1,-1,c,b,d,0);f("z","y",1,-1,c,b,-d,1);f("x","z",1,1,a,c,e,2);f("x","z",1,-1,a,c,-e,3);f("x","y",1,-1,a,b,g,4);f("x","y",-1,-1,a,b,-g,5);this.mergeVertices()};THREE.BoxGeometry.prototype=Object.create(THREE.Geometry.prototype);
 THREE.BoxGeometry.prototype.constructor=THREE.BoxGeometry;THREE.BoxGeometry.prototype.clone=function(){return new THREE.BoxGeometry(this.parameters.width,this.parameters.height,this.parameters.depth,this.parameters.widthSegments,this.parameters.heightSegments,this.parameters.depthSegments)};THREE.CubeGeometry=THREE.BoxGeometry;
 THREE.CircleGeometry=function(a,b,c,d){THREE.Geometry.call(this);this.type="CircleGeometry";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};a=a||50;b=void 0!==b?Math.max(3,b):8;c=void 0!==c?c:0;d=void 0!==d?d:2*Math.PI;var e,g=[];e=new THREE.Vector3;var f=new THREE.Vector2(.5,.5);this.vertices.push(e);g.push(f);for(e=0;e<=b;e++){var h=new THREE.Vector3,k=c+e/b*d;h.x=a*Math.cos(k);h.y=a*Math.sin(k);this.vertices.push(h);g.push(new THREE.Vector2((h.x/a+1)/2,(h.y/a+1)/2))}c=new THREE.Vector3(0,
 0,1);for(e=1;e<=b;e++)this.faces.push(new THREE.Face3(e,e+1,0,[c.clone(),c.clone(),c.clone()])),this.faceVertexUvs[0].push([g[e].clone(),g[e+1].clone(),f.clone()]);this.computeFaceNormals();this.boundingSphere=new THREE.Sphere(new THREE.Vector3,a)};THREE.CircleGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CircleGeometry.prototype.constructor=THREE.CircleGeometry;
@@ -751,42 +749,40 @@ THREE.CircleGeometry.prototype.clone=function(){return new THREE.CircleGeometry(
 THREE.CircleBufferGeometry=function(a,b,c,d){THREE.BufferGeometry.call(this);this.type="CircleBufferGeometry";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};a=a||50;b=void 0!==b?Math.max(3,b):8;c=void 0!==c?c:0;d=void 0!==d?d:2*Math.PI;var e=b+2,g=new Float32Array(3*e),f=new Float32Array(3*e),e=new Float32Array(2*e);f[3]=1;e[0]=.5;e[1]=.5;for(var h=0,k=3,l=2;h<=b;h++,k+=3,l+=2){var n=c+h/b*d;g[k]=a*Math.cos(n);g[k+1]=a*Math.sin(n);f[k+2]=1;e[l]=(g[k]/a+1)/2;e[l+1]=(g[k+1]/a+1)/2}c=
 [];for(k=1;k<=b;k++)c.push(k),c.push(k+1),c.push(0);this.addIndex(new THREE.BufferAttribute(new Uint16Array(c),1));this.addAttribute("position",new THREE.BufferAttribute(g,3));this.addAttribute("normal",new THREE.BufferAttribute(f,3));this.addAttribute("uv",new THREE.BufferAttribute(e,2));this.boundingSphere=new THREE.Sphere(new THREE.Vector3,a)};THREE.CircleBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.CircleBufferGeometry.prototype.constructor=THREE.CircleBufferGeometry;
 THREE.CircleBufferGeometry.prototype.clone=function(){var a=new THREE.CircleBufferGeometry(this.parameters.radius,this.parameters.segments,this.parameters.thetaStart,this.parameters.thetaLength);a.copy(this);return a};
-THREE.CylinderGeometry=function(a,b,c,d,e,g,f,h){THREE.Geometry.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:g,thetaStart:f,thetaLength:h};a=void 0!==a?a:20;b=void 0!==b?b:20;c=void 0!==c?c:100;d=d||8;e=e||1;g=void 0!==g?g:!1;f=void 0!==f?f:0;h=void 0!==h?h:2*Math.PI;var k=c/2,l,n,p=[],m=[];for(n=0;n<=e;n++){var q=[],s=[],r=n/e,u=r*(b-a)+a;for(l=0;l<=d;l++){var x=l/d,v=new THREE.Vector3;v.x=u*Math.sin(x*h+
-f);v.y=-r*c+k;v.z=u*Math.cos(x*h+f);this.vertices.push(v);q.push(this.vertices.length-1);s.push(new THREE.Vector2(x,1-r))}p.push(q);m.push(s)}c=(b-a)/c;for(l=0;l<d;l++)for(0!==a?(f=this.vertices[p[0][l]].clone(),h=this.vertices[p[0][l+1]].clone()):(f=this.vertices[p[1][l]].clone(),h=this.vertices[p[1][l+1]].clone()),f.setY(Math.sqrt(f.x*f.x+f.z*f.z)*c).normalize(),h.setY(Math.sqrt(h.x*h.x+h.z*h.z)*c).normalize(),n=0;n<e;n++){var q=p[n][l],s=p[n+1][l],r=p[n+1][l+1],u=p[n][l+1],x=f.clone(),v=f.clone(),
-y=h.clone(),w=h.clone(),G=m[n][l].clone(),B=m[n+1][l].clone(),z=m[n+1][l+1].clone(),A=m[n][l+1].clone();this.faces.push(new THREE.Face3(q,s,u,[x,v,w]));this.faceVertexUvs[0].push([G,B,A]);this.faces.push(new THREE.Face3(s,r,u,[v.clone(),y,w.clone()]));this.faceVertexUvs[0].push([B.clone(),z,A.clone()])}if(!1===g&&0<a)for(this.vertices.push(new THREE.Vector3(0,k,0)),l=0;l<d;l++)q=p[0][l],s=p[0][l+1],r=this.vertices.length-1,x=new THREE.Vector3(0,1,0),v=new THREE.Vector3(0,1,0),y=new THREE.Vector3(0,
-1,0),G=m[0][l].clone(),B=m[0][l+1].clone(),z=new THREE.Vector2(B.x,0),this.faces.push(new THREE.Face3(q,s,r,[x,v,y],void 0,1)),this.faceVertexUvs[0].push([G,B,z]);if(!1===g&&0<b)for(this.vertices.push(new THREE.Vector3(0,-k,0)),l=0;l<d;l++)q=p[e][l+1],s=p[e][l],r=this.vertices.length-1,x=new THREE.Vector3(0,-1,0),v=new THREE.Vector3(0,-1,0),y=new THREE.Vector3(0,-1,0),G=m[e][l+1].clone(),B=m[e][l].clone(),z=new THREE.Vector2(B.x,1),this.faces.push(new THREE.Face3(q,s,r,[x,v,y],void 0,2)),this.faceVertexUvs[0].push([G,
-B,z]);this.computeFaceNormals()};THREE.CylinderGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CylinderGeometry.prototype.constructor=THREE.CylinderGeometry;THREE.CylinderGeometry.prototype.clone=function(){return new THREE.CylinderGeometry(this.parameters.radiusTop,this.parameters.radiusBottom,this.parameters.height,this.parameters.radialSegments,this.parameters.heightSegments,this.parameters.openEnded,this.parameters.thetaStart,this.parameters.thetaLength)};
+THREE.CylinderGeometry=function(a,b,c,d,e,g,f,h){THREE.Geometry.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:g,thetaStart:f,thetaLength:h};a=void 0!==a?a:20;b=void 0!==b?b:20;c=void 0!==c?c:100;d=d||8;e=e||1;g=void 0!==g?g:!1;f=void 0!==f?f:0;h=void 0!==h?h:2*Math.PI;var k=c/2,l,n,p=[],m=[];for(n=0;n<=e;n++){var q=[],t=[],r=n/e,v=r*(b-a)+a;for(l=0;l<=d;l++){var w=l/d,u=new THREE.Vector3;u.x=v*Math.sin(w*h+
+f);u.y=-r*c+k;u.z=v*Math.cos(w*h+f);this.vertices.push(u);q.push(this.vertices.length-1);t.push(new THREE.Vector2(w,1-r))}p.push(q);m.push(t)}c=(b-a)/c;for(l=0;l<d;l++)for(0!==a?(f=this.vertices[p[0][l]].clone(),h=this.vertices[p[0][l+1]].clone()):(f=this.vertices[p[1][l]].clone(),h=this.vertices[p[1][l+1]].clone()),f.setY(Math.sqrt(f.x*f.x+f.z*f.z)*c).normalize(),h.setY(Math.sqrt(h.x*h.x+h.z*h.z)*c).normalize(),n=0;n<e;n++){var q=p[n][l],t=p[n+1][l],r=p[n+1][l+1],v=p[n][l+1],w=f.clone(),u=f.clone(),
+z=h.clone(),x=h.clone(),D=m[n][l].clone(),F=m[n+1][l].clone(),y=m[n+1][l+1].clone(),B=m[n][l+1].clone();this.faces.push(new THREE.Face3(q,t,v,[w,u,x]));this.faceVertexUvs[0].push([D,F,B]);this.faces.push(new THREE.Face3(t,r,v,[u.clone(),z,x.clone()]));this.faceVertexUvs[0].push([F.clone(),y,B.clone()])}if(!1===g&&0<a)for(this.vertices.push(new THREE.Vector3(0,k,0)),l=0;l<d;l++)q=p[0][l],t=p[0][l+1],r=this.vertices.length-1,w=new THREE.Vector3(0,1,0),u=new THREE.Vector3(0,1,0),z=new THREE.Vector3(0,
+1,0),D=m[0][l].clone(),F=m[0][l+1].clone(),y=new THREE.Vector2(F.x,0),this.faces.push(new THREE.Face3(q,t,r,[w,u,z],void 0,1)),this.faceVertexUvs[0].push([D,F,y]);if(!1===g&&0<b)for(this.vertices.push(new THREE.Vector3(0,-k,0)),l=0;l<d;l++)q=p[e][l+1],t=p[e][l],r=this.vertices.length-1,w=new THREE.Vector3(0,-1,0),u=new THREE.Vector3(0,-1,0),z=new THREE.Vector3(0,-1,0),D=m[e][l+1].clone(),F=m[e][l].clone(),y=new THREE.Vector2(F.x,1),this.faces.push(new THREE.Face3(q,t,r,[w,u,z],void 0,2)),this.faceVertexUvs[0].push([D,
+F,y]);this.computeFaceNormals()};THREE.CylinderGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CylinderGeometry.prototype.constructor=THREE.CylinderGeometry;THREE.CylinderGeometry.prototype.clone=function(){return new THREE.CylinderGeometry(this.parameters.radiusTop,this.parameters.radiusBottom,this.parameters.height,this.parameters.radialSegments,this.parameters.heightSegments,this.parameters.openEnded,this.parameters.thetaStart,this.parameters.thetaLength)};
 THREE.EdgesGeometry=function(a,b){THREE.BufferGeometry.call(this);var c=Math.cos(THREE.Math.degToRad(void 0!==b?b:1)),d=[0,0],e={},g=function(a,b){return a-b},f=["a","b","c"],h;a instanceof THREE.BufferGeometry?(h=new THREE.Geometry,h.fromBufferGeometry(a)):h=a.clone();h.mergeVertices();h.computeFaceNormals();var k=h.vertices;h=h.faces;for(var l=0,n=h.length;l<n;l++)for(var p=h[l],m=0;3>m;m++){d[0]=p[f[m]];d[1]=p[f[(m+1)%3]];d.sort(g);var q=d.toString();void 0===e[q]?e[q]={vert1:d[0],vert2:d[1],face1:l,
 face2:void 0}:e[q].face2=l}d=[];for(q in e)if(g=e[q],void 0===g.face2||h[g.face1].normal.dot(h[g.face2].normal)<=c)f=k[g.vert1],d.push(f.x),d.push(f.y),d.push(f.z),f=k[g.vert2],d.push(f.x),d.push(f.y),d.push(f.z);this.addAttribute("position",new THREE.BufferAttribute(new Float32Array(d),3))};THREE.EdgesGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.EdgesGeometry.prototype.constructor=THREE.EdgesGeometry;
 THREE.ExtrudeGeometry=function(a,b){"undefined"!==typeof a&&(THREE.Geometry.call(this),this.type="ExtrudeGeometry",a=Array.isArray(a)?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<c;d++)this.addShape(a[d],b)};
 THREE.ExtrudeGeometry.prototype.addShape=function(a,b){function c(a,b,c){b||console.error("THREE.ExtrudeGeometry: vec does not exist");return b.clone().multiplyScalar(c).add(a)}function d(a,b,c){var d=1,d=a.x-b.x,e=a.y-b.y,f=c.x-a.x,g=c.y-a.y,h=d*d+e*e;if(1E-10<Math.abs(d*g-e*f)){var k=Math.sqrt(h),l=Math.sqrt(f*f+g*g),h=b.x-e/k;b=b.y+d/k;f=((c.x-g/l-h)*g-(c.y+f/l-b)*f)/(d*g-e*f);c=h+d*f-a.x;a=b+e*f-a.y;d=c*c+a*a;if(2>=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10<d?1E-10<f&&(a=
-!0):-1E-10>d?-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(E=a.length;0<=--E;){c=E;d=E-1;0>d&&(d=a.length-1);for(var e=0,f=q+2*n,e=0;e<f;e++){var g=U*e,h=U*(e+1),k=b+c+g,g=b+d+g,l=b+d+h,h=b+c+h,k=k+K,g=g+K,l=l+K,h=h+K;O.faces.push(new THREE.Face3(k,g,h));O.faces.push(new THREE.Face3(g,l,h));k=x.generateSideWallUV(O,k,g,l,h);O.faceVertexUvs[0].push([k[0],k[1],k[3]]);O.faceVertexUvs[0].push([k[1],
-k[2],k[3]])}}}function g(a,b,c){O.vertices.push(new THREE.Vector3(a,b,c))}function f(a,b,c){a+=K;b+=K;c+=K;O.faces.push(new THREE.Face3(a,b,c));a=x.generateTopUV(O,a,b,c);O.faceVertexUvs[0].push(a)}var h=void 0!==b.amount?b.amount:100,k=void 0!==b.bevelThickness?b.bevelThickness:6,l=void 0!==b.bevelSize?b.bevelSize:k-2,n=void 0!==b.bevelSegments?b.bevelSegments:3,p=void 0!==b.bevelEnabled?b.bevelEnabled:!0,m=void 0!==b.curveSegments?b.curveSegments:12,q=void 0!==b.steps?b.steps:1,s=b.extrudePath,
-r,u=!1,x=void 0!==b.UVGenerator?b.UVGenerator:THREE.ExtrudeGeometry.WorldUVGenerator,v,y,w,G;s&&(r=s.getSpacedPoints(q),u=!0,p=!1,v=void 0!==b.frames?b.frames:new THREE.TubeGeometry.FrenetFrames(s,q,!1),y=new THREE.Vector3,w=new THREE.Vector3,G=new THREE.Vector3);p||(l=k=n=0);var B,z,A,O=this,K=this.vertices.length,s=a.extractPoints(m),m=s.shape,D=s.holes;if(s=!THREE.Shape.Utils.isClockWise(m)){m=m.reverse();z=0;for(A=D.length;z<A;z++)B=D[z],THREE.Shape.Utils.isClockWise(B)&&(D[z]=B.reverse());s=
-!1}var P=THREE.Shape.Utils.triangulateShape(m,D),J=m;z=0;for(A=D.length;z<A;z++)B=D[z],m=m.concat(B);var H,C,F,N,R,U=m.length,Q,S=P.length,s=[],E=0;F=J.length;H=F-1;for(C=E+1;E<F;E++,H++,C++)H===F&&(H=0),C===F&&(C=0),s[E]=d(J[E],J[H],J[C]);var ha=[],X,ia=s.concat();z=0;for(A=D.length;z<A;z++){B=D[z];X=[];E=0;F=B.length;H=F-1;for(C=E+1;E<F;E++,H++,C++)H===F&&(H=0),C===F&&(C=0),X[E]=d(B[E],B[H],B[C]);ha.push(X);ia=ia.concat(X)}for(H=0;H<n;H++){F=H/n;N=k*(1-F);C=l*Math.sin(F*Math.PI/2);E=0;for(F=J.length;E<
-F;E++)R=c(J[E],s[E],C),g(R.x,R.y,-N);z=0;for(A=D.length;z<A;z++)for(B=D[z],X=ha[z],E=0,F=B.length;E<F;E++)R=c(B[E],X[E],C),g(R.x,R.y,-N)}C=l;for(E=0;E<U;E++)R=p?c(m[E],ia[E],C):m[E],u?(w.copy(v.normals[0]).multiplyScalar(R.x),y.copy(v.binormals[0]).multiplyScalar(R.y),G.copy(r[0]).add(w).add(y),g(G.x,G.y,G.z)):g(R.x,R.y,0);for(F=1;F<=q;F++)for(E=0;E<U;E++)R=p?c(m[E],ia[E],C):m[E],u?(w.copy(v.normals[F]).multiplyScalar(R.x),y.copy(v.binormals[F]).multiplyScalar(R.y),G.copy(r[F]).add(w).add(y),g(G.x,
-G.y,G.z)):g(R.x,R.y,h/q*F);for(H=n-1;0<=H;H--){F=H/n;N=k*(1-F);C=l*Math.sin(F*Math.PI/2);E=0;for(F=J.length;E<F;E++)R=c(J[E],s[E],C),g(R.x,R.y,h+N);z=0;for(A=D.length;z<A;z++)for(B=D[z],X=ha[z],E=0,F=B.length;E<F;E++)R=c(B[E],X[E],C),u?g(R.x,R.y+r[q-1].y,r[q-1].x+N):g(R.x,R.y,h+N)}(function(){if(p){var a;a=0*U;for(E=0;E<S;E++)Q=P[E],f(Q[2]+a,Q[1]+a,Q[0]+a);a=q+2*n;a*=U;for(E=0;E<S;E++)Q=P[E],f(Q[0]+a,Q[1]+a,Q[2]+a)}else{for(E=0;E<S;E++)Q=P[E],f(Q[2],Q[1],Q[0]);for(E=0;E<S;E++)Q=P[E],f(Q[0]+U*q,Q[1]+
-U*q,Q[2]+U*q)}})();(function(){var a=0;e(J,a);a+=J.length;z=0;for(A=D.length;z<A;z++)B=D[z],e(B,a),a+=B.length})()};
+!0):-1E-10>d?-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(E=a.length;0<=--E;){c=E;d=E-1;0>d&&(d=a.length-1);for(var e=0,f=q+2*n,e=0;e<f;e++){var g=V*e,h=V*(e+1),k=b+c+g,g=b+d+g,l=b+d+h,h=b+c+h,k=k+N,g=g+N,l=l+N,h=h+N;L.faces.push(new THREE.Face3(k,g,h));L.faces.push(new THREE.Face3(g,l,h));k=w.generateSideWallUV(L,k,g,l,h);L.faceVertexUvs[0].push([k[0],k[1],k[3]]);L.faceVertexUvs[0].push([k[1],
+k[2],k[3]])}}}function g(a,b,c){L.vertices.push(new THREE.Vector3(a,b,c))}function f(a,b,c){a+=N;b+=N;c+=N;L.faces.push(new THREE.Face3(a,b,c));a=w.generateTopUV(L,a,b,c);L.faceVertexUvs[0].push(a)}var h=void 0!==b.amount?b.amount:100,k=void 0!==b.bevelThickness?b.bevelThickness:6,l=void 0!==b.bevelSize?b.bevelSize:k-2,n=void 0!==b.bevelSegments?b.bevelSegments:3,p=void 0!==b.bevelEnabled?b.bevelEnabled:!0,m=void 0!==b.curveSegments?b.curveSegments:12,q=void 0!==b.steps?b.steps:1,t=b.extrudePath,
+r,v=!1,w=void 0!==b.UVGenerator?b.UVGenerator:THREE.ExtrudeGeometry.WorldUVGenerator,u,z,x,D;t&&(r=t.getSpacedPoints(q),v=!0,p=!1,u=void 0!==b.frames?b.frames:new THREE.TubeGeometry.FrenetFrames(t,q,!1),z=new THREE.Vector3,x=new THREE.Vector3,D=new THREE.Vector3);p||(l=k=n=0);var F,y,B,L=this,N=this.vertices.length,t=a.extractPoints(m),m=t.shape,C=t.holes;if(t=!THREE.Shape.Utils.isClockWise(m)){m=m.reverse();y=0;for(B=C.length;y<B;y++)F=C[y],THREE.Shape.Utils.isClockWise(F)&&(C[y]=F.reverse());t=
+!1}var O=THREE.Shape.Utils.triangulateShape(m,C),G=m;y=0;for(B=C.length;y<B;y++)F=C[y],m=m.concat(F);var J,A,H,P,Q,V=m.length,R,S=O.length,t=[],E=0;H=G.length;J=H-1;for(A=E+1;E<H;E++,J++,A++)J===H&&(J=0),A===H&&(A=0),t[E]=d(G[E],G[J],G[A]);var ja=[],Y,la=t.concat();y=0;for(B=C.length;y<B;y++){F=C[y];Y=[];E=0;H=F.length;J=H-1;for(A=E+1;E<H;E++,J++,A++)J===H&&(J=0),A===H&&(A=0),Y[E]=d(F[E],F[J],F[A]);ja.push(Y);la=la.concat(Y)}for(J=0;J<n;J++){H=J/n;P=k*(1-H);A=l*Math.sin(H*Math.PI/2);E=0;for(H=G.length;E<
+H;E++)Q=c(G[E],t[E],A),g(Q.x,Q.y,-P);y=0;for(B=C.length;y<B;y++)for(F=C[y],Y=ja[y],E=0,H=F.length;E<H;E++)Q=c(F[E],Y[E],A),g(Q.x,Q.y,-P)}A=l;for(E=0;E<V;E++)Q=p?c(m[E],la[E],A):m[E],v?(x.copy(u.normals[0]).multiplyScalar(Q.x),z.copy(u.binormals[0]).multiplyScalar(Q.y),D.copy(r[0]).add(x).add(z),g(D.x,D.y,D.z)):g(Q.x,Q.y,0);for(H=1;H<=q;H++)for(E=0;E<V;E++)Q=p?c(m[E],la[E],A):m[E],v?(x.copy(u.normals[H]).multiplyScalar(Q.x),z.copy(u.binormals[H]).multiplyScalar(Q.y),D.copy(r[H]).add(x).add(z),g(D.x,
+D.y,D.z)):g(Q.x,Q.y,h/q*H);for(J=n-1;0<=J;J--){H=J/n;P=k*(1-H);A=l*Math.sin(H*Math.PI/2);E=0;for(H=G.length;E<H;E++)Q=c(G[E],t[E],A),g(Q.x,Q.y,h+P);y=0;for(B=C.length;y<B;y++)for(F=C[y],Y=ja[y],E=0,H=F.length;E<H;E++)Q=c(F[E],Y[E],A),v?g(Q.x,Q.y+r[q-1].y,r[q-1].x+P):g(Q.x,Q.y,h+P)}(function(){if(p){var a;a=0*V;for(E=0;E<S;E++)R=O[E],f(R[2]+a,R[1]+a,R[0]+a);a=q+2*n;a*=V;for(E=0;E<S;E++)R=O[E],f(R[0]+a,R[1]+a,R[2]+a)}else{for(E=0;E<S;E++)R=O[E],f(R[2],R[1],R[0]);for(E=0;E<S;E++)R=O[E],f(R[0]+V*q,R[1]+
+V*q,R[2]+V*q)}})();(function(){var a=0;e(G,a);a+=G.length;y=0;for(B=C.length;y<B;y++)F=C[y],e(F,a),a+=F.length})()};
 THREE.ExtrudeGeometry.WorldUVGenerator={generateTopUV:function(a,b,c,d){a=a.vertices;b=a[b];c=a[c];d=a[d];return[new THREE.Vector2(b.x,b.y),new THREE.Vector2(c.x,c.y),new THREE.Vector2(d.x,d.y)]},generateSideWallUV:function(a,b,c,d,e){a=a.vertices;b=a[b];c=a[c];d=a[d];e=a[e];return.01>Math.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===Array.isArray(a)&&(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<d;c++)this.addShape(a[c],b);return this};
 THREE.ShapeGeometry.prototype.addShape=function(a,b){void 0===b&&(b={});var c=b.material,d=void 0===b.UVGenerator?THREE.ExtrudeGeometry.WorldUVGenerator:b.UVGenerator,e,g,f,h=this.vertices.length;e=a.extractPoints(void 0!==b.curveSegments?b.curveSegments:12);var k=e.shape,l=e.holes;if(!THREE.Shape.Utils.isClockWise(k))for(k=k.reverse(),e=0,g=l.length;e<g;e++)f=l[e],THREE.Shape.Utils.isClockWise(f)&&(l[e]=f.reverse());var n=THREE.Shape.Utils.triangulateShape(k,l);e=0;for(g=l.length;e<g;e++)f=l[e],
 k=k.concat(f);l=k.length;g=n.length;for(e=0;e<l;e++)f=k[e],this.vertices.push(new THREE.Vector3(f.x,f.y,0));for(e=0;e<g;e++)l=n[e],k=l[0]+h,f=l[1]+h,l=l[2]+h,this.faces.push(new THREE.Face3(k,f,l,null,null,c)),this.faceVertexUvs[0].push(d.generateTopUV(this,k,f,l))};
-THREE.LatheGeometry=function(a,b,c,d){THREE.Geometry.call(this);this.type="LatheGeometry";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};b=b||12;c=c||0;d=d||2*Math.PI;for(var e=1/(a.length-1),g=1/b,f=0,h=b;f<=h;f++)for(var k=c+f*g*d,l=Math.cos(k),n=Math.sin(k),k=0,p=a.length;k<p;k++){var m=a[k],q=new THREE.Vector3;q.x=l*m.x-n*m.y;q.y=n*m.x+l*m.y;q.z=m.z;this.vertices.push(q)}c=a.length;f=0;for(h=b;f<h;f++)for(k=0,p=a.length-1;k<p;k++){b=n=k+c*f;d=n+c;var l=n+1+c,n=n+1,m=f*g,q=k*e,s=
-m+g,r=q+e;this.faces.push(new THREE.Face3(b,d,n));this.faceVertexUvs[0].push([new THREE.Vector2(m,q),new THREE.Vector2(s,q),new THREE.Vector2(m,r)]);this.faces.push(new THREE.Face3(d,l,n));this.faceVertexUvs[0].push([new THREE.Vector2(s,q),new THREE.Vector2(s,r),new THREE.Vector2(m,r)])}this.mergeVertices();this.computeFaceNormals();this.computeVertexNormals()};THREE.LatheGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.LatheGeometry.prototype.constructor=THREE.LatheGeometry;
+THREE.LatheGeometry=function(a,b,c,d){THREE.Geometry.call(this);this.type="LatheGeometry";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};b=b||12;c=c||0;d=d||2*Math.PI;for(var e=1/(a.length-1),g=1/b,f=0,h=b;f<=h;f++)for(var k=c+f*g*d,l=Math.cos(k),n=Math.sin(k),k=0,p=a.length;k<p;k++){var m=a[k],q=new THREE.Vector3;q.x=l*m.x-n*m.y;q.y=n*m.x+l*m.y;q.z=m.z;this.vertices.push(q)}c=a.length;f=0;for(h=b;f<h;f++)for(k=0,p=a.length-1;k<p;k++){b=n=k+c*f;d=n+c;var l=n+1+c,n=n+1,m=f*g,q=k*e,t=
+m+g,r=q+e;this.faces.push(new THREE.Face3(b,d,n));this.faceVertexUvs[0].push([new THREE.Vector2(m,q),new THREE.Vector2(t,q),new THREE.Vector2(m,r)]);this.faces.push(new THREE.Face3(d,l,n));this.faceVertexUvs[0].push([new THREE.Vector2(t,q),new THREE.Vector2(t,r),new THREE.Vector2(m,r)])}this.mergeVertices();this.computeFaceNormals();this.computeVertexNormals()};THREE.LatheGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.LatheGeometry.prototype.constructor=THREE.LatheGeometry;
 THREE.PlaneGeometry=function(a,b,c,d){THREE.Geometry.call(this);this.type="PlaneGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};this.fromBufferGeometry(new THREE.PlaneBufferGeometry(a,b,c,d))};THREE.PlaneGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.PlaneGeometry.prototype.constructor=THREE.PlaneGeometry;
 THREE.PlaneGeometry.prototype.clone=function(){return new THREE.PlaneGeometry(this.parameters.width,this.parameters.height,this.parameters.widthSegments,this.parameters.heightSegments)};
-THREE.PlaneBufferGeometry=function(a,b,c,d){THREE.BufferGeometry.call(this);this.type="PlaneBufferGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};var e=a/2,g=b/2;c=Math.floor(c)||1;d=Math.floor(d)||1;var f=c+1,h=d+1,k=a/c,l=b/d;b=new Float32Array(f*h*3);a=new Float32Array(f*h*3);for(var n=new Float32Array(f*h*2),p=0,m=0,q=0;q<h;q++)for(var s=q*l-g,r=0;r<f;r++)b[p]=r*k-e,b[p+1]=-s,a[p+2]=1,n[m]=r/c,n[m+1]=1-q/d,p+=3,m+=2;p=0;e=new (65535<b.length/3?Uint32Array:Uint16Array)(c*
+THREE.PlaneBufferGeometry=function(a,b,c,d){THREE.BufferGeometry.call(this);this.type="PlaneBufferGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};var e=a/2,g=b/2;c=Math.floor(c)||1;d=Math.floor(d)||1;var f=c+1,h=d+1,k=a/c,l=b/d;b=new Float32Array(f*h*3);a=new Float32Array(f*h*3);for(var n=new Float32Array(f*h*2),p=0,m=0,q=0;q<h;q++)for(var t=q*l-g,r=0;r<f;r++)b[p]=r*k-e,b[p+1]=-t,a[p+2]=1,n[m]=r/c,n[m+1]=1-q/d,p+=3,m+=2;p=0;e=new (65535<b.length/3?Uint32Array:Uint16Array)(c*
 d*6);for(q=0;q<d;q++)for(r=0;r<c;r++)g=r+f*(q+1),h=r+1+f*(q+1),k=r+1+f*q,e[p]=r+f*q,e[p+1]=g,e[p+2]=k,e[p+3]=g,e[p+4]=h,e[p+5]=k,p+=6;this.addIndex(new THREE.BufferAttribute(e,1));this.addAttribute("position",new THREE.BufferAttribute(b,3));this.addAttribute("normal",new THREE.BufferAttribute(a,3));this.addAttribute("uv",new THREE.BufferAttribute(n,2))};THREE.PlaneBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.PlaneBufferGeometry.prototype.constructor=THREE.PlaneBufferGeometry;
 THREE.PlaneBufferGeometry.prototype.clone=function(){var a=new THREE.PlaneBufferGeometry(this.parameters.width,this.parameters.height,this.parameters.widthSegments,this.parameters.heightSegments);a.copy(this);return a};
 THREE.RingGeometry=function(a,b,c,d,e,g){THREE.Geometry.call(this);this.type="RingGeometry";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:g};a=a||0;b=b||50;e=void 0!==e?e:0;g=void 0!==g?g:2*Math.PI;c=void 0!==c?Math.max(3,c):8;d=void 0!==d?Math.max(1,d):8;var f,h=[],k=a,l=(b-a)/d;for(a=0;a<d+1;a++){for(f=0;f<c+1;f++){var n=new THREE.Vector3,p=e+f/c*g;n.x=k*Math.cos(p);n.y=k*Math.sin(p);this.vertices.push(n);h.push(new THREE.Vector2((n.x/b+1)/2,
 (n.y/b+1)/2))}k+=l}b=new THREE.Vector3(0,0,1);for(a=0;a<d;a++)for(e=a*(c+1),f=0;f<c;f++)g=p=f+e,l=p+c+1,n=p+c+2,this.faces.push(new THREE.Face3(g,l,n,[b.clone(),b.clone(),b.clone()])),this.faceVertexUvs[0].push([h[g].clone(),h[l].clone(),h[n].clone()]),g=p,l=p+c+2,n=p+1,this.faces.push(new THREE.Face3(g,l,n,[b.clone(),b.clone(),b.clone()])),this.faceVertexUvs[0].push([h[g].clone(),h[l].clone(),h[n].clone()]);this.computeFaceNormals();this.boundingSphere=new THREE.Sphere(new THREE.Vector3,k)};
 THREE.RingGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.RingGeometry.prototype.constructor=THREE.RingGeometry;THREE.RingGeometry.prototype.clone=function(){return new THREE.RingGeometry(this.parameters.innerRadius,this.parameters.outerRadius,this.parameters.thetaSegments,this.parameters.phiSegments,this.parameters.thetaStart,this.parameters.thetaLength)};
-THREE.SphereGeometry=function(a,b,c,d,e,g,f){console.log("THREE.SphereGeometry: Consider using THREE.SphereBufferGeometry for lower memory footprint.");THREE.Geometry.call(this);this.type="SphereGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:g,thetaLength:f};a=a||50;b=Math.max(3,Math.floor(b)||8);c=Math.max(2,Math.floor(c)||6);d=void 0!==d?d:0;e=void 0!==e?e:2*Math.PI;g=void 0!==g?g:0;f=void 0!==f?f:Math.PI;var h,k,l=[],n=[];for(k=0;k<=c;k++){var p=
-[],m=[];for(h=0;h<=b;h++){var q=h/b,s=k/c,r=new THREE.Vector3;r.x=-a*Math.cos(d+q*e)*Math.sin(g+s*f);r.y=a*Math.cos(g+s*f);r.z=a*Math.sin(d+q*e)*Math.sin(g+s*f);this.vertices.push(r);p.push(this.vertices.length-1);m.push(new THREE.Vector2(q,1-s))}l.push(p);n.push(m)}for(k=0;k<c;k++)for(h=0;h<b;h++){d=l[k][h+1];e=l[k][h];g=l[k+1][h];f=l[k+1][h+1];var p=this.vertices[d].clone().normalize(),m=this.vertices[e].clone().normalize(),q=this.vertices[g].clone().normalize(),s=this.vertices[f].clone().normalize(),
-r=n[k][h+1].clone(),u=n[k][h].clone(),x=n[k+1][h].clone(),v=n[k+1][h+1].clone();Math.abs(this.vertices[d].y)===a?(r.x=(r.x+u.x)/2,this.faces.push(new THREE.Face3(d,g,f,[p,q,s])),this.faceVertexUvs[0].push([r,x,v])):Math.abs(this.vertices[g].y)===a?(x.x=(x.x+v.x)/2,this.faces.push(new THREE.Face3(d,e,g,[p,m,q])),this.faceVertexUvs[0].push([r,u,x])):(this.faces.push(new THREE.Face3(d,e,f,[p,m,s])),this.faceVertexUvs[0].push([r,u,v]),this.faces.push(new THREE.Face3(e,g,f,[m.clone(),q,s.clone()])),this.faceVertexUvs[0].push([u.clone(),
-x,v.clone()]))}this.computeFaceNormals();this.boundingSphere=new THREE.Sphere(new THREE.Vector3,a)};THREE.SphereGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.SphereGeometry.prototype.constructor=THREE.SphereGeometry;THREE.SphereGeometry.prototype.clone=function(){return new THREE.SphereGeometry(this.parameters.radius,this.parameters.widthSegments,this.parameters.heightSegments,this.parameters.phiStart,this.parameters.phiLength,this.parameters.thetaStart,this.parameters.thetaLength)};
+THREE.SphereGeometry=function(a,b,c,d,e,g,f){THREE.Geometry.call(this);this.type="SphereGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:g,thetaLength:f};this.fromBufferGeometry(new THREE.SphereBufferGeometry(a,b,c,d,e,g,f))};THREE.SphereGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.SphereGeometry.prototype.constructor=THREE.SphereGeometry;
+THREE.SphereGeometry.prototype.clone=function(){return new THREE.SphereGeometry(this.parameters.radius,this.parameters.widthSegments,this.parameters.heightSegments,this.parameters.phiStart,this.parameters.phiLength,this.parameters.thetaStart,this.parameters.thetaLength)};
 THREE.SphereBufferGeometry=function(a,b,c,d,e,g,f){THREE.BufferGeometry.call(this);this.type="SphereBufferGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:g,thetaLength:f};a=a||50;b=Math.max(3,Math.floor(b)||8);c=Math.max(2,Math.floor(c)||6);d=void 0!==d?d:0;e=void 0!==e?e:2*Math.PI;g=void 0!==g?g:0;f=void 0!==f?f:Math.PI;for(var h=g+f,k=(b+1)*(c+1),l=new THREE.BufferAttribute(new Float32Array(3*k),3),n=new THREE.BufferAttribute(new Float32Array(3*
-k),3),k=new THREE.BufferAttribute(new Float32Array(2*k),2),p=0,m=[],q=new THREE.Vector3,s=0;s<=c;s++){for(var r=[],u=s/c,x=0;x<=b;x++){var v=x/b,y=-a*Math.cos(d+v*e)*Math.sin(g+u*f),w=a*Math.cos(g+u*f),G=a*Math.sin(d+v*e)*Math.sin(g+u*f);q.set(y,w,G).normalize();l.setXYZ(p,y,w,G);n.setXYZ(p,q.x,q.y,q.z);k.setXY(p,v,1-u);r.push(p);p++}m.push(r)}d=[];for(s=0;s<c;s++)for(x=0;x<b;x++)e=m[s][x+1],f=m[s][x],p=m[s+1][x],q=m[s+1][x+1],(0!==s||0<g)&&d.push(e,f,q),(s!==c-1||h<Math.PI)&&d.push(f,p,q);this.addIndex(new THREE.BufferAttribute(new Uint16Array(d),
+k),3),k=new THREE.BufferAttribute(new Float32Array(2*k),2),p=0,m=[],q=new THREE.Vector3,t=0;t<=c;t++){for(var r=[],v=t/c,w=0;w<=b;w++){var u=w/b,z=-a*Math.cos(d+u*e)*Math.sin(g+v*f),x=a*Math.cos(g+v*f),D=a*Math.sin(d+u*e)*Math.sin(g+v*f);q.set(z,x,D).normalize();l.setXYZ(p,z,x,D);n.setXYZ(p,q.x,q.y,q.z);k.setXY(p,u,1-v);r.push(p);p++}m.push(r)}d=[];for(t=0;t<c;t++)for(w=0;w<b;w++)e=m[t][w+1],f=m[t][w],p=m[t+1][w],q=m[t+1][w+1],(0!==t||0<g)&&d.push(e,f,q),(t!==c-1||h<Math.PI)&&d.push(f,p,q);this.addIndex(new THREE.BufferAttribute(new Uint16Array(d),
 1));this.addAttribute("position",l);this.addAttribute("normal",n);this.addAttribute("uv",k);this.boundingSphere=new THREE.Sphere(new THREE.Vector3,a)};THREE.SphereBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.SphereBufferGeometry.prototype.constructor=THREE.SphereBufferGeometry;
 THREE.SphereBufferGeometry.prototype.clone=function(){var a=new THREE.SphereBufferGeometry(this.parameters.radius,this.parameters.widthSegments,this.parameters.heightSegments,this.parameters.phiStart,this.parameters.phiLength,this.parameters.thetaStart,this.parameters.thetaLength);a.copy(this);return a};
 THREE.TextGeometry=function(a,b){b=b||{};var c=THREE.FontUtils.generateShapes(a,b);b.amount=void 0!==b.height?b.height:50;void 0===b.bevelThickness&&(b.bevelThickness=10);void 0===b.bevelSize&&(b.bevelSize=8);void 0===b.bevelEnabled&&(b.bevelEnabled=!1);THREE.ExtrudeGeometry.call(this,c,b);this.type="TextGeometry"};THREE.TextGeometry.prototype=Object.create(THREE.ExtrudeGeometry.prototype);THREE.TextGeometry.prototype.constructor=THREE.TextGeometry;
@@ -794,17 +790,17 @@ THREE.TorusGeometry=function(a,b,c,d,e){THREE.Geometry.call(this);this.type="Tor
 d,k/c));h.push(m.clone().sub(g).normalize())}for(k=1;k<=c;k++)for(l=1;l<=d;l++)a=(d+1)*k+l-1,b=(d+1)*(k-1)+l-1,e=(d+1)*(k-1)+l,g=(d+1)*k+l,n=new THREE.Face3(a,b,g,[h[a].clone(),h[b].clone(),h[g].clone()]),this.faces.push(n),this.faceVertexUvs[0].push([f[a].clone(),f[b].clone(),f[g].clone()]),n=new THREE.Face3(b,e,g,[h[b].clone(),h[e].clone(),h[g].clone()]),this.faces.push(n),this.faceVertexUvs[0].push([f[b].clone(),f[e].clone(),f[g].clone()]);this.computeFaceNormals()};
 THREE.TorusGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.TorusGeometry.prototype.constructor=THREE.TorusGeometry;THREE.TorusGeometry.prototype.clone=function(){return new THREE.TorusGeometry(this.parameters.radius,this.parameters.tube,this.parameters.radialSegments,this.parameters.tubularSegments,this.parameters.arc)};
 THREE.TorusKnotGeometry=function(a,b,c,d,e,g,f){function h(a,b,c,d,e){var f=Math.cos(a),g=Math.sin(a);a*=b/c;b=Math.cos(a);f*=d*(2+b)*.5;g=d*(2+b)*g*.5;d=e*d*Math.sin(a)*.5;return new THREE.Vector3(f,g,d)}THREE.Geometry.call(this);this.type="TorusKnotGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,p:e,q:g,heightScale:f};a=a||100;b=b||40;c=c||64;d=d||8;e=e||2;g=g||3;f=f||1;for(var k=Array(c),l=new THREE.Vector3,n=new THREE.Vector3,p=new THREE.Vector3,m=0;m<c;++m){k[m]=
-Array(d);var q=m/c*2*e*Math.PI,s=h(q,g,e,a,f),q=h(q+.01,g,e,a,f);l.subVectors(q,s);n.addVectors(q,s);p.crossVectors(l,n);n.crossVectors(p,l);p.normalize();n.normalize();for(q=0;q<d;++q){var r=q/d*2*Math.PI,u=-b*Math.cos(r),r=b*Math.sin(r),x=new THREE.Vector3;x.x=s.x+u*n.x+r*p.x;x.y=s.y+u*n.y+r*p.y;x.z=s.z+u*n.z+r*p.z;k[m][q]=this.vertices.push(x)-1}}for(m=0;m<c;++m)for(q=0;q<d;++q)e=(m+1)%c,g=(q+1)%d,a=k[m][q],b=k[e][q],e=k[e][g],g=k[m][g],f=new THREE.Vector2(m/c,q/d),l=new THREE.Vector2((m+1)/c,
+Array(d);var q=m/c*2*e*Math.PI,t=h(q,g,e,a,f),q=h(q+.01,g,e,a,f);l.subVectors(q,t);n.addVectors(q,t);p.crossVectors(l,n);n.crossVectors(p,l);p.normalize();n.normalize();for(q=0;q<d;++q){var r=q/d*2*Math.PI,v=-b*Math.cos(r),r=b*Math.sin(r),w=new THREE.Vector3;w.x=t.x+v*n.x+r*p.x;w.y=t.y+v*n.y+r*p.y;w.z=t.z+v*n.z+r*p.z;k[m][q]=this.vertices.push(w)-1}}for(m=0;m<c;++m)for(q=0;q<d;++q)e=(m+1)%c,g=(q+1)%d,a=k[m][q],b=k[e][q],e=k[e][g],g=k[m][g],f=new THREE.Vector2(m/c,q/d),l=new THREE.Vector2((m+1)/c,
 q/d),n=new THREE.Vector2((m+1)/c,(q+1)/d),p=new THREE.Vector2(m/c,(q+1)/d),this.faces.push(new THREE.Face3(a,b,g)),this.faceVertexUvs[0].push([f,l,p]),this.faces.push(new THREE.Face3(b,e,g)),this.faceVertexUvs[0].push([l.clone(),n,p.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.TorusKnotGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.TorusKnotGeometry.prototype.constructor=THREE.TorusKnotGeometry;
 THREE.TorusKnotGeometry.prototype.clone=function(){return new THREE.TorusKnotGeometry(this.parameters.radius,this.parameters.tube,this.parameters.radialSegments,this.parameters.tubularSegments,this.parameters.p,this.parameters.q,this.parameters.heightScale)};
-THREE.TubeGeometry=function(a,b,c,d,e,g){THREE.Geometry.call(this);this.type="TubeGeometry";this.parameters={path:a,segments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;g=g||THREE.TubeGeometry.NoTaper;var f=[],h,k,l=b+1,n,p,m,q,s,r=new THREE.Vector3,u,x,v;u=new THREE.TubeGeometry.FrenetFrames(a,b,e);x=u.normals;v=u.binormals;this.tangents=u.tangents;this.normals=x;this.binormals=v;for(u=0;u<l;u++)for(f[u]=[],n=u/(l-1),s=a.getPointAt(n),h=x[u],k=v[u],m=c*g(n),n=0;n<d;n++)p=
-n/d*2*Math.PI,q=-m*Math.cos(p),p=m*Math.sin(p),r.copy(s),r.x+=q*h.x+p*k.x,r.y+=q*h.y+p*k.y,r.z+=q*h.z+p*k.z,f[u][n]=this.vertices.push(new THREE.Vector3(r.x,r.y,r.z))-1;for(u=0;u<b;u++)for(n=0;n<d;n++)g=e?(u+1)%b:u+1,l=(n+1)%d,a=f[u][n],c=f[g][n],g=f[g][l],l=f[u][l],r=new THREE.Vector2(u/b,n/d),x=new THREE.Vector2((u+1)/b,n/d),v=new THREE.Vector2((u+1)/b,(n+1)/d),h=new THREE.Vector2(u/b,(n+1)/d),this.faces.push(new THREE.Face3(a,c,l)),this.faceVertexUvs[0].push([r,x,h]),this.faces.push(new THREE.Face3(c,
-g,l)),this.faceVertexUvs[0].push([x.clone(),v,h.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.TubeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.TubeGeometry.prototype.constructor=THREE.TubeGeometry;THREE.TubeGeometry.NoTaper=function(a){return 1};THREE.TubeGeometry.SinusoidalTaper=function(a){return Math.sin(Math.PI*a)};
+THREE.TubeGeometry=function(a,b,c,d,e,g){THREE.Geometry.call(this);this.type="TubeGeometry";this.parameters={path:a,segments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;g=g||THREE.TubeGeometry.NoTaper;var f=[],h,k,l=b+1,n,p,m,q,t,r=new THREE.Vector3,v,w,u;v=new THREE.TubeGeometry.FrenetFrames(a,b,e);w=v.normals;u=v.binormals;this.tangents=v.tangents;this.normals=w;this.binormals=u;for(v=0;v<l;v++)for(f[v]=[],n=v/(l-1),t=a.getPointAt(n),h=w[v],k=u[v],m=c*g(n),n=0;n<d;n++)p=
+n/d*2*Math.PI,q=-m*Math.cos(p),p=m*Math.sin(p),r.copy(t),r.x+=q*h.x+p*k.x,r.y+=q*h.y+p*k.y,r.z+=q*h.z+p*k.z,f[v][n]=this.vertices.push(new THREE.Vector3(r.x,r.y,r.z))-1;for(v=0;v<b;v++)for(n=0;n<d;n++)g=e?(v+1)%b:v+1,l=(n+1)%d,a=f[v][n],c=f[g][n],g=f[g][l],l=f[v][l],r=new THREE.Vector2(v/b,n/d),w=new THREE.Vector2((v+1)/b,n/d),u=new THREE.Vector2((v+1)/b,(n+1)/d),h=new THREE.Vector2(v/b,(n+1)/d),this.faces.push(new THREE.Face3(a,c,l)),this.faceVertexUvs[0].push([r,w,h]),this.faces.push(new THREE.Face3(c,
+g,l)),this.faceVertexUvs[0].push([w.clone(),u,h.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.TubeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.TubeGeometry.prototype.constructor=THREE.TubeGeometry;THREE.TubeGeometry.NoTaper=function(a){return 1};THREE.TubeGeometry.SinusoidalTaper=function(a){return Math.sin(Math.PI*a)};
 THREE.TubeGeometry.FrenetFrames=function(a,b,c){var d=new THREE.Vector3,e=[],g=[],f=[],h=new THREE.Vector3,k=new THREE.Matrix4;b+=1;var l,n,p;this.tangents=e;this.normals=g;this.binormals=f;for(l=0;l<b;l++)n=l/(b-1),e[l]=a.getTangentAt(n),e[l].normalize();g[0]=new THREE.Vector3;f[0]=new THREE.Vector3;a=Number.MAX_VALUE;l=Math.abs(e[0].x);n=Math.abs(e[0].y);p=Math.abs(e[0].z);l<=a&&(a=l,d.set(1,0,0));n<=a&&(a=n,d.set(0,1,0));p<=a&&d.set(0,0,1);h.crossVectors(e[0],d).normalize();g[0].crossVectors(e[0],
 h);f[0].crossVectors(e[0],g[0]);for(l=1;l<b;l++)g[l]=g[l-1].clone(),f[l]=f[l-1].clone(),h.crossVectors(e[l-1],e[l]),1E-4<h.length()&&(h.normalize(),d=Math.acos(THREE.Math.clamp(e[l-1].dot(e[l]),-1,1)),g[l].applyMatrix4(k.makeRotationAxis(h,d))),f[l].crossVectors(e[l],g[l]);if(c)for(d=Math.acos(THREE.Math.clamp(g[0].dot(g[b-1]),-1,1)),d/=b-1,0<e[0].dot(h.crossVectors(g[0],g[b-1]))&&(d=-d),l=1;l<b;l++)g[l].applyMatrix4(k.makeRotationAxis(e[l],d*l)),f[l].crossVectors(e[l],g[l])};
-THREE.PolyhedronGeometry=function(a,b,c,d){function e(a){var b=a.normalize().clone();b.index=k.vertices.push(b)-1;var c=Math.atan2(a.z,-a.x)/2/Math.PI+.5;a=Math.atan2(-a.y,Math.sqrt(a.x*a.x+a.z*a.z))/Math.PI+.5;b.uv=new THREE.Vector2(c,1-a);return b}function g(a,b,c,d){d=new THREE.Face3(a.index,b.index,c.index,[a.clone(),b.clone(),c.clone()],void 0,d);k.faces.push(d);u.copy(a).add(b).add(c).divideScalar(3);d=Math.atan2(u.z,-u.x);k.faceVertexUvs[0].push([h(a.uv,a,d),h(b.uv,b,d),h(c.uv,c,d)])}function f(a,
-b){for(var c=Math.pow(2,b),d=e(k.vertices[a.a]),f=e(k.vertices[a.b]),h=e(k.vertices[a.c]),l=[],m=a.materialIndex,n=0;n<=c;n++){l[n]=[];for(var p=e(d.clone().lerp(h,n/c)),q=e(f.clone().lerp(h,n/c)),r=c-n,s=0;s<=r;s++)l[n][s]=0===s&&n===c?p:e(p.clone().lerp(q,s/r))}for(n=0;n<c;n++)for(s=0;s<2*(c-n)-1;s++)d=Math.floor(s/2),0===s%2?g(l[n][d+1],l[n+1][d],l[n][d],m):g(l[n][d+1],l[n+1][d+1],l[n+1][d],m)}function h(a,b,c){0>c&&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,n=a.length;l<n;l+=3)e(new THREE.Vector3(a[l],a[l+1],a[l+2]));a=this.vertices;for(var p=[],m=l=0,n=b.length;l<n;l+=3,m++){var q=a[b[l]],s=a[b[l+1]],r=a[b[l+2]];p[m]=new THREE.Face3(q.index,s.index,r.index,[q.clone(),s.clone(),r.clone()],void 0,m)}for(var u=new THREE.Vector3,l=0,n=p.length;l<n;l++)f(p[l],d);l=0;for(n=this.faceVertexUvs[0].length;l<
+THREE.PolyhedronGeometry=function(a,b,c,d){function e(a){var b=a.normalize().clone();b.index=k.vertices.push(b)-1;var c=Math.atan2(a.z,-a.x)/2/Math.PI+.5;a=Math.atan2(-a.y,Math.sqrt(a.x*a.x+a.z*a.z))/Math.PI+.5;b.uv=new THREE.Vector2(c,1-a);return b}function g(a,b,c,d){d=new THREE.Face3(a.index,b.index,c.index,[a.clone(),b.clone(),c.clone()],void 0,d);k.faces.push(d);v.copy(a).add(b).add(c).divideScalar(3);d=Math.atan2(v.z,-v.x);k.faceVertexUvs[0].push([h(a.uv,a,d),h(b.uv,b,d),h(c.uv,c,d)])}function f(a,
+b){for(var c=Math.pow(2,b),d=e(k.vertices[a.a]),f=e(k.vertices[a.b]),h=e(k.vertices[a.c]),l=[],m=a.materialIndex,n=0;n<=c;n++){l[n]=[];for(var p=e(d.clone().lerp(h,n/c)),q=e(f.clone().lerp(h,n/c)),r=c-n,t=0;t<=r;t++)l[n][t]=0===t&&n===c?p:e(p.clone().lerp(q,t/r))}for(n=0;n<c;n++)for(t=0;t<2*(c-n)-1;t++)d=Math.floor(t/2),0===t%2?g(l[n][d+1],l[n+1][d],l[n][d],m):g(l[n][d+1],l[n+1][d+1],l[n+1][d],m)}function h(a,b,c){0>c&&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,n=a.length;l<n;l+=3)e(new THREE.Vector3(a[l],a[l+1],a[l+2]));a=this.vertices;for(var p=[],m=l=0,n=b.length;l<n;l+=3,m++){var q=a[b[l]],t=a[b[l+1]],r=a[b[l+2]];p[m]=new THREE.Face3(q.index,t.index,r.index,[q.clone(),t.clone(),r.clone()],void 0,m)}for(var v=new THREE.Vector3,l=0,n=p.length;l<n;l++)f(p[l],d);l=0;for(n=this.faceVertexUvs[0].length;l<
 n;l++)b=this.faceVertexUvs[0][l],d=b[0].x,a=b[1].x,p=b[2].x,m=Math.max(d,Math.max(a,p)),q=Math.min(d,Math.min(a,p)),.9<m&&.1>q&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>p&&(b[2].x+=1));l=0;for(n=this.vertices.length;l<n;l++)this.vertices[l].multiplyScalar(c);this.mergeVertices();this.computeFaceNormals();this.boundingSphere=new THREE.Sphere(new THREE.Vector3,c)};THREE.PolyhedronGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.PolyhedronGeometry.prototype.constructor=THREE.PolyhedronGeometry;
 THREE.PolyhedronGeometry.prototype.clone=function(){return(new THREE.PolyhedronGeometry(this.parameters.vertices,this.parameters.indices,this.parameters.radius,this.parameters.detail)).copy(this)};THREE.PolyhedronGeometry.prototype.copy=function(a){THREE.Geometry.prototype.copy.call(this,a);return this};
 THREE.DodecahedronGeometry=function(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;THREE.PolyhedronGeometry.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,
@@ -814,8 +810,8 @@ THREE.IcosahedronGeometry.prototype.constructor=THREE.IcosahedronGeometry;THREE.
 THREE.OctahedronGeometry.prototype=Object.create(THREE.PolyhedronGeometry.prototype);THREE.OctahedronGeometry.prototype.constructor=THREE.OctahedronGeometry;THREE.OctahedronGeometry.prototype.clone=function(){var a=new THREE.OctahedronGeometry(this.parameters.radius,this.parameters.detail);a.copy(this);return a};
 THREE.TetrahedronGeometry=function(a,b){THREE.PolyhedronGeometry.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b}};THREE.TetrahedronGeometry.prototype=Object.create(THREE.PolyhedronGeometry.prototype);THREE.TetrahedronGeometry.prototype.constructor=THREE.TetrahedronGeometry;
 THREE.TetrahedronGeometry.prototype.clone=function(){var a=new THREE.TetrahedronGeometry(this.parameters.radius,this.parameters.detail);a.copy(this);return a};
-THREE.ParametricGeometry=function(a,b,c){THREE.Geometry.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};var d=this.vertices,e=this.faces,g=this.faceVertexUvs[0],f,h,k,l,n=b+1;for(f=0;f<=c;f++)for(l=f/c,h=0;h<=b;h++)k=h/b,k=a(k,l),d.push(k);var p,m,q,s;for(f=0;f<c;f++)for(h=0;h<b;h++)a=f*n+h,d=f*n+h+1,l=(f+1)*n+h+1,k=(f+1)*n+h,p=new THREE.Vector2(h/b,f/c),m=new THREE.Vector2((h+1)/b,f/c),q=new THREE.Vector2((h+1)/b,(f+1)/c),s=new THREE.Vector2(h/b,(f+1)/c),e.push(new THREE.Face3(a,
-d,k)),g.push([p,m,s]),e.push(new THREE.Face3(d,l,k)),g.push([m.clone(),q,s.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.ParametricGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ParametricGeometry.prototype.constructor=THREE.ParametricGeometry;
+THREE.ParametricGeometry=function(a,b,c){THREE.Geometry.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};var d=this.vertices,e=this.faces,g=this.faceVertexUvs[0],f,h,k,l,n=b+1;for(f=0;f<=c;f++)for(l=f/c,h=0;h<=b;h++)k=h/b,k=a(k,l),d.push(k);var p,m,q,t;for(f=0;f<c;f++)for(h=0;h<b;h++)a=f*n+h,d=f*n+h+1,l=(f+1)*n+h+1,k=(f+1)*n+h,p=new THREE.Vector2(h/b,f/c),m=new THREE.Vector2((h+1)/b,f/c),q=new THREE.Vector2((h+1)/b,(f+1)/c),t=new THREE.Vector2(h/b,(f+1)/c),e.push(new THREE.Face3(a,
+d,k)),g.push([p,m,t]),e.push(new THREE.Face3(d,l,k)),g.push([m.clone(),q,t.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.ParametricGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ParametricGeometry.prototype.constructor=THREE.ParametricGeometry;
 THREE.WireframeGeometry=function(a){THREE.BufferGeometry.call(this);var b=[0,0],c={},d=function(a,b){return a-b},e=["a","b","c"];if(a instanceof THREE.Geometry){var g=a.vertices,f=a.faces,h=0,k=new Uint32Array(6*f.length);a=0;for(var l=f.length;a<l;a++)for(var n=f[a],p=0;3>p;p++){b[0]=n[e[p]];b[1]=n[e[(p+1)%3]];b.sort(d);var m=b.toString();void 0===c[m]&&(k[2*h]=b[0],k[2*h+1]=b[1],c[m]=!0,h++)}b=new Float32Array(6*h);a=0;for(l=h;a<l;a++)for(p=0;2>p;p++)c=g[k[2*a+p]],h=6*a+3*p,b[h+0]=c.x,b[h+1]=c.y,
 b[h+2]=c.z;this.addAttribute("position",new THREE.BufferAttribute(b,3))}else if(a instanceof THREE.BufferGeometry){if(null!==a.index){l=a.index.array;g=a.attributes.position;e=a.drawcalls;h=0;0===e.length&&a.addDrawCall(0,l.length);k=new Uint32Array(2*l.length);f=0;for(n=e.length;f<n;++f){a=e[f];p=a.start;m=a.count;a=p;for(var q=p+m;a<q;a+=3)for(p=0;3>p;p++)b[0]=l[a+p],b[1]=l[a+(p+1)%3],b.sort(d),m=b.toString(),void 0===c[m]&&(k[2*h]=b[0],k[2*h+1]=b[1],c[m]=!0,h++)}b=new Float32Array(6*h);a=0;for(l=
 h;a<l;a++)for(p=0;2>p;p++)h=6*a+3*p,c=k[2*a+p],b[h+0]=g.getX(c),b[h+1]=g.getY(c),b[h+2]=g.getZ(c)}else for(g=a.attributes.position.array,h=g.length/3,k=h/3,b=new Float32Array(6*h),a=0,l=k;a<l;a++)for(p=0;3>p;p++)h=18*a+6*p,k=9*a+3*p,b[h+0]=g[k],b[h+1]=g[k+1],b[h+2]=g[k+2],c=9*a+(p+1)%3*3,b[h+3]=g[c],b[h+4]=g[c+1],b[h+5]=g[c+2];this.addAttribute("position",new THREE.BufferAttribute(b,3))}};THREE.WireframeGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);
@@ -855,12 +851,8 @@ THREE.SpotLightHelper=function(a){THREE.Object3D.call(this);this.light=a;this.li
 THREE.SpotLightHelper.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()};THREE.SpotLightHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){var c=this.light.distance?this.light.distance:1E4,d=c*Math.tan(this.light.angle);this.cone.scale.set(d,d,c);a.setFromMatrixPosition(this.light.matrixWorld);b.setFromMatrixPosition(this.light.target.matrixWorld);this.cone.lookAt(b.sub(a));this.cone.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)}}();
 THREE.VertexNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16711680;d=void 0!==d?d:1;b=0;c=this.object.geometry;c instanceof THREE.Geometry?b=3*c.faces.length:c instanceof THREE.BufferGeometry&&(b=c.attributes.normal.count);c=new THREE.BufferGeometry;b=new THREE.Float32Attribute(6*b,3);c.addAttribute("position",b);THREE.LineSegments.call(this,c,new THREE.LineBasicMaterial({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()};
 THREE.VertexNormalsHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.VertexNormalsHelper.prototype.constructor=THREE.VertexNormalsHelper;
-THREE.VertexNormalsHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Matrix3;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var e=this.object.matrixWorld,g=this.geometry.attributes.position,f=this.object.geometry;if(f instanceof THREE.Geometry)for(var h=f.vertices,k=f.faces,l=f=0,n=k.length;l<n;l++)for(var p=k[l],m=0,q=p.vertexNormals.length;m<q;m++){var s=p.vertexNormals[m];a.copy(h[p[d[m]]]).applyMatrix4(e);
-b.copy(s).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);g.setXYZ(f,a.x,a.y,a.z);f+=1;g.setXYZ(f,b.x,b.y,b.z);f+=1}else if(f instanceof THREE.BufferGeometry)for(d=f.attributes.position,h=f.attributes.normal,m=f=0,q=d.count;m<q;m++)a.set(d.getX(m),d.getY(m),d.getZ(m)).applyMatrix4(e),b.set(h.getX(m),h.getY(m),h.getZ(m)),b.applyMatrix3(c).normalize().multiplyScalar(this.size).add(a),g.setXYZ(f,a.x,a.y,a.z),f+=1,g.setXYZ(f,b.x,b.y,b.z),f+=1;g.needsUpdate=!0;return this}}();
-THREE.VertexTangentsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:255;d=void 0!==d?d:1;b=0;c=this.object.geometry;c instanceof THREE.Geometry?b=3*c.faces.length:c instanceof THREE.BufferGeometry&&(b=c.attributes.tangent.count);c=new THREE.BufferGeometry;b=new THREE.Float32Attribute(6*b,3);c.addAttribute("position",b);THREE.LineSegments.call(this,c,new THREE.LineBasicMaterial({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()};
-THREE.VertexTangentsHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.VertexTangentsHelper.prototype.constructor=THREE.VertexTangentsHelper;
-THREE.VertexTangentsHelper.prototype.update=function(a){var b=new THREE.Vector3,c=new THREE.Vector3;return function(){var a=["a","b","c"];this.object.updateMatrixWorld(!0);var e=this.object.matrixWorld,g=this.geometry.attributes.position,f=this.object.geometry;if(f instanceof THREE.Geometry)for(var h=f.vertices,k=f.faces,l=f=0,n=k.length;l<n;l++)for(var p=k[l],m=0,q=p.vertexTangents.length;m<q;m++){var s=p.vertexTangents[m];b.copy(h[p[a[m]]]).applyMatrix4(e);c.set(s.x,s.y,s.z);c.transformDirection(e).multiplyScalar(this.size).add(b);
-g.setXYZ(f,b.x,b.y,b.z);f+=1;g.setXYZ(f,c.x,c.y,c.z);f+=1}else if(f instanceof THREE.BufferGeometry)for(a=f.attributes.position,h=f.attributes.tangent,m=f=0,q=a.count;m<q;m++)b.set(a.getX(m),a.getY(m),a.getZ(m)).applyMatrix4(e),c.set(h.getX(m),h.getY(m),h.getZ(m)),c.transformDirection(e).multiplyScalar(this.size).add(b),g.setXYZ(f,b.x,b.y,b.z),f+=1,g.setXYZ(f,c.x,c.y,c.z),f+=1;g.needsUpdate=!0;return this}}();
+THREE.VertexNormalsHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Matrix3;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var e=this.object.matrixWorld,g=this.geometry.attributes.position,f=this.object.geometry;if(f instanceof THREE.Geometry)for(var h=f.vertices,k=f.faces,l=f=0,n=k.length;l<n;l++)for(var p=k[l],m=0,q=p.vertexNormals.length;m<q;m++){var t=p.vertexNormals[m];a.copy(h[p[d[m]]]).applyMatrix4(e);
+b.copy(t).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);g.setXYZ(f,a.x,a.y,a.z);f+=1;g.setXYZ(f,b.x,b.y,b.z);f+=1}else if(f instanceof THREE.BufferGeometry)for(d=f.attributes.position,h=f.attributes.normal,m=f=0,q=d.count;m<q;m++)a.set(d.getX(m),d.getY(m),d.getZ(m)).applyMatrix4(e),b.set(h.getX(m),h.getY(m),h.getZ(m)),b.applyMatrix3(c).normalize().multiplyScalar(this.size).add(a),g.setXYZ(f,a.x,a.y,a.z),f+=1,g.setXYZ(f,b.x,b.y,b.z),f+=1;g.needsUpdate=!0;return this}}();
 THREE.WireframeHelper=function(a,b){var c=void 0!==b?b:16777215;THREE.LineSegments.call(this,new THREE.WireframeGeometry(a.geometry),new THREE.LineBasicMaterial({color:c}));this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.WireframeHelper.prototype=Object.create(THREE.LineSegments.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={start:b,end: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)};

+ 7 - 24
docs/api/core/BufferGeometry.html

@@ -86,11 +86,6 @@
 		Set by [page:.fromGeometry]().
 		</div>
 
-		<h4>[page:BufferAttribute tangent] (itemSize: 3)</h4>
-		<div>
-		Stores the x, y, and z components of the tangent vector of each vertex in this geometry. Set by [page:.computeTangents]().
-		</div>
-
 		<h4>[page:BufferAttribute index] (itemSize: 3)</h4>
 		Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles," and works much the same as it does in [page:Geometry]: each triangle is associated with the index of three vertices. This attribute therefore stores the index of each vertex for each triangular face.
 
@@ -158,11 +153,6 @@
 		Morph vertices match number and order of primary vertices.
 		</div>
 
-		<h3>[property:boolean hasTangents]</h3>
-		<div>
-		True if BufferGeometry has tangents. Set in [page:.computeTangents].
-		</div>
-
 		<h2>Methods</h2>
 
 		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
@@ -178,7 +168,7 @@
 		<div>
 		Adds a draw call to this geometry; see the [page:BufferGeometry.drawcalls drawcalls] property for details.
 		</div>
-    
+
 		<h3>[method:null clearDrawCalls]( )</h3>
 		<div>
 		Clears all draw calls.
@@ -188,12 +178,12 @@
 		<div>
 		Bakes matrix transform directly into vertex coordinates.
 		</div>
-    
+
 		<h3>[method:null center] ()</h3>
 		<div>
 		Center the geometry based on the bounding box.
 		</div>
-    
+
 		<h3>[method:BufferGeometry rotateX] ( [page:Float radians] )</h3>
 		<div>
 		Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop
@@ -243,13 +233,6 @@
 		Computes vertex normals by averaging face normals.<br />
 		</div>
 
-		<h3>[method:null computeTangents]()</h3>
-		<div>
-		Computes vertex tangents.<br />
-		Based on [link:http://www.terathon.com/code/tangent.html]<br />
-		Geometry must have vertex [page:UV UVs] (layer 0 will be used).
-		</div>
-
 		<h3>[method:null computeBoundingBox]()</h3>
 		<div>
 		Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.<br />
@@ -306,18 +289,18 @@
 		<div>
 		Returns a raw object representation of the BufferGeometry.
 		</div>
-		
+
 		<h3>[method:BufferGeometry clone]()</h3>
 		<div>
 		Creates a clone of this BufferGeometry.
 		</div>
-		
+
 		<h3>[method:BufferGeometry copy]( [page:BufferGeometry bufferGeometry] )</h3>
 		<div>
 		Copies another BufferGeometry to this BufferGeometry.
 		</div>
-		
-		
+
+
 
 		<h2>Source</h2>
 

+ 2 - 7
docs/api/core/Face3.html

@@ -71,11 +71,6 @@
 		Array of 3 vertex colors.
 		</div>
 
-		<h3>[property:Array vertexTangents]</h3>
-		<div>
-		Array of 3 vertex tangents.
-		</div>
-
 
 		<h3>[property:Integer materialIndex]</h3>
 		<div>
@@ -88,8 +83,8 @@
 		<div>
 		Creates a new clone of the Face3 object.
 		</div>
-		
-		
+
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 15 - 32
docs/api/core/Geometry.html

@@ -117,10 +117,10 @@
 		// e.g.
 		geometry.skinIndices[15] = new THREE.Vector4(   0,   5,   9, 0 );
 		geometry.skinWeights[15] = new THREE.Vector4( 0.2, 0.5, 0.3, 0 );
-		
+
 		// corresponds with the following vertex
 		geometry.vertices[15];
-		
+
 		// these bones will be used like so:
 		skeleton.bones[0]; // weight of 0.2
 		skeleton.bones[5]; // weight of 0.5
@@ -141,48 +141,38 @@
 		<code>{ radius: float }</code>
 		</div>
 
-		<h3>[property:Boolean hasTangents]</h3>
-		<div>
-		True if geometry has tangents. Set in [page:Geometry Geometry.computeTangents].
-		</div>
-
 		<h3>[property:Boolean dynamic]</h3>
 		<div>
 		Set to *true* if attribute buffers will need to change in runtime (using "dirty" flags).<br/>
 		Unless set to true internal typed arrays corresponding to buffers will be deleted once sent to GPU.<br/>
 		Defaults to true.
 		</div>
-		
+
 		<h3>[property:Boolean verticesNeedUpdate]</h3>
 		<div>
 		Set to *true* if the vertices array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean elementsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the faces array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean uvsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the uvs array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean normalsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the normals array has been updated.
 		</div>
-		
-		<h3>[property:Boolean tangentsNeedUpdate]</h3>
-		<div>
-		Set to *true* if the tangents in the faces has been updated.
-		</div>
-		
+
 		<h3>[property:Boolean colorsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the colors array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean lineDistancesNeedUpdate]</h3>
 		<div>
 		Set to *true* if the linedistances array has been updated.
@@ -193,10 +183,10 @@
 		An array containing distances between vertices for Line geometries.
 		This is required for LinePieces/LineDashedMaterial to render correctly.
 		Line distances can also be generated with computeLineDistances.
-		</div> 
+		</div>
 
 		<h2>Methods</h2>
-		
+
 		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
 
 		<h3>[method:null applyMatrix]( [page:Matrix4 matrix] )</h3>
@@ -208,7 +198,7 @@
 		<div>
 		Center the geometry based on the bounding box.
 		</div>
-    
+
 		<h3>[method:Geometry rotateX] ( [page:Float radians] )</h3>
 		<div>
 		Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop
@@ -264,13 +254,6 @@
 		Computes morph normals.
 		</div>
 
-		<h3>[method:null computeTangents]()</h3>
-		<div>
-		Computes vertex tangents.<br />
-		Based on [link:http://www.terathon.com/code/tangent.html]<br />
-		Geometry must have vertex [page:UV UVs] (layer 0 will be used).
-		</div>
-
 		<h3>[method:null computeBoundingBox]()</h3>
 		<div>
 		Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.
@@ -280,7 +263,7 @@
 		<div>
 		Computes bounding sphere of the geometry, updating [page:Geometry Geometry.boundingSphere] attribute.
 		</div>
-		
+
 		<div>Neither bounding boxes or bounding spheres are computed by default. They need to be explicitly computed, otherwise they are *null*.</div>
 
 		<h3>[method:null merge]( [page:Geometry geometry], [page:Matrix4 matrix], [page:Integer materialIndexOffset] )</h3>
@@ -297,16 +280,16 @@
 		Normalize the geometry. <br />
 		Make the geometry centered and has a bounding sphere whose raidus equals to 1.0.
 		</div>
-		
+
 		<h3>[method:Geometry clone]()</h3>
 		<div>
 		Creates a new clone of the Geometry.
 		</div>
-		
+
 		<h3>[method:null dispose]()</h3>
 		<div>
 		Removes The object from memory. <br />
-		Don't forget to call this method when you remove a geometry because it can cause memory leaks. 
+		Don't forget to call this method when you remove a geometry because it can cause memory leaks.
 		</div>
 
 		<h3>[method:null computeLineDistances]()</h3>

+ 0 - 59
docs/api/extras/helpers/VertexTangentsHelper.html

@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:Line] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">Renders [page:ArrowHelper arrows] to visualize an object's vertex tangent vectors. Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or have been computed using [page:Geometry.computeTangents computeTangents]. </div>
-
-		<h2>Example</h2>
-
-		<code>
-		geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 );
-		material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
-		object = new THREE.Mesh( geometry, material );
-
-		edges = new THREE.VertexTangentsHelper( object, 2, 0x00ff00, 1 );
-
-		scene.add( object );
-		scene.add( edges );
-		</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]( [page:Object3D object], [page:Number size], [page:Color color], [page:Number linewidth] )</h3>
-		<div>object -- object for which to render vertex tangents
-		size -- size (length) of the arrows
-		color -- color of the arrows
-		linewidth -- width of the arrow lines
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<h3>[property:Object3D object]</h3>
-		<div>
-		The attached object
-		</div>
-
-
-		<h2>Methods</h2>
-
-
-		<h3>[method:null update]()</h3>
-		<div>Updates the vertex tangent preview arrows based on the new position and tangents of the object.</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 93
docs/api/lights/AreaLight.html

@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-        [page:Object3D] &rarr; [page:Light] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">This illuminates the scene from a complete surface. This light only works in the [page:WebGLDeferredRenderer deferredrenderer]. </div>
-
-
-		<h2>Example</h2>
-		<h2>Example</h2>
-
-		<div>[example:webgldeferred_arealights arealights ]</div>
-
-		<code>areaLight1 = new THREE.AreaLight( 0xffffff, 1 );
-areaLight1.position.set( 0.0001, 10.0001, -18.5001 );
-areaLight1.rotation.set( -0.74719, 0.0001, 0.0001 );
-areaLight1.width = 10;
-areaLight1.height = 1;
-
-scene.add( areaLight1 );</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]( [page:Integer hex], [page:Float intensity])</h3>
-		<div>
-		[page:Integer hex] — Numeric value of the RGB component of the color.<br />
-		[page:Float intensity] — Numeric value of the light's strength/intensity.
-		</div>
-		<div>
-		This creates a arealight with color.
-		</div>
-
-
-		<h2>Properties</h2>
-
-
-
-		<h3>[property:Vector3 right]</h3>
-		<div>
-		Sets or gets an unit vector that indicates the right side of the light. This is calculated in local space.
-		</div>
-
-		<h3>[property:Vector3 normal]</h3>
-		<div>
-		Sets or gets an unit vectorSets or gets an unit vector that indicates the right side of the light. This is calculated in local space.
-		</div>
-
-		<h3>[property:number height]</h3>
-		<div>
-		Sets or gets the height of the illuminating plane.
-		</div>
-
-		<h3>[property:number width]</h3>
-		<div>
-		Sets or gets the width of the illuminating plane.
-		</div>
-
-		<h3>[property:Float intensity]</h3>
-		<div>
-		Light's intensity.<br />
-		Default — *1.0*.
-		</div>
-
-		<h3>[property:number constantAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in constant space. This is independant of the distance of the light.
-		</div>
-
-		<h3>[property:number linearAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in linear space. This increases the attenuation linearly with the distance from the light.
-		</div>
-
-		<h3>[property:number quadraticAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in quadratic space. This increases the attenuation quadraticly with the distance from the light.
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 8
docs/api/loaders/Loader.html

@@ -43,14 +43,6 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Boolean needsTangents]( [page:Array materials] )</h3>
-		<div>
-		[page:Array materials] — an array of [page:Material]
-		</div>
-		<div>
-		Checks if the loaded object needs tangents based on its materials.
-		</div>
-
 		<h3>[method:Material createMaterial]( [page:object m], [page:string texturePath] )</h3>
 		<div>
 		[page:Object m] — The parameters to create the material. <br />

+ 0 - 2
docs/list.js

@@ -37,7 +37,6 @@ var list = {
 
 		"Lights": [
 			[ "AmbientLight", "api/lights/AmbientLight" ],
-			[ "AreaLight", "api/lights/AreaLight" ],
 			[ "DirectionalLight", "api/lights/DirectionalLight" ],
 			[ "HemisphereLight", "api/lights/HemisphereLight" ],
 			[ "Light", "api/lights/Light" ],
@@ -231,7 +230,6 @@ var list = {
 			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
 			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ],
 			[ "VertexNormalsHelper", "api/extras/helpers/VertexNormalsHelper" ],
-			[ "VertexTangentsHelper", "api/extras/helpers/VertexTangentsHelper" ],
 			[ "WireframeHelper", "api/extras/helpers/WireframeHelper" ]
 		],
 

+ 11 - 0
editor/js/Sidebar.Geometry.BufferGeometry.js

@@ -17,6 +17,17 @@ Sidebar.Geometry.BufferGeometry = function ( signals ) {
 			container.clear();
 			container.setDisplay( 'block' );
 
+			var index = geometry.index;
+
+			if ( index !== null ) {
+
+				var panel = new UI.Panel();
+				panel.add( new UI.Text( 'index' ).setWidth( '90px' ) );
+				panel.add( new UI.Text( ( index.count ).format() ).setFontSize( '12px' ) );
+				container.add( panel );
+
+			}
+
 			var attributes = geometry.attributes;
 
 			for ( var name in attributes ) {

+ 0 - 20
editor/js/Sidebar.Geometry.Modifiers.js

@@ -31,26 +31,6 @@ Sidebar.Geometry.Modifiers = function ( signals, object ) {
 
 	container.add( button );
 
-	// Convert to Geometry/BufferGeometry
-
-	var isBufferGeometry = geometry instanceof THREE.BufferGeometry;
-
-	if ( geometry instanceof THREE.Geometry ) {
-
-		var button = new UI.Button( 'Convert to BufferGeometry' );
-		button.onClick( function () {
-
-			if ( confirm( 'Are you sure?' ) === false ) return;
-
-			object.geometry = new THREE.BufferGeometry().fromGeometry( object.geometry );
-
-			signals.geometryChanged.dispatch( object );
-
-		} );
-		container.add( button );
-
-	}
-
 	//
 
 	return container;

+ 13 - 0
editor/js/Sidebar.Geometry.js

@@ -25,6 +25,7 @@ Sidebar.Geometry = function ( editor ) {
 
 		'Actions': 'Actions',
 		'Center': 'Center',
+		'Convert': 'Convert',
 		'Flatten': 'Flatten'
 
 	} );
@@ -55,6 +56,18 @@ Sidebar.Geometry = function ( editor ) {
 
 				break;
 
+			case 'Convert':
+
+				if ( geometry instanceof THREE.Geometry ) {
+
+					object.geometry = new THREE.BufferGeometry().fromGeometry( geometry );
+
+					signals.geometryChanged.dispatch( object );
+
+				}
+
+				break;
+
 			case 'Flatten':
 
 				geometry.applyMatrix( object.matrix );

+ 1 - 89
editor/js/libs/tern-threejs/threejs.js

@@ -225,10 +225,6 @@
           "!type": "[]",
           "!doc": "Array of morph targets. Each morph target is a Javascript object:\n\t\t<code>{ name: \"targetName\", vertices: [ new THREE.Vertex(), ... ] }</code>\n\t\tMorph vertices match number and order of primary vertices."
         },
-        "hasTangents": {
-          "!type": "boolean",
-          "!doc": "True if BufferGeometry has tangents. Set in [page:.computeTangents]."
-        },
         "addAttribute": {
           "!type": "null",
           "!doc": "Adds an attribute to this geometry. Use this rather than the attributes property, \n\t\tbecause an internal array of attributes is maintained to speed up iterating over\n\t\tattributes."
@@ -245,10 +241,6 @@
           "!type": "fn()",
           "!doc": "Computes vertex normals by averaging face normals.<br>"
         },
-        "computeTangents": {
-          "!type": "fn()",
-          "!doc": "Computes vertex tangents.<br>\n\t\tBased on [link:http://www.terathon.com/code/tangent.html]<br>\n\t\tGeometry must have vertex [page:UV UVs] (layer 0 will be used)."
-        },
         "computeBoundingBox": {
           "!type": "fn()",
           "!doc": "Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.<br>\n\t\tBounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are *null*."
@@ -374,10 +366,6 @@
           "!type": "[]",
           "!doc": "Array of 3 vertex colors."
         },
-        "vertexTangents": {
-          "!type": "[]",
-          "!doc": "Array of 3 vertex tangents."
-        },
         "materialIndex": {
           "!type": "number",
           "!doc": "Material index (points to [page:MeshFaceMaterial MeshFaceMaterial.materials])."
@@ -445,10 +433,6 @@
           "!type": "object",
           "!doc": "Bounding sphere.\n\t\t<code>{ radius: float }</code>"
         },
-        "hasTangents": {
-          "!type": "bool",
-          "!doc": "True if geometry has tangents. Set in [page:Geometry Geometry.computeTangents]."
-        },
         "dynamic": {
           "!type": "bool",
           "!doc": "Set to *true* if attribute buffers will need to change in runtime (using \"dirty\" flags).<br>\n\t\tUnless set to true internal typed arrays corresponding to buffers will be deleted once sent to GPU.<br>\n\t\tDefaults to true."
@@ -469,10 +453,6 @@
           "!type": "bool",
           "!doc": "Set to *true* if the normals array has been updated."
         },
-        "tangentsNeedUpdate": {
-          "!type": "bool",
-          "!doc": "Set to *true* if the tangents in the faces has been updated."
-        },
         "colorsNeedUpdate": {
           "!type": "bool",
           "!doc": "Set to *true* if the colors array has been updated."
@@ -501,10 +481,6 @@
           "!type": "fn()",
           "!doc": "Computes morph normals."
         },
-        "computeTangents": {
-          "!type": "fn()",
-          "!doc": "Computes vertex tangents.<br>\n\t\tBased on [link:http://www.terathon.com/code/tangent.html]<br>\n\t\tGeometry must have vertex [page:UV UVs] (layer 0 will be used)."
-        },
         "computeBoundingBox": {
           "!type": "fn()",
           "!doc": "Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute."
@@ -2005,22 +1981,6 @@
       "!doc": "Renders [page:ArrowHelper arrows] to visualize an object's vertex normal vectors. Requires that normals have been specified in a [page:BufferAttribute custom attribute] or have been calculated using [page:Geometry.computeVertexNormals computeVertexNormals].",
       "!type": "fn(object: +THREE.Object3D, size: number, color: +THREE.Color, linewidth: number)"
     },
-    "VertexTangentsHelper": {
-      "!url": "http://threejs.org/docs/#Reference/extras/helpers/VertexTangentsHelper",
-      "prototype": {
-        "!proto": "THREE.Line.prototype",
-        "object": {
-          "!type": "+THREE.Object3D",
-          "!doc": "The attached object"
-        },
-        "update": {
-          "!type": "fn()",
-          "!doc": "Updates the vertex tangent preview arrows based on the new position and tangents of the object."
-        }
-      },
-      "!doc": "Renders [page:ArrowHelper arrows] to visualize an object's vertex tangent vectors. Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or have been computed using [page:Geometry.computeTangents computeTangents].",
-      "!type": "fn(object: +THREE.Object3D, size: number, color: +THREE.Color, linewidth: number)"
-    },
     "WireframeHelper": {
       "!url": "http://threejs.org/docs/#Reference/extras/helpers/WireframeHelper",
       "prototype": {
@@ -2117,46 +2077,6 @@
       "!doc": "This light's color gets applied to all the objects in the scene globally.",
       "!type": "fn(hex: number)"
     },
-    "AreaLight": {
-      "!url": "http://threejs.org/docs/#Reference/lights/AreaLight",
-      "prototype": {
-        "!proto": "THREE.Light.prototype",
-        "right": {
-          "!type": "+THREE.Vector3",
-          "!doc": "Sets or gets an unit vector that indicates the right side of the light. This is calculated in local space."
-        },
-        "normal": {
-          "!type": "+THREE.Vector3",
-          "!doc": "Sets or gets an unit vectorSets or gets an unit vector that indicates the right side of the light. This is calculated in local space."
-        },
-        "height": {
-          "!type": "number",
-          "!doc": "Sets or gets the height of the illuminating plane."
-        },
-        "width": {
-          "!type": "number",
-          "!doc": "Sets or gets the width of the illuminating plane."
-        },
-        "intensity": {
-          "!type": "number",
-          "!doc": "Light's intensity.<br>\n\t\tDefault — *1.0*."
-        },
-        "constantAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in constant space. This is independant of the distance of the light."
-        },
-        "linearAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in linear space. This increases the attenuation linearly with the distance from the light."
-        },
-        "quadraticAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in linear space. This increases the attenuation quadratic with the distance from the light."
-        }
-      },
-      "!doc": "This illuminates the scene from a complete surface. This light only works in the [page:WebGLDeferredRenderer deferredrenderer].",
-      "!type": "fn(hex: number, intensity: number)"
-    },
     "DirectionalLight": {
       "!url": "http://threejs.org/docs/#Reference/lights/DirectionalLight",
       "prototype": {
@@ -2544,10 +2464,6 @@
           "!type": "fn(json: object, texturePath: string) -> +THREE.Object3D",
           "!doc": "Parse a <em>JSON</em> structure and return an [page:Object] containing the parsed .[page:Geometry] and .[page:Array materials]."
         },
-        "needsTangents": {
-          "!type": "fn(materials: []) -> bool",
-          "!doc": "Checks if the loaded object needs tangents based on its materials."
-        },
         "updateProgress": {
           "!type": "fn(progress: object)",
           "!doc": "Updates the DOM object with the progress made."
@@ -2599,10 +2515,6 @@
           "!type": "string",
           "!doc": "The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS."
         },
-        "needsTangents": {
-          "!type": "fn(materials: []) -> bool",
-          "!doc": "Checks if the loaded object needs tangents based on its materials."
-        },
         "updateProgress": {
           "!type": "fn(progress: object)",
           "!doc": "Updates the DOM object with the progress made."
@@ -6025,4 +5937,4 @@
 }
     };
   });
-});
+});

+ 1 - 6
examples/index.html

@@ -297,7 +297,6 @@
 				"webgl_materials_envmaps",
 				"webgl_materials_grass",
 				"webgl_materials_lightmap",
-				"webgl_materials_normaldisplacementmap",
 				"webgl_materials_normalmap",
 				"webgl_materials_parallaxmap",
 				"webgl_materials_shaders_fresnel",
@@ -345,6 +344,7 @@
 				"webgl_postprocessing_glitch",
 				"webgl_postprocessing_godrays",
 				"webgl_postprocessing_ssao",
+				"webgl_raycast_texture",
 				"webgl_rtt",
 				"webgl_sandbox",
 				"webgl_shader",
@@ -389,11 +389,6 @@
 				"webgl_custom_attributes_particles2",
 				"webgl_custom_attributes_particles3"
 			],
-			"webgldeferred": [
-				"webgldeferred_animation",
-				"webgldeferred_arealights",
-				"webgldeferred_pointlights"
-			],
 			"vr": [
 				"vr_cubes",
 				"vr_video"

+ 187 - 0
examples/js/BufferGeometryUtils.js

@@ -0,0 +1,187 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.BufferGeometryUtils = {
+
+	computeTangents: function ( geometry ) {
+
+		var index = geometry.index;
+		var attributes = geometry.attributes;
+
+		// based on http://www.terathon.com/code/tangent.html
+		// (per vertex tangents)
+
+		if ( index === null ||
+			 attributes.position === undefined ||
+			 attributes.normal === undefined ||
+			 attributes.uv === undefined ) {
+
+			console.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' );
+			return;
+
+		}
+
+		var indices = index.array;
+		var positions = attributes.position.array;
+		var normals = attributes.normal.array;
+		var uvs = attributes.uv.array;
+
+		var nVertices = positions.length / 3;
+
+		if ( attributes.tangent === undefined ) {
+
+			geometry.addAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );
+
+		}
+
+		var tangents = attributes.tangent.array;
+
+		var tan1 = [], tan2 = [];
+
+		for ( var k = 0; k < nVertices; k ++ ) {
+
+			tan1[ k ] = new THREE.Vector3();
+			tan2[ k ] = new THREE.Vector3();
+
+		}
+
+		var vA = new THREE.Vector3(),
+			vB = new THREE.Vector3(),
+			vC = new THREE.Vector3(),
+
+			uvA = new THREE.Vector2(),
+			uvB = new THREE.Vector2(),
+			uvC = new THREE.Vector2(),
+
+			sdir = new THREE.Vector3(),
+			tdir = new THREE.Vector3();
+
+		function handleTriangle( a, b, c ) {
+
+			vA.fromArray( positions, a * 3 );
+			vB.fromArray( positions, b * 3 );
+			vC.fromArray( positions, c * 3 );
+
+			uvA.fromArray( uvs, a * 2 );
+			uvB.fromArray( uvs, b * 2 );
+			uvC.fromArray( uvs, c * 2 );
+
+			var x1 = vB.x - vA.x;
+			var x2 = vC.x - vA.x;
+
+			var y1 = vB.y - vA.y;
+			var y2 = vC.y - vA.y;
+
+			var z1 = vB.z - vA.z;
+			var z2 = vC.z - vA.z;
+
+			var s1 = uvB.x - uvA.x;
+			var s2 = uvC.x - uvA.x;
+
+			var t1 = uvB.y - uvA.y;
+			var t2 = uvC.y - uvA.y;
+
+			var r = 1.0 / ( s1 * t2 - s2 * t1 );
+
+			sdir.set(
+				( t2 * x1 - t1 * x2 ) * r,
+				( t2 * y1 - t1 * y2 ) * r,
+				( t2 * z1 - t1 * z2 ) * r
+			);
+
+			tdir.set(
+				( s1 * x2 - s2 * x1 ) * r,
+				( s1 * y2 - s2 * y1 ) * r,
+				( s1 * z2 - s2 * z1 ) * r
+			);
+
+			tan1[ a ].add( sdir );
+			tan1[ b ].add( sdir );
+			tan1[ c ].add( sdir );
+
+			tan2[ a ].add( tdir );
+			tan2[ b ].add( tdir );
+			tan2[ c ].add( tdir );
+
+		}
+
+		var groups = geometry.groups;
+
+		if ( groups.length === 0 ) {
+
+			groups = [ {
+				start: 0,
+				count: indices.length
+			} ];
+
+		}
+
+		for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
+
+			var group = groups[ j ];
+
+			var start = group.start;
+			var count = group.count;
+
+			for ( var i = start, il = start + count; i < il; i += 3 ) {
+
+				handleTriangle(
+					indices[ i + 0 ],
+					indices[ i + 1 ],
+					indices[ i + 2 ]
+				);
+
+			}
+
+		}
+
+		var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
+		var n = new THREE.Vector3(), n2 = new THREE.Vector3();
+		var w, t, test;
+
+		function handleVertex( v ) {
+
+			n.fromArray( normals, v * 3 );
+			n2.copy( n );
+
+			t = tan1[ v ];
+
+			// Gram-Schmidt orthogonalize
+
+			tmp.copy( t );
+			tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
+
+			// Calculate handedness
+
+			tmp2.crossVectors( n2, t );
+			test = tmp2.dot( tan2[ v ] );
+			w = ( test < 0.0 ) ? - 1.0 : 1.0;
+
+			tangents[ v * 4 ] = tmp.x;
+			tangents[ v * 4 + 1 ] = tmp.y;
+			tangents[ v * 4 + 2 ] = tmp.z;
+			tangents[ v * 4 + 3 ] = w;
+
+		}
+
+		for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
+
+			var group = groups[ j ];
+
+			var start = group.start;
+			var count = group.count;
+
+			for ( var i = start, il = start + count; i < il; i += 3 ) {
+
+				handleVertex( indices[ i + 0 ] );
+				handleVertex( indices[ i + 1 ] );
+				handleVertex( indices[ i + 2 ] );
+
+			}
+
+		}
+
+	}
+
+};

+ 0 - 1104
examples/js/ShaderDeferred.js

@@ -1,1104 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author MPanknin / http://www.redplant.de/
- * @author benaadams / http://blog.illyriad.co.uk/
- *
- */
-
-
-THREE.DeferredShaderChunk = {
-
-	// decode float to vec3
-
-	unpackFloat: [
-
-		"vec3 float_to_vec3( float data ) {",
-
-			"vec3 uncompressed;",
-			"uncompressed.x = fract( data );",
-			"float zInt = floor( data / 255.0 );",
-			"uncompressed.z = fract( zInt / 255.0 );",
-			"uncompressed.y = fract( floor( data - ( zInt * 255.0 ) ) / 255.0 );",
-			"return uncompressed;",
-
-		"}"
-
-	].join( "\n" ),
-
-	computeVertexPositionVS: [
-
-		"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-		"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-		"float z = normalDepth.w;",
-
-		"if ( z == 0.0 ) discard;",
-
-		"vec2 xy = texCoord * 2.0 - 1.0;",
-
-		"vec4 vertexPositionProjected = vec4( xy, z, 1.0 );",
-		"vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;",
-		"vertexPositionVS.xyz /= vertexPositionVS.w;",
-		"vertexPositionVS.w = 1.0;"
-
-	].join( "\n" ),
-
-	computeNormal: [
-
-		"vec3 normal = normalDepth.xyz * 2.0 - 1.0;"
-
-	].join( "\n" ),
-
-	unpackColorMap: [
-
-		"vec4 colorMap = texture2D( samplerColor, texCoord );",
-
-		"vec3 albedo = float_to_vec3( abs( colorMap.x ) );",
-		"vec3 specularColor = float_to_vec3( abs( colorMap.y ) );",
-		"float shininess = abs( colorMap.z );",
-		"float wrapAround = sign( colorMap.z );",
-		"float additiveSpecular = sign( colorMap.y );"
-
-	].join( "\n" ),
-
-	computeDiffuse: [
-
-		"float dotProduct = dot( normal, lightVector );",
-		"float diffuseFull = max( dotProduct, 0.0 );",
-
-		"vec3 diffuse;",
-
-		"if ( wrapAround < 0.0 ) {",
-
-			// wrap around lighting
-
-			"float diffuseHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
-
-			"const vec3 wrapRGB = vec3( 1.0, 1.0, 1.0 );",
-			"diffuse = mix( vec3( diffuseFull ), vec3( diffuseHalf ), wrapRGB );",
-
-		"} else {",
-
-			// simple lighting
-
-			"diffuse = vec3( diffuseFull );",
-
-		"}"
-
-	].join( "\n" ),
-
-	computeSpecular: [
-
-		"vec3 halfVector = normalize( lightVector - normalize( vertexPositionVS.xyz ) );",
-		"float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
-
-		// simple specular
-
-		//"vec3 specular = specularColor * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse;",
-
-		// physically based specular
-
-		"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
-
-		"vec3 schlick = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, halfVector ), 5.0 );",
-		"vec3 specular = schlick * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse * specularNormalization;"
-
-	].join( "\n" ),
-
-	combine: [
-
-		"vec3 light = lightIntensity * lightColor;",
-		"gl_FragColor = vec4( light * ( albedo * diffuse + specular ), attenuation );"
-
-	].join( "\n" )
-
-};
-
-THREE.ShaderDeferred = {
-
-	"color" : {
-
-		uniforms: THREE.UniformsUtils.merge( [
-
-			THREE.UniformsLib[ "common" ],
-			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "shadowmap" ],
-
-			{
-				"emissive" :  { type: "c", value: new THREE.Color( 0x000000 ) },
-				"specular" :  { type: "c", value: new THREE.Color( 0x111111 ) },
-				"shininess":  { type: "f", value: 30 },
-				"wrapAround": 		{ type: "f", value: 1 },
-				"additiveSpecular": { type: "f", value: 1 },
-
-				"samplerNormalDepth": { type: "t", value: null },
-				"viewWidth": 		{ type: "f", value: 800 },
-				"viewHeight": 		{ type: "f", value: 600 }
-			}
-
-		] ),
-
-		fragmentShader : [
-
-			"uniform vec3 diffuse;",
-			"uniform vec3 specular;",
-			"uniform vec3 emissive;",
-			"uniform float shininess;",
-			"uniform float wrapAround;",
-			"uniform float additiveSpecular;",
-
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "color_pars_fragment" ],
-			THREE.ShaderChunk[ "uv_pars_fragment" ],
-			THREE.ShaderChunk[ "uv2_pars_fragment" ],
-			THREE.ShaderChunk[ "map_pars_fragment" ],
-
-			"#ifdef USE_ENVMAP",
-
-				"varying vec3 vWorldPosition;",
-
-				"uniform float reflectivity;",
-				"uniform samplerCube envMap;",
-				"uniform float flipEnvMap;",
-				"uniform int combine;",
-
-				"uniform bool useRefract;",
-				"uniform float refractionRatio;",
-
-				"uniform sampler2D samplerNormalDepth;",
-				"uniform float viewHeight;",
-				"uniform float viewWidth;",
-
-			"#endif",
-
-			THREE.ShaderChunk[ "fog_pars_fragment" ],
-			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
-			THREE.ShaderChunk[ "specularmap_pars_fragment" ],
-
-			"const float unit = 255.0/256.0;",
-
-			"float vec3_to_float( vec3 data ) {",
-
-				"highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;",
-				"return compressed;",
-
-			"}",
-
-			"void main() {",
-
-				"const float opacity = 1.0;",
-
-				"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" ],
-				THREE.ShaderChunk[ "specularmap_fragment" ],
-				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "color_fragment" ],
-
-				"outgoingLight = diffuseColor.rgb;",
-
-				"#ifdef USE_ENVMAP",
-
-					"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-					"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-					"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
-
-					"vec3 reflectVec;",
-
-					"vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
-
-					"if ( useRefract ) {",
-
-						"reflectVec = refract( cameraToVertex, normal, refractionRatio );",
-
-					"} else { ",
-
-						"reflectVec = reflect( cameraToVertex, normal );",
-
-					"}",
-
-					"#ifdef DOUBLE_SIDED",
-
-						"float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
-						"vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
-
-					"#else",
-
-						"vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
-
-					"#endif",
-
-					"cubeColor.xyz = inputToLinear( cubeColor.xyz );",
-
-					"if ( combine == 1 ) {",
-
-						"outgoingLight = mix( outgoingLight, cubeColor.xyz, specularStrength * reflectivity );",
-
-					"} else if ( combine == 2 ) {",
-
-						"outgoingLight += cubeColor.xyz * specularStrength * reflectivity;",
-
-					"} else {",
-
-						"outgoingLight = mix( outgoingLight, diffuseColor.xyz * cubeColor.xyz, specularStrength * reflectivity );",
-
-					"}",
-
-				"#endif",
-
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
-				THREE.ShaderChunk[ "fog_fragment" ],
-
-				//
-
-				"const float compressionScale = 0.999;",
-
-				//
-
-				"vec3 diffuseMapColor;",
-
-				"#ifdef USE_MAP",
-
-					"diffuseMapColor = texelColor.xyz;",
-
-				"#else",
-
-					"diffuseMapColor = vec3( 1.0 );",
-
-				"#endif",
-
-				// diffuse color
-
-				"gl_FragColor.x = vec3_to_float( compressionScale * outgoingLight );",
-
-				// specular color
-
-				"if ( additiveSpecular < 0.0 ) {",
-
-					"gl_FragColor.y = vec3_to_float( compressionScale * specular );",
-
-				"} else {",
-
-					"gl_FragColor.y = vec3_to_float( compressionScale * specular * diffuseMapColor );",
-
-				"}",
-
-				"gl_FragColor.y *= additiveSpecular;",
-
-				// shininess
-
-				"gl_FragColor.z = wrapAround * shininess;",
-
-				// emissive color
-
-				"#ifdef USE_COLOR",
-
-					"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor * vColor );",
-
-				"#else",
-
-					"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor );",
-
-				"#endif",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "uv_pars_vertex" ],
-			THREE.ShaderChunk[ "uv2_pars_vertex" ],
-			THREE.ShaderChunk[ "color_pars_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
-
-			"#ifdef USE_ENVMAP",
-
-				"varying vec3 vWorldPosition;",
-
-			"#endif",
-
-			"void main() {",
-
-				THREE.ShaderChunk[ "uv_vertex" ],
-				THREE.ShaderChunk[ "uv2_vertex" ],
-				THREE.ShaderChunk[ "color_vertex" ],
-
-				THREE.ShaderChunk[ "skinbase_vertex" ],
-
-				THREE.ShaderChunk[ "morphtarget_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
-				THREE.ShaderChunk[ "default_vertex" ],
-
-				THREE.ShaderChunk[ "worldpos_vertex" ],
-				THREE.ShaderChunk[ "shadowmap_vertex" ],
-
-				"#ifdef USE_ENVMAP",
-
-					"vWorldPosition = worldPosition.xyz;",
-
-				"#endif",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"normalDepth" : {
-
-		uniforms: {
-
-			bumpMap: 	  { type: "t", value: null },
-			bumpScale:	  { type: "f", value: 1 },
-			offsetRepeat: { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }
-
-		},
-
-		fragmentShader : [
-
-			"#ifdef USE_BUMPMAP",
-
-				"varying vec2 vUv;",
-				"varying vec3 vViewPosition;",
-
-				THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
-
-			"#endif",
-
-			"varying vec3 normalView;",
-			"varying vec4 clipPos;",
-
-			"void main() {",
-
-				"vec3 normal = normalize( normalView );",
-
-				"#ifdef USE_BUMPMAP",
-
-					"normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",
-
-				"#endif",
-
-				"gl_FragColor.xyz = normal * 0.5 + 0.5;",
-				"gl_FragColor.w = clipPos.z / clipPos.w;",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"varying vec3 normalView;",
-			"varying vec4 clipPos;",
-
-			"#ifdef USE_BUMPMAP",
-
-				"varying vec2 vUv;",
-				"varying vec3 vViewPosition;",
-
-				"uniform vec4 offsetRepeat;",
-
-			"#endif",
-
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-
-			"void main() {",
-
-				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" ],
-
-				"normalView = normalize( normalMatrix * objectNormal );",
-
-				"#ifdef USE_BUMPMAP",
-
-					"vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
-					"vViewPosition = -mvPosition.xyz;",
-
-				"#endif",
-
-				"clipPos = gl_Position;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"composite" : {
-
-		uniforms: {
-
-			samplerLight: 	{ type: "t", value: null },
-			brightness:		{ type: "f", value: 1 }
-
-		},
-
-		fragmentShader : [
-
-			"varying vec2 texCoord;",
-			"uniform sampler2D samplerLight;",
-			"uniform float brightness;",
-
-			// tonemapping operators
-			// based on John Hable's HLSL snippets
-			// from http://filmicgames.com/archives/75
-
-			"#ifdef TONEMAP_UNCHARTED",
-
-				"const float A = 0.15;",
-				"const float B = 0.50;",
-				"const float C = 0.10;",
-				"const float D = 0.20;",
-				"const float E = 0.02;",
-				"const float F = 0.30;",
-				"const float W = 11.2;",
-
-				"vec3 Uncharted2Tonemap( vec3 x ) {",
-
-				   "return ( ( x * ( A * x + C * B ) + D * E ) / ( x * ( A * x + B ) + D * F ) ) - E / F;",
-
-				"}",
-
-			"#endif",
-
-			"void main() {",
-
-				"vec3 inColor = texture2D( samplerLight, texCoord ).xyz;",
-				"inColor *= brightness;",
-
-				"vec3 outColor;",
-
-				"#if defined( TONEMAP_SIMPLE )",
-
-					"outColor = sqrt( inColor );",
-
-				"#elif defined( TONEMAP_LINEAR )",
-
-					// simple linear to gamma conversion
-
-					"outColor = pow( inColor, vec3( 1.0 / 2.2 ) );",
-
-				"#elif defined( TONEMAP_REINHARD )",
-
-					// Reinhard operator
-
-					"inColor = inColor / ( 1.0 + inColor );",
-					"outColor = pow( inColor, vec3( 1.0 / 2.2 ) );",
-
-				"#elif defined( TONEMAP_FILMIC )",
-
-					// filmic operator by Jim Hejl and Richard Burgess-Dawson
-
-					"vec3 x = max( vec3( 0.0 ), inColor - 0.004 );",
-					"outColor = ( x * ( 6.2 * x + 0.5 ) ) / ( x * ( 6.2 * x + 1.7 ) + 0.06 );",
-
-				"#elif defined( TONEMAP_UNCHARTED )",
-
-					// tonemapping operator from Uncharted 2 by John Hable
-
-					"float ExposureBias = 2.0;",
-					"vec3 curr = Uncharted2Tonemap( ExposureBias * inColor );",
-
-					"vec3 whiteScale = vec3( 1.0 ) / Uncharted2Tonemap( vec3( W ) );",
-					"vec3 color = curr * whiteScale;",
-
-					"outColor = pow( color, vec3( 1.0 / 2.2 ) );",
-
-				"#else",
-
-					"outColor = inColor;",
-
-				"#endif",
-
-				"gl_FragColor = vec4( outColor, 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"varying vec2 texCoord;",
-
-			"void main() {",
-
-				"vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );",
-				"texCoord = pos.xy * vec2( 0.5 ) + 0.5;",
-				"gl_Position = pos;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"pointLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-			lightRadius: 	{ type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColor;",
-			"uniform vec3 lightPositionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-
-				// bail out early when pixel outside of light sphere
-
-				"vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;",
-				"float distance = length( lightVector );",
-
-				"if ( distance > lightRadius ) discard;",
-
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"lightVector = normalize( lightVector );",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"float cutoff = 0.3;",
-				"float denom = distance / lightRadius + 1.0;",
-				"float attenuation = 1.0 / ( denom * denom );",
-				"attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );",
-				"attenuation = max( attenuation, 0.0 );",
-				"attenuation *= attenuation;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// sphere proxy needs real position
-
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-				"gl_Position = projectionMatrix * mvPosition;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"spotLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS : { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-			lightDistance: 	{ type: "f", value: 1.0 },
-			lightAngle: 	{ type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform vec3 lightPositionVS;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform float lightAngle;",
-			"uniform float lightIntensity;",
-			"uniform vec3 lightColor;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
-
-				"float rho = dot( lightDirectionVS, lightVector );",
-				"float rhoMax = cos( lightAngle * 0.5 );",
-
-				"if ( rho <= rhoMax ) discard;",
-
-				"float theta = rhoMax + 0.0001;",
-				"float phi = rhoMax + 0.05;",
-				"float falloff = 4.0;",
-
-				"float spot = 0.0;",
-
-				"if ( rho >= phi ) {",
-
-					"spot = 1.0;",
-
-				"} else if ( rho <= theta ) {",
-
-					"spot = 0.0;",
-
-				"} else { ",
-
-					"spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
-
-				"}",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-
-				"diffuse *= spot;",
-
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"const float attenuation = 1.0;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"directionalLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColor;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = lightDirectionVS;",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"const float attenuation = 1.0;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"hemisphereLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColorSky: 	  { type: "c", value: new THREE.Color( 0x000000 ) },
-			lightColorGround: { type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity:   { type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColorSky;",
-			"uniform vec3 lightColorGround;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = lightDirectionVS;",
-
-				// diffuse
-
-				"float dotProduct = dot( normal, lightVector );",
-				"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
-
-				"vec3 hemiColor = mix( lightColorGround, lightColorSky, hemiDiffuseWeight );",
-
-				"vec3 diffuse = hemiColor;",
-
-				// specular (sky light)
-
-				"vec3 hemiHalfVectorSky = normalize( lightVector - vertexPositionVS.xyz );",
-				"float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
-				"float hemiSpecularWeightSky = max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",
-
-				// specular (ground light)
-
-				"vec3 lVectorGround = -lightVector;",
-
-				"vec3 hemiHalfVectorGround = normalize( lVectorGround - vertexPositionVS.xyz );",
-				"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
-				"float hemiSpecularWeightGround = max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",
-
-				"float dotProductGround = dot( normal, lVectorGround );",
-
-				"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
-
-				"vec3 schlickSky = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, hemiHalfVectorSky ), 5.0 );",
-				"vec3 schlickGround = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
-				"vec3 specular = hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
-
-				// combine
-
-				"gl_FragColor = vec4( lightIntensity * ( albedo * diffuse + specular ), 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"areaLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightNormalVS: 	 { type: "v3", value: new THREE.Vector3( 0, - 1, 0 ) },
-			lightRightVS:  	 { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
-			lightUpVS:  	 { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
-
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-
-			lightWidth:  { type: "f", value: 1.0 },
-			lightHeight: { type: "f", value: 1.0 },
-
-			constantAttenuation:  { type: "f", value: 1.5 },
-			linearAttenuation:    { type: "f", value: 0.5 },
-			quadraticAttenuation: { type: "f", value: 0.1 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform vec3 lightPositionVS;",
-			"uniform vec3 lightNormalVS;",
-			"uniform vec3 lightRightVS;",
-			"uniform vec3 lightUpVS;",
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightWidth;",
-			"uniform float lightHeight;",
-
-			"uniform float constantAttenuation;",
-			"uniform float linearAttenuation;",
-			"uniform float quadraticAttenuation;",
-
-			"uniform float lightIntensity;",
-			"uniform vec3 lightColor;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"vec3 projectOnPlane( vec3 point, vec3 planeCenter, vec3 planeNorm ) {",
-
-				"return point - dot( point - planeCenter, planeNorm ) * planeNorm;",
-
-			"}",
-
-			"bool sideOfPlane( vec3 point, vec3 planeCenter, vec3 planeNorm ) {",
-
-				"return ( dot( point - planeCenter, planeNorm ) >= 0.0 );",
-
-			"}",
-
-			"vec3 linePlaneIntersect( vec3 lp, vec3 lv, vec3 pc, vec3 pn ) {",
-
-				"return lp + lv * ( dot( pn, pc - lp ) / dot( pn, lv ) );",
-
-			"}",
-
-			"float calculateAttenuation( float dist ) {",
-
-				"return ( 1.0 / ( constantAttenuation + linearAttenuation * dist + quadraticAttenuation * dist * dist ) );",
-
-			"}",
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				"float w = lightWidth;",
-				"float h = lightHeight;",
-
-				"vec3 proj = projectOnPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS );",
-				"vec3 dir = proj - lightPositionVS;",
-
-				"vec2 diagonal = vec2( dot( dir, lightRightVS ), dot( dir, lightUpVS ) );",
-				"vec2 nearest2D = vec2( clamp( diagonal.x, -w, w ), clamp( diagonal.y, -h, h ) );",
-				"vec3 nearestPointInside = vec3( lightPositionVS ) + ( lightRightVS * nearest2D.x + lightUpVS * nearest2D.y );",
-
-				"vec3 lightDir = normalize( nearestPointInside - vertexPositionVS.xyz );",
-				"float NdotL = max( dot( lightNormalVS, -lightDir ), 0.0 );",
-				"float NdotL2 = max( dot( normal, lightDir ), 0.0 );",
-
-				//"if ( NdotL2 * NdotL > 0.0 && sideOfPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS ) ) {",
-				"if ( NdotL2 * NdotL > 0.0 ) {",
-
-					// diffuse
-
-					"vec3 diffuse = vec3( sqrt( NdotL * NdotL2 ) );",
-
-					// specular
-
-					"vec3 specular = vec3( 0.0 );",
-
-					"vec3 R = reflect( normalize( -vertexPositionVS.xyz ), normal );",
-					"vec3 E = linePlaneIntersect( vertexPositionVS.xyz, R, vec3( lightPositionVS ), lightNormalVS );",
-
-					"float specAngle = dot( R, lightNormalVS );",
-
-					"if ( specAngle > 0.0 ) {",
-
-						"vec3 dirSpec = E - vec3( lightPositionVS );",
-						"vec2 dirSpec2D = vec2( dot( dirSpec, lightRightVS ), dot( dirSpec, lightUpVS ) );",
-						"vec2 nearestSpec2D = vec2( clamp( dirSpec2D.x, -w, w ), clamp( dirSpec2D.y, -h, h ) );",
-						"float specFactor = 1.0 - clamp( length( nearestSpec2D - dirSpec2D ) * 0.05 * shininess, 0.0, 1.0 );",
-						"specular = specularColor * specFactor * specAngle * diffuse;",
-
-					"}",
-
-					// combine
-
-					"float dist = distance( vertexPositionVS.xyz, nearestPointInside );",
-					"float attenuation = calculateAttenuation( dist );",
-
-					THREE.DeferredShaderChunk[ "combine" ],
-
-				"} else {",
-
-					"discard;",
-
-				"}",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() {",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"emissiveLight" : {
-
-		uniforms: {
-
-			samplerColor: 	{ type: "t", value: null },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-				"vec4 colorMap = texture2D( samplerColor, texCoord );",
-				"vec3 emissiveColor = float_to_vec3( abs( colorMap.w ) );",
-
-				"gl_FragColor = vec4( emissiveColor, 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	}
-
-};

+ 28 - 15
examples/js/WaterShader.js

@@ -9,17 +9,21 @@
 
 THREE.ShaderLib[ 'water' ] = {
 
-	uniforms: { "normalSampler":	{ type: "t", value: null },
-				"mirrorSampler":	{ type: "t", value: null },
-				"alpha":			{ type: "f", value: 1.0 },
-				"time":				{ type: "f", value: 0.0 },
-				"distortionScale":	{ type: "f", value: 20.0 },
-				"textureMatrix" :	{ type: "m4", value: new THREE.Matrix4() },
-				"sunColor":			{ type: "c", value: new THREE.Color( 0x7F7F7F ) },
-				"sunDirection":		{ type: "v3", value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
-				"eye":				{ type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
-				"waterColor":		{ type: "c", value: new THREE.Color( 0x555555 ) }
-	},
+	uniforms: THREE.UniformsUtils.merge( [
+		THREE.UniformsLib[ "fog" ], { 
+			"normalSampler":    { type: "t", value: null },
+			"mirrorSampler":    { type: "t", value: null },
+			"alpha":            { type: "f", value: 1.0 },
+			"time":             { type: "f", value: 0.0 },
+			"distortionScale":  { type: "f", value: 20.0 },
+			"noiseScale":       { type: "f", value: 1.0 },
+			"textureMatrix" :   { type: "m4", value: new THREE.Matrix4() },
+			"sunColor":         { type: "c", value: new THREE.Color(0x7F7F7F) },
+			"sunDirection":     { type: "v3", value: new THREE.Vector3(0.70707, 0.70707, 0) },
+			"eye":              { type: "v3", value: new THREE.Vector3(0, 0, 0) },
+			"waterColor":       { type: "c", value: new THREE.Color(0x555555) }
+		}
+	] ),
 
 	vertexShader: [
 		'uniform mat4 textureMatrix;',
@@ -73,7 +77,10 @@ THREE.ShaderLib[ 'water' ] = {
 		'	specularColor += pow( direction, shiny ) * sunColor * spec;',
 		'	diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;',
 		'}',
-		
+
+		THREE.ShaderChunk[ "common" ],
+		THREE.ShaderChunk[ "fog_pars_fragment" ],		
+
 		'void main()',
 		'{',
 		'	vec4 noise = getNoise( worldPosition.xz );',
@@ -96,7 +103,9 @@ THREE.ShaderLib[ 'water' ] = {
 		'	float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );',
 		'	vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;',
 		'	vec3 albedo = mix( sunColor * diffuseLight * 0.3 + scatter, ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance );',
-		'	gl_FragColor = vec4( albedo, alpha );',
+		'	vec3 outgoingLight = albedo;',
+			THREE.ShaderChunk[ "fog_fragment" ],
+		'	gl_FragColor = vec4( outgoingLight, alpha );',		
 		'}'
 	].join( '\n' )
 
@@ -128,7 +137,9 @@ THREE.Water = function ( renderer, camera, scene, options ) {
 	this.waterColor = new THREE.Color( optionalParameter( options.waterColor, 0x7F7F7F ) );
 	this.eye = optionalParameter( options.eye, new THREE.Vector3( 0, 0, 0 ) );
 	this.distortionScale = optionalParameter( options.distortionScale, 20.0 );
-	
+	this.side = optionalParameter(options.side, THREE.FrontSide);
+	this.fog = optionalParameter(options.fog, false);
+
 	this.renderer = renderer;
 	this.scene = scene;
 	this.mirrorPlane = new THREE.Plane();
@@ -162,7 +173,9 @@ THREE.Water = function ( renderer, camera, scene, options ) {
 		fragmentShader: mirrorShader.fragmentShader, 
 		vertexShader: mirrorShader.vertexShader, 
 		uniforms: mirrorUniforms,
-		transparent: true
+		transparent: true,
+		side: this.side,
+		fog: this.fog		
 	} );
 
 	this.material.uniforms.mirrorSampler.value = this.texture;

+ 22 - 23
examples/js/geometries/DecalGeometry.js

@@ -27,7 +27,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 	this.cube.updateMatrix();
 
 	this.iCubeMatrix = ( new THREE.Matrix4() ).getInverse( this.cube.matrix );
-	
+
 	this.faceIndices = [ 'a', 'b', 'c', 'd' ];
 
 	this.clipFace = function( inVertices, plane ) {
@@ -40,16 +40,16 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 				d1 = v1.vertex.dot( p ) - size;
 
 			var s = d0 / ( d0 - d1 );
-			var v = new THREE.DecalVertex( 
-				new THREE.Vector3( 
+			var v = new THREE.DecalVertex(
+				new THREE.Vector3(
 					v0.vertex.x + s * ( v1.vertex.x - v0.vertex.x ),
 					v0.vertex.y + s * ( v1.vertex.y - v0.vertex.y ),
-					v0.vertex.z + s * ( v1.vertex.z - v0.vertex.z ) 
+					v0.vertex.z + s * ( v1.vertex.z - v0.vertex.z )
 				),
 				new THREE.Vector3(
 					v0.normal.x + s * ( v1.normal.x - v0.normal.x ),
 					v0.normal.y + s * ( v1.normal.y - v0.normal.y ),
-					v0.normal.z + s * ( v1.normal.z - v0.normal.z ) 
+					v0.normal.z + s * ( v1.normal.z - v0.normal.z )
 				)
 			);
 
@@ -91,19 +91,19 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 					var nV1, nV2, nV3;
 					if ( v1Out ) {
 
-						nV1 = inVertices[ j + 1 ]; 
+						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 ]; 
+						nV1 = inVertices[ j ];
 						nV2 = inVertices[ j + 2 ];
 						nV3 = clip( inVertices[ j + 1 ], nV1, plane );
 						nV4 = clip( inVertices[ j + 1 ], nV2, plane );
-						
+
 						outVertices.push( nV3 );
 						outVertices.push( nV2.clone() );
 						outVertices.push( nV1.clone() );
@@ -114,9 +114,9 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 						break;
 
 					}
-					if ( v3Out ) { 
+					if ( v3Out ) {
 
-						nV1 = inVertices[ j ]; 
+						nV1 = inVertices[ j ];
 						nV2 = inVertices[ j + 1 ];
 						nV3 = clip( inVertices[ j + 2 ], nV1, plane );
 						nV4 = clip( inVertices[ j + 2 ], nV2, plane );
@@ -137,17 +137,17 @@ 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 ); 
+						nV3 = clip( nV1, inVertices[ j + 2 ], plane );
 						outVertices.push( nV1 );
 						outVertices.push( nV2 );
 						outVertices.push( nV3 );
 
 					}
-					if ( ! v2Out ) { 
+					if ( ! v2Out ) {
 
 						nV1 = inVertices[ j + 1 ].clone();
 						nV2 = clip( nV1, inVertices[ j + 2 ], plane );
@@ -245,30 +245,30 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 		}
 
 		for ( var k = 0; k < finalVertices.length; k += 3 ) {
-			
+
 			this.vertices.push(
 				finalVertices[ k ].vertex,
 				finalVertices[ k + 1 ].vertex,
 				finalVertices[ k + 2 ].vertex
 			);
 
-			var f = new THREE.Face3( 
-				k, 
-				k + 1, 
+			var f = new THREE.Face3(
+				k,
+				k + 1,
 				k + 2
 			);
 			f.vertexNormals.push( finalVertices[ k + 0 ].normal );
 			f.vertexNormals.push( finalVertices[ k + 1 ].normal );
 			f.vertexNormals.push( finalVertices[ k + 2 ].normal );
-			
+
 			this.faces.push( f );
-			
+
 			this.faceVertexUvs[ 0 ].push( [
 				this.uvs[ k ],
-				this.uvs[ k + 1 ], 
+				this.uvs[ k + 1 ],
 				this.uvs[ k + 2 ]
 			] );
-		
+
 		}
 
 		this.verticesNeedUpdate = true;
@@ -277,7 +277,6 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 		this.uvsNeedUpdate = true;
 		this.normalsNeedUpdate = true;
 		this.colorsNeedUpdate = true;
-		this.tangentsNeedUpdate = true;
 		this.computeFaceNormals();
 
 	};

+ 0 - 2
examples/js/loaders/AssimpJSONLoader.js

@@ -212,10 +212,8 @@ THREE.AssimpJSONLoader.prototype = {
 
 		//geometry.computeFaceNormals();
 		//geometry.computeVertexNormals();
-		//geometry.computeTangents();
 		geometry.computeBoundingSphere();
 
-		// TODO: tangents
 		return geometry;
 
 	},

+ 0 - 2
examples/js/loaders/BinaryLoader.js

@@ -686,8 +686,6 @@ THREE.BinaryLoader.prototype = {
 		var geometry = new Model( texturePath );
 		var materials = THREE.Loader.prototype.initMaterials( jsonMaterials, texturePath, this.crossOrigin );
 
-		if ( THREE.Loader.prototype.needsTangents( materials ) ) geometry.computeTangents();
-
 		callback( geometry, materials );
 
 	}

+ 23 - 15
examples/js/loaders/DDSLoader.js

@@ -16,7 +16,7 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 	var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
 
 	// Adapted from @toji's DDS utils
-	//	https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
+	// https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
 
 	// All values and structures referenced from:
 	// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
@@ -175,9 +175,9 @@ 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_GBitMask ] & 0xff00
 				&& header[ off_BBitMask ] & 0xff
 				&& header[ off_ABitMask ] & 0xff000000  ) {
 
@@ -201,9 +201,21 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 
 	}
 
-	//TODO: Verify that all faces of the cubemap are present with DDSCAPS2_CUBEMAP_POSITIVEX, etc.
+	var caps2 = header[ off_caps2 ];
+	dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false;
+	if ( dds.isCubemap && (
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ )
+		) ) {
+
+		console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
+		return dds;
 
-	dds.isCubemap = header[ off_caps2 ] & DDSCAPS2_CUBEMAP ? true : false;
+	}
 
 	dds.width = header[ off_width ];
 	dds.height = header[ off_height ];
@@ -212,13 +224,13 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 
 	// Extract mipmaps buffers
 
-	var width = dds.width;
-	var height = dds.height;
-
 	var faces = dds.isCubemap ? 6 : 1;
 
 	for ( var face = 0; face < faces; face ++ ) {
 
+		var width = dds.width;
+		var height = dds.height;
+
 		for ( var i = 0; i < dds.mipmapCount; i ++ ) {
 
 			if ( isRGBAUncompressed ) {
@@ -232,23 +244,19 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 				var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
 
 			}
-			
+
 			var mipmap = { "data": byteArray, "width": width, "height": height };
 			dds.mipmaps.push( mipmap );
 
 			dataOffset += dataLength;
 
-			width = Math.max( width * 0.5, 1 );
-			height = Math.max( height * 0.5, 1 );
+			width = Math.max( width >> 1, 1 );
+			height = Math.max( height >> 1, 1 );
 
 		}
 
-		width = dds.width;
-		height = dds.height;
-
 	}
 
 	return dds;
 
 };
-

+ 1 - 27
examples/js/loaders/deprecated/SceneLoader.js

@@ -218,10 +218,7 @@ THREE.SceneLoader.prototype = {
 
 						if ( geometry ) {
 
-							var needsTangents = false;
-
 							material = result.materials[ objJSON.material ];
-							needsTangents = material instanceof THREE.ShaderMaterial;
 
 							pos = objJSON.position;
 							rot = objJSON.rotation;
@@ -248,22 +245,6 @@ THREE.SceneLoader.prototype = {
 
 							}
 
-							if ( material instanceof THREE.MeshFaceMaterial ) {
-
-								for ( var i = 0; i < material.materials.length; i ++ ) {
-
-									needsTangents = needsTangents || ( material.materials[ i ] instanceof THREE.ShaderMaterial );
-
-								}
-
-							}
-
-							if ( needsTangents ) {
-
-								geometry.computeTangents();
-
-							}
-
 							if ( objJSON.skin ) {
 
 								object = new THREE.SkinnedMesh( geometry, material );
@@ -346,7 +327,7 @@ THREE.SceneLoader.prototype = {
 
 					} else if ( objJSON.type === "AmbientLight" || objJSON.type === "PointLight" ||
 						objJSON.type === "DirectionalLight" || objJSON.type === "SpotLight" ||
-						objJSON.type === "HemisphereLight" || objJSON.type === "AreaLight" ) {
+						objJSON.type === "HemisphereLight" ) {
 
 						var color = objJSON.color;
 						var intensity = objJSON.intensity;
@@ -384,13 +365,6 @@ THREE.SceneLoader.prototype = {
 								light.target.applyEuler( new THREE.Euler( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ], 'XYZ' ) );
 								break;
 
-							case 'AreaLight':
-								light = new THREE.AreaLight( color, intensity );
-								light.position.fromArray( position );
-								light.width = objJSON.size;
-								light.height = objJSON.size_y;
-								break;
-
 						}
 
 						parent.add( light );

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 506 - 329
examples/js/loaders/sea3d/SEA3D.js


+ 11 - 12
examples/js/loaders/sea3d/SEA3DDeflate.js

@@ -318,7 +318,6 @@ var zip_GET_BYTE = function() {
     if(zip_inflate_data.length == zip_inflate_pos)
 	return -1;
 	return zip_inflate_data[zip_inflate_pos++];
-    //return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
 }
 
 var zip_NEEDBITS = function(n) {
@@ -730,11 +729,11 @@ var zip_inflate_internal = function(buff, off, size) {
     return n;
 }
 
-var zip_inflate = function(str) {
+var zip_inflate = function(data) {
     var i, j, pos = 0;
 
     zip_inflate_start();
-    zip_inflate_data = str;
+    zip_inflate_data = new Uint8Array(data);
     zip_inflate_pos = 0;
 	
     var buff = new Uint8Array(1024);
@@ -745,7 +744,7 @@ var zip_inflate = function(str) {
 			out[pos++] = buff[j];		    
 	
     zip_inflate_data = null; // G.C.
-    return new Uint8Array(out);
+    return new Uint8Array(out).buffer;
 }
 
 if (! ctx.RawDeflate) ctx.RawDeflate = {};
@@ -754,14 +753,14 @@ ctx.RawDeflate.inflate = zip_inflate;
 })(this);
 
 /**
- * 	SEA3D.js - SEA3D SDK ( Deflate )
- * 	Copyright (C) 2013 Sunag Entertainment 
- * 
- * 	http://code.google.com/p/sea3d/
+ * 	SEA3D DEFLATE
+ * 	@author Sunag / http://www.sunag.com.br/
  */
- 
-SEA3D.File.DeflateUncompress = function(data) {	
-	return RawDeflate.inflate(data);
+
+SEA3D.File.DeflateUncompress = function( data ) {
+
+	return RawDeflate.inflate( data );
+
 }
 
-SEA3D.File.setDecompressionEngine(1, "deflate", SEA3D.File.DeflateUncompress);
+SEA3D.File.setDecompressionEngine( 1, "deflate", SEA3D.File.DeflateUncompress );

+ 25 - 19
examples/js/loaders/sea3d/SEA3DLZMA.js

@@ -561,32 +561,38 @@ LZMA.decompressFile = function(inStream, outStream){
 };
 
 /**
- * 	SEA3D.js - SEA3D SDK ( LZMA )
- * 	Copyright (C) 2013 Sunag Entertainment 
- * 
- * 	http://code.google.com/p/sea3d/
+ * 	SEA3D LZMA
+ * 	@author Sunag / http://www.sunag.com.br/
  */
- 
-SEA3D.File.LZMAUncompress = function(data) {	
+
+SEA3D.File.LZMAUncompress = function( data ) {
+
+	data = new Uint8Array( data );
+
 	var inStream = {
-		data:data,
-		position:0,
-		readByte:function(){
-			return this.data[this.position++];
+		data: data,
+		position: 0,
+		readByte: function() {
+
+			return this.data[ this.position ++ ];
+
 		}
 	}
-	
+
 	var outStream = {
-		data:[],
-		position:0,
-		writeByte: function(value){
-			this.data[this.position++] = value;
+		data: [],
+		position: 0,
+		writeByte: function( value ) {
+
+			this.data[ this.position ++ ] = value;
+
 		}
 	}
-	
-	LZMA.decompressFile(inStream, outStream);
 
-	return new Uint8Array(outStream.data);
+	LZMA.decompressFile( inStream, outStream );
+
+	return new Uint8Array( outStream.data ).buffer;
+
 }
 
-SEA3D.File.setDecompressionEngine(2, "lzma", SEA3D.File.LZMAUncompress);
+SEA3D.File.setDecompressionEngine( 2, "lzma", SEA3D.File.LZMAUncompress );

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 13
examples/js/loaders/sea3d/SEA3DLZMA_LZIP.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 760 - 1087
examples/js/loaders/sea3d/SEA3DLoader.js


+ 0 - 1209
examples/js/renderers/WebGLDeferredRenderer.js

@@ -1,1209 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author MPanknin / http://www.redplant.de/
- */
-
-THREE.WebGLDeferredRenderer = function ( parameters ) {
-
-	var _this = this;
-
-	var pixelWidth = parameters.width !== undefined ? parameters.width : 800;
-	var pixelHeight = parameters.height !== undefined ? parameters.height : 600;
-	var currentScale = parameters.scale !== undefined ? parameters.scale : 1;
-
-	var scaledWidth = Math.floor( currentScale * pixelWidth );
-	var scaledHeight = Math.floor( currentScale * pixelHeight );
-
-	var brightness = parameters.brightness !== undefined ? parameters.brightness : 1;
-	var tonemapping = parameters.tonemapping !== undefined ? parameters.tonemapping : THREE.SimpleOperator;
-	var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
-
-	this.renderer = parameters.renderer;
-
-	if ( this.renderer === undefined ) {
-
-		this.renderer = new THREE.WebGLRenderer( { antialias: false } );
-		this.renderer.setSize( pixelWidth, pixelHeight );
-		this.renderer.setClearColor( 0x000000, 0 );
-
-		this.renderer.autoClear = false;
-
-	}
-
-	this.domElement = this.renderer.domElement;
-
-	//
-
-	var gl = this.renderer.context;
-
-	//
-
-	var currentCamera = null;
-	var projectionMatrixInverse = new THREE.Matrix4();
-
-	var positionVS = new THREE.Vector3();
-	var directionVS = new THREE.Vector3();
-	var tempVS = new THREE.Vector3();
-
-	var rightVS = new THREE.Vector3();
-	var normalVS = new THREE.Vector3();
-	var upVS = new THREE.Vector3();
-
-	//
-
-	var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 );
-	var geometryLightPlane = new THREE.PlaneBufferGeometry( 2, 2 );
-
-	var black = new THREE.Color( 0x000000 );
-
-	var colorShader = THREE.ShaderDeferred[ "color" ];
-	var normalDepthShader = THREE.ShaderDeferred[ "normalDepth" ];
-
-	//
-
-	var emissiveLightShader = THREE.ShaderDeferred[ "emissiveLight" ];
-	var pointLightShader = THREE.ShaderDeferred[ "pointLight" ];
-	var spotLightShader = THREE.ShaderDeferred[ "spotLight" ];
-	var directionalLightShader = THREE.ShaderDeferred[ "directionalLight" ];
-	var hemisphereLightShader = THREE.ShaderDeferred[ "hemisphereLight" ];
-	var areaLightShader = THREE.ShaderDeferred[ "areaLight" ];
-
-	var compositeShader = THREE.ShaderDeferred[ "composite" ];
-
-	//
-
-	var compColor, compNormal, compDepth, compLight, compFinal;
-	var passColor, passNormal, passDepth, passLightFullscreen, passLightProxy, compositePass;
-
-	var effectFXAA;
-
-	//
-
-	var lightSceneFullscreen, lightSceneProxy;
-
-	//
-
-	var resizableMaterials = [];
-
-	//
-
-	var invisibleMaterial = new THREE.ShaderMaterial();
-	invisibleMaterial.visible = false;
-
-
-	var defaultNormalDepthMaterial = new THREE.ShaderMaterial( {
-
-		uniforms:       THREE.UniformsUtils.clone( normalDepthShader.uniforms ),
-		vertexShader:   normalDepthShader.vertexShader,
-		fragmentShader: normalDepthShader.fragmentShader,
-		blending:       THREE.NoBlending,
-		derivatives:    true
-
-	} );
-
-	//
-
-	var initDeferredMaterials = function ( object ) {
-
-		if ( object.material instanceof THREE.MeshFaceMaterial ) {
-
-			var colorMaterials = [];
-			var normalDepthMaterials = [];
-
-			var materials = object.material.materials;
-
-			for ( var i = 0, il = materials.length; i < il; i ++ ) {
-
-				var deferredMaterials = createDeferredMaterials( materials[ i ] );
-
-				if ( deferredMaterials.transparent ) {
-
-					colorMaterials.push( invisibleMaterial );
-					normalDepthMaterials.push( invisibleMaterial );
-
-				} else {
-
-					colorMaterials.push( deferredMaterials.colorMaterial );
-					normalDepthMaterials.push( deferredMaterials.normalDepthMaterial );
-
-				}
-
-			}
-
-			object.userData.colorMaterial = new THREE.MeshFaceMaterial( colorMaterials );
-			object.userData.normalDepthMaterial = new THREE.MeshFaceMaterial( normalDepthMaterials );
-
-		} else {
-
-			var deferredMaterials = createDeferredMaterials( object.material );
-
-			object.userData.colorMaterial = deferredMaterials.colorMaterial;
-			object.userData.normalDepthMaterial = deferredMaterials.normalDepthMaterial;
-			object.userData.transparent = deferredMaterials.transparent;
-
-		}
-
-	};
-
-	var createDeferredMaterials = function ( originalMaterial ) {
-
-		var deferredMaterials = {};
-
-		// color material
-		// -----------------
-		// 	diffuse color
-		//	specular color
-		//	shininess
-		//	diffuse map
-		//	vertex colors
-		//	alphaTest
-		// 	morphs
-
-		var uniforms = THREE.UniformsUtils.clone( colorShader.uniforms );
-		var defines = { "USE_MAP": !! originalMaterial.map, "USE_ENVMAP": !! originalMaterial.envMap, "GAMMA_INPUT": true };
-
-		var material = new THREE.ShaderMaterial( {
-
-			fragmentShader: colorShader.fragmentShader,
-			vertexShader: 	colorShader.vertexShader,
-			uniforms: 		uniforms,
-			defines: 		defines,
-			shading:		originalMaterial.shading
-
-		} );
-
-		if ( originalMaterial instanceof THREE.MeshBasicMaterial ) {
-
-			var diffuse = black;
-			var emissive = originalMaterial.color;
-
-		} else {
-
-			var diffuse = originalMaterial.color;
-			var emissive = originalMaterial.emissive !== undefined ? originalMaterial.emissive : black;
-
-		}
-
-		var specular = originalMaterial.specular !== undefined ? originalMaterial.specular : black;
-		var shininess = originalMaterial.shininess !== undefined ? originalMaterial.shininess : 1;
-		var wrapAround = originalMaterial.wrapAround !== undefined ? ( originalMaterial.wrapAround ? - 1 : 1 ) : 1;
-		var additiveSpecular = originalMaterial.metal !== undefined ? ( originalMaterial.metal ? 1 : - 1 ) : - 1;
-
-		uniforms.emissive.value.copyGammaToLinear( emissive );
-		uniforms.diffuse.value.copyGammaToLinear( diffuse );
-		uniforms.specular.value.copyGammaToLinear( specular );
-		uniforms.shininess.value = shininess;
-		uniforms.wrapAround.value = wrapAround;
-		uniforms.additiveSpecular.value = additiveSpecular;
-
-		uniforms.map.value = originalMaterial.map;
-
-		if ( originalMaterial.envMap ) {
-
-			uniforms.envMap.value = originalMaterial.envMap;
-			uniforms.refractionRatio.value = originalMaterial.refractionRatio;
-			uniforms.reflectivity.value = originalMaterial.reflectivity;
-			uniforms.flipEnvMap.value = ( originalMaterial.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
-
-			uniforms.samplerNormalDepth.value = compNormalDepth.renderTarget2;
-			uniforms.viewWidth.value = scaledWidth;
-			uniforms.viewHeight.value = scaledHeight;
-
-			resizableMaterials.push( { "material": material } );
-
-		}
-
-		material.vertexColors = originalMaterial.vertexColors;
-		material.morphTargets = originalMaterial.morphTargets;
-		material.morphNormals = originalMaterial.morphNormals;
-		material.skinning = originalMaterial.skinning;
-
-		material.alphaTest = originalMaterial.alphaTest;
-		material.wireframe = originalMaterial.wireframe;
-
-		// uv repeat and offset setting priorities
-		//	1. color map
-		//	2. specular map
-		//	3. normal map
-		//	4. bump map
-
-		var uvScaleMap;
-
-		if ( originalMaterial.map ) {
-
-			uvScaleMap = originalMaterial.map;
-
-		} else if ( originalMaterial.specularMap ) {
-
-			uvScaleMap = originalMaterial.specularMap;
-
-		} else if ( originalMaterial.normalMap ) {
-
-			uvScaleMap = originalMaterial.normalMap;
-
-		} else if ( originalMaterial.bumpMap ) {
-
-			uvScaleMap = originalMaterial.bumpMap;
-
-		}
-
-		if ( uvScaleMap !== undefined ) {
-
-			var offset = uvScaleMap.offset;
-			var repeat = uvScaleMap.repeat;
-
-			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
-
-		}
-
-		deferredMaterials.colorMaterial = material;
-
-		// normal + depth material
-		// -----------------
-		//	vertex normals
-		//	morph normals
-		//	bump map
-		//	bump scale
-		//  clip depth
-
-		if ( originalMaterial.morphTargets || originalMaterial.skinning || originalMaterial.bumpMap ) {
-
-			var uniforms = THREE.UniformsUtils.clone( normalDepthShader.uniforms );
-			var defines = { "USE_BUMPMAP": !! originalMaterial.bumpMap };
-
-			var normalDepthMaterial = new THREE.ShaderMaterial( {
-
-				uniforms:       uniforms,
-				vertexShader:   normalDepthShader.vertexShader,
-				fragmentShader: normalDepthShader.fragmentShader,
-				shading:        originalMaterial.shading,
-				defines:        defines,
-				blending:       THREE.NoBlending,
-				derivatives:    true
-
-			} );
-
-			normalDepthMaterial.morphTargets = originalMaterial.morphTargets;
-			normalDepthMaterial.morphNormals = originalMaterial.morphNormals;
-			normalDepthMaterial.skinning = originalMaterial.skinning;
-
-			if ( originalMaterial.bumpMap ) {
-
-				uniforms.bumpMap.value = originalMaterial.bumpMap;
-				uniforms.bumpScale.value = originalMaterial.bumpScale;
-
-				var offset = originalMaterial.bumpMap.offset;
-				var repeat = originalMaterial.bumpMap.repeat;
-
-				uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
-
-			}
-
-		} else {
-
-			var normalDepthMaterial = defaultNormalDepthMaterial.clone();
-
-		}
-
-		normalDepthMaterial.wireframe = originalMaterial.wireframe;
-		normalDepthMaterial.vertexColors = originalMaterial.vertexColors;
-
-		deferredMaterials.normalDepthMaterial = normalDepthMaterial;
-
-		//
-
-		deferredMaterials.transparent = originalMaterial.transparent;
-
-		return deferredMaterials;
-
-	};
-
-	var updatePointLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		// skip infinite pointlights
-		// right now you can't switch between infinite and finite pointlights
-		// it's just too messy as they use different proxies
-
-		var distance = light.distance;
-
-		if ( distance > 0 ) {
-
-			lightProxy.scale.set( 1, 1, 1 ).multiplyScalar( distance );
-			uniforms[ "lightRadius" ].value = distance;
-
-			positionVS.setFromMatrixPosition( light.matrixWorld );
-			positionVS.applyMatrix4( currentCamera.matrixWorldInverse );
-
-			uniforms[ "lightPositionVS" ].value.copy( positionVS );
-
-			lightProxy.position.setFromMatrixPosition( light.matrixWorld );
-
-		} else {
-
-			uniforms[ "lightRadius" ].value = Infinity;
-
-		}
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredPointLight = function ( light ) {
-
-		// setup light material
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       THREE.UniformsUtils.clone( pointLightShader.uniforms ),
-			vertexShader:   pointLightShader.vertexShader,
-			fragmentShader: pointLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			transparent:	true,
-
-			side: THREE.BackSide
-
-		} );
-
-		// infinite pointlights use full-screen quad proxy
-		// regular pointlights use sphere proxy
-
-		var  geometry;
-
-		if ( light.distance > 0 ) {
-
-			geometry = geometryLightSphere;
-
-		} else {
-
-			geometry = geometryLightPlane;
-
-			materialLight.depthTest = false;
-			materialLight.side = THREE.FrontSide;
-
-		}
-
-		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
-		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
-
-		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometry, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updatePointLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateSpotLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		var viewMatrix = currentCamera.matrixWorldInverse;
-		var modelMatrix = light.matrixWorld;
-
-		positionVS.setFromMatrixPosition( modelMatrix );
-		positionVS.applyMatrix4( viewMatrix );
-
-		directionVS.setFromMatrixPosition( modelMatrix );
-		tempVS.setFromMatrixPosition( light.target.matrixWorld );
-		directionVS.sub( tempVS );
-		directionVS.normalize();
-		directionVS.transformDirection( viewMatrix );
-
-		uniforms[ "lightPositionVS" ].value.copy( positionVS );
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		uniforms[ "lightAngle" ].value = light.angle;
-		uniforms[ "lightDistance" ].value = light.distance;
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredSpotLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( spotLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   spotLightShader.vertexShader,
-			fragmentShader: spotLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateSpotLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateDirectionalLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		directionVS.setFromMatrixPosition( light.matrixWorld );
-		tempVS.setFromMatrixPosition( light.target.matrixWorld );
-		directionVS.sub( tempVS );
-		directionVS.normalize();
-		directionVS.transformDirection( currentCamera.matrixWorldInverse );
-
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredDirectionalLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( directionalLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   directionalLightShader.vertexShader,
-			fragmentShader: directionalLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateDirectionalLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateHemisphereLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		directionVS.setFromMatrixPosition( light.matrixWorld );
-		directionVS.normalize();
-		directionVS.transformDirection( currentCamera.matrixWorldInverse );
-
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColorSky" ].value.copyGammaToLinear( light.color );
-		uniforms[ "lightColorGround" ].value.copyGammaToLinear( light.groundColor );
-
-	};
-
-	var createDeferredHemisphereLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( hemisphereLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   hemisphereLightShader.vertexShader,
-			fragmentShader: hemisphereLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateHemisphereLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateAreaLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		var modelMatrix = light.matrixWorld;
-		var viewMatrix = currentCamera.matrixWorldInverse;
-
-		positionVS.setFromMatrixPosition( modelMatrix );
-		positionVS.applyMatrix4( viewMatrix );
-
-		uniforms[ "lightPositionVS" ].value.copy( positionVS );
-
-		rightVS.copy( light.right );
-		rightVS.transformDirection( modelMatrix );
-		rightVS.transformDirection( viewMatrix );
-
-		normalVS.copy( light.normal );
-		normalVS.transformDirection( modelMatrix );
-		normalVS.transformDirection( viewMatrix );
-
-		upVS.crossVectors( rightVS, normalVS );
-		upVS.normalize();
-
-		uniforms[ "lightRightVS" ].value.copy( rightVS );
-		uniforms[ "lightNormalVS" ].value.copy( normalVS );
-		uniforms[ "lightUpVS" ].value.copy( upVS );
-
-		uniforms[ "lightWidth" ].value = light.width;
-		uniforms[ "lightHeight" ].value = light.height;
-
-		uniforms[ "constantAttenuation" ].value = light.constantAttenuation;
-		uniforms[ "linearAttenuation" ].value = light.linearAttenuation;
-		uniforms[ "quadraticAttenuation" ].value = light.quadraticAttenuation;
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredAreaLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( areaLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   areaLightShader.vertexShader,
-			fragmentShader: areaLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateAreaLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var createDeferredEmissiveLight = function () {
-
-		// setup light material
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       THREE.UniformsUtils.clone( emissiveLightShader.uniforms ),
-			vertexShader:   emissiveLightShader.vertexShader,
-			fragmentShader: emissiveLightShader.fragmentShader,
-			depthTest:		false,
-			depthWrite:		false,
-			blending:		THREE.NoBlending
-
-		} );
-
-		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
-		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
-
-		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		return meshLight;
-
-	};
-
-	var initDeferredProperties = function ( object ) {
-
-		if ( object.userData.deferredInitialized ) return;
-
-		if ( object.material ) initDeferredMaterials( object );
-
-		if ( object instanceof THREE.PointLight ) {
-
-			var proxy = createDeferredPointLight( object );
-
-			if ( object.distance > 0 ) {
-
-				lightSceneProxy.add( proxy );
-
-			} else {
-
-				lightSceneFullscreen.add( proxy );
-
-			}
-
-		} else if ( object instanceof THREE.SpotLight ) {
-
-			var proxy = createDeferredSpotLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.DirectionalLight ) {
-
-			var proxy = createDeferredDirectionalLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.HemisphereLight ) {
-
-			var proxy = createDeferredHemisphereLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.AreaLight ) {
-
-			var proxy = createDeferredAreaLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		}
-
-		object.userData.deferredInitialized = true;
-
-	};
-
-	//
-
-	var setMaterialColor = function ( object ) {
-
-		if ( object.material ) {
-
-			if ( object.userData.transparent ) {
-
-				object.material = invisibleMaterial;
-
-			} else {
-
-				object.material = object.userData.colorMaterial;
-
-			}
-
-		}
-
-	};
-
-	var setMaterialNormalDepth = function ( object ) {
-
-		if ( object.material ) {
-
-			if ( object.userData.transparent ) {
-
-				object.material = invisibleMaterial;
-
-			} else {
-
-				object.material = object.userData.normalDepthMaterial;
-
-			}
-
-		}
-
-	};
-
-	// external API
-
-	this.setAntialias = function ( enabled ) {
-
-		antialias = enabled;
-
-		if ( antialias ) {
-
-			effectFXAA.enabled = true;
-			compositePass.renderToScreen = false;
-
-		} else {
-
-			effectFXAA.enabled = false;
-			compositePass.renderToScreen = true;
-
-		}
-
-	};
-
-	this.getAntialias = function () {
-
-		return antialias;
-
-	};
-
-	this.addEffect = function ( effect, normalDepthUniform, colorUniform ) {
-
-		if ( effect.material && effect.uniforms ) {
-
-			if ( normalDepthUniform ) effect.uniforms[ normalDepthUniform ].value = compNormalDepth.renderTarget2;
-			if ( colorUniform )    	  effect.uniforms[ colorUniform ].value = compColor.renderTarget2;
-
-			if ( normalDepthUniform || colorUniform ) {
-
-				resizableMaterials.push( { "material": effect.material, "normalDepth": normalDepthUniform, "color": colorUniform } );
-
-			}
-
-		}
-
-		compFinal.insertPass( effect, - 1 );
-
-	};
-
-	this.setScale = function ( scale ) {
-
-		currentScale = scale;
-
-		scaledWidth = Math.floor( currentScale * pixelWidth );
-		scaledHeight = Math.floor( currentScale * pixelHeight );
-
-		compNormalDepth.setSize( scaledWidth, scaledHeight );
-		compColor.setSize( scaledWidth, scaledHeight );
-		compLight.setSize( scaledWidth, scaledHeight );
-		compFinal.setSize( scaledWidth, scaledHeight );
-
-		compColor.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-		compLight.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		for ( var i = 0, il = resizableMaterials.length; i < il; i ++ ) {
-
-			var materialEntry = resizableMaterials[ i ];
-
-			var material = materialEntry.material;
-			var uniforms = material.uniforms;
-
-			var colorLabel = materialEntry.color !== undefined ? materialEntry.color : 'samplerColor';
-			var normalDepthLabel = materialEntry.normalDepth !== undefined ? materialEntry.normalDepth : 'samplerNormalDepth';
-
-			if ( uniforms[ colorLabel ] ) uniforms[ colorLabel ].value = compColor.renderTarget2;
-			if ( uniforms[ normalDepthLabel ] ) uniforms[ normalDepthLabel ].value = compNormalDepth.renderTarget2;
-
-			if ( uniforms[ 'viewWidth' ] ) uniforms[ "viewWidth" ].value = scaledWidth;
-			if ( uniforms[ 'viewHeight' ] ) uniforms[ "viewHeight" ].value = scaledHeight;
-
-		}
-
-		compositePass.uniforms[ 'samplerLight' ].value = compLight.renderTarget2;
-
-		effectFXAA.uniforms[ 'resolution' ].value.set( 1 / pixelWidth, 1 / pixelHeight );
-
-	};
-
-	this.setSize = function ( width, height ) {
-
-		pixelWidth = width;
-		pixelHeight = height;
-
-		this.renderer.setSize( pixelWidth, pixelHeight );
-
-		this.setScale( currentScale );
-
-	};
-
-	//
-
-	function updateLightProxy ( proxy ) {
-
-		var uniforms = proxy.material.uniforms;
-
-		if ( uniforms[ "matProjInverse" ] ) uniforms[ "matProjInverse" ].value = projectionMatrixInverse;
-		if ( uniforms[ "matView" ] ) uniforms[ "matView" ].value = currentCamera.matrixWorldInverse;
-
-		var originalLight = proxy.userData.originalLight;
-
-		if ( originalLight ) {
-
-			proxy.visible = originalLight.visible;
-
-			if ( originalLight instanceof THREE.PointLight ) {
-
-				updatePointLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.SpotLight ) {
-
-				updateSpotLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.DirectionalLight ) {
-
-				updateDirectionalLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.HemisphereLight ) {
-
-				updateHemisphereLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.AreaLight ) {
-
-				updateAreaLightProxy( proxy );
-
-			}
-
-		}
-
-	}
-
-	this.render = function ( scene, camera ) {
-
-		// setup deferred properties
-
-		if ( ! scene.userData.lightSceneProxy ) {
-
-			scene.userData.lightSceneProxy = new THREE.Scene();
-			scene.userData.lightSceneFullscreen = new THREE.Scene();
-
-			var meshLight = createDeferredEmissiveLight();
-			scene.userData.lightSceneFullscreen.add( meshLight );
-
-		}
-
-		currentCamera = camera;
-
-		lightSceneProxy = scene.userData.lightSceneProxy;
-		lightSceneFullscreen = scene.userData.lightSceneFullscreen;
-
-		passColor.camera = currentCamera;
-		passNormalDepth.camera = currentCamera;
-		passLightProxy.camera = currentCamera;
-		passLightFullscreen.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-
-		passColor.scene = scene;
-		passNormalDepth.scene = scene;
-		passLightFullscreen.scene = lightSceneFullscreen;
-		passLightProxy.scene = lightSceneProxy;
-
-		scene.traverse( initDeferredProperties );
-
-		// update scene graph only once per frame
-		// (both color and normalDepth passes use exactly the same scene state)
-
-		scene.autoUpdate = false;
-		scene.updateMatrixWorld();
-
-		// 1) g-buffer normals + depth pass
-
-		scene.traverse( setMaterialNormalDepth );
-
-		// clear shared depth buffer
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = true;
-
-		// write 1 to shared stencil buffer
-		// for non-background pixels
-
-		//gl.enable( gl.STENCIL_TEST );
-		gl.stencilOp( gl.REPLACE, gl.REPLACE, gl.REPLACE );
-		gl.stencilFunc( gl.ALWAYS, 1, 0xffffffff );
-		gl.clearStencil( 0 );
-
-		compNormalDepth.render();
-
-		// just touch foreground pixels (stencil == 1)
-		// both in color and light passes
-
-		gl.stencilFunc( gl.EQUAL, 1, 0xffffffff );
-		gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP );
-
-		// 2) g-buffer color pass
-
-		scene.traverse( setMaterialColor );
-
-		// must use clean slate depth buffer
-		// otherwise there are z-fighting glitches
-		// not enough precision between two geometry passes
-		// just to use EQUAL depth test
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = false;
-
-		compColor.render();
-
-		// 3) light pass
-
-		// do not clear depth buffer in this pass
-		// depth from geometry pass is used for light culling
-		// (write light proxy color pixel if behind scene pixel)
-
-		this.renderer.autoClearDepth = false;
-
-		scene.autoUpdate = true;
-
-		gl.depthFunc( gl.GEQUAL );
-
-		projectionMatrixInverse.getInverse( currentCamera.projectionMatrix );
-
-		for ( var i = 0, il = lightSceneProxy.children.length; i < il; i ++ ) {
-
-			var proxy = lightSceneProxy.children[ i ];
-			updateLightProxy( proxy );
-
-		}
-
-		for ( var i = 0, il = lightSceneFullscreen.children.length; i < il; i ++ ) {
-
-			var proxy = lightSceneFullscreen.children[ i ];
-			updateLightProxy( proxy );
-
-		}
-
-		compLight.render();
-
-		// 4) composite pass
-
-		// return back to usual depth and stencil handling state
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = true;
-		gl.depthFunc( gl.LEQUAL );
-		gl.disable( gl.STENCIL_TEST );
-
-		compFinal.render( 0.1 );
-
-	};
-
-	//
-
-	var createRenderTargets = function ( ) {
-
-		var rtParamsFloatLinear = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: true,
-									format: THREE.RGBAFormat, type: THREE.FloatType };
-
-		var rtParamsFloatNearest = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: true,
-									 format: THREE.RGBAFormat, type: THREE.FloatType };
-
-		var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-							  format: THREE.RGBFormat, type: THREE.UnsignedByteType };
-
-		// g-buffers
-
-		var rtColor   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatNearest );
-		var rtNormalDepth = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatNearest );
-		var rtLight   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatLinear );
-		var rtFinal   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsUByte );
-
-		rtColor.generateMipmaps = false;
-		rtNormalDepth.generateMipmaps = false;
-		rtLight.generateMipmaps = false;
-		rtFinal.generateMipmaps = false;
-
-		// normal + depth composer
-
-		passNormalDepth = new THREE.RenderPass();
-		passNormalDepth.clear = true;
-
-		compNormalDepth = new THREE.EffectComposer( _this.renderer, rtNormalDepth );
-		compNormalDepth.addPass( passNormalDepth );
-
-		// color composer
-
-		passColor = new THREE.RenderPass();
-		passColor.clear = true;
-
-		compColor = new THREE.EffectComposer( _this.renderer, rtColor );
-		compColor.addPass( passColor );
-
-		compColor.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		// light composer
-
-		passLightFullscreen = new THREE.RenderPass();
-		passLightFullscreen.clear = true;
-
-		passLightProxy = new THREE.RenderPass();
-		passLightProxy.clear = false;
-
-		compLight = new THREE.EffectComposer( _this.renderer, rtLight );
-		compLight.addPass( passLightFullscreen );
-		compLight.addPass( passLightProxy );
-
-		compLight.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		// final composer
-
-		compositePass = new THREE.ShaderPass( compositeShader );
-		compositePass.uniforms[ 'samplerLight' ].value = compLight.renderTarget2;
-		compositePass.uniforms[ 'brightness' ].value = brightness;
-		compositePass.material.blending = THREE.NoBlending;
-		compositePass.clear = true;
-
-		var defines;
-
-		switch ( tonemapping ) {
-
-			case THREE.SimpleOperator:    defines = { "TONEMAP_SIMPLE": true };    break;
-			case THREE.LinearOperator:    defines = { "TONEMAP_LINEAR": true };    break;
-			case THREE.ReinhardOperator:  defines = { "TONEMAP_REINHARD": true };  break;
-			case THREE.FilmicOperator:    defines = { "TONEMAP_FILMIC": true };    break;
-			case THREE.UnchartedOperator: defines = { "TONEMAP_UNCHARTED": true }; break;
-
-		}
-
-		compositePass.material.defines = defines;
-
-		// FXAA
-
-		effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
-		effectFXAA.uniforms[ 'resolution' ].value.set( 1 / pixelWidth, 1 / pixelHeight );
-		effectFXAA.renderToScreen = true;
-
-		//
-
-		compFinal = new THREE.EffectComposer( _this.renderer, rtFinal );
-		compFinal.addPass( compositePass );
-		compFinal.addPass( effectFXAA );
-
-		if ( antialias ) {
-
-			effectFXAA.enabled = true;
-			compositePass.renderToScreen = false;
-
-		} else {
-
-			effectFXAA.enabled = false;
-			compositePass.renderToScreen = true;
-
-		}
-
-	};
-
-	// init
-
-	createRenderTargets();
-
-};
-
-// tonemapping operator types
-
-THREE.NoOperator = 0;
-THREE.SimpleOperator = 1;
-THREE.LinearOperator = 2;
-THREE.ReinhardOperator = 3;
-THREE.FilmicOperator = 4;
-THREE.UnchartedOperator = 5;

+ 0 - 515
examples/js/shaders/NormalDisplacementShader.js

@@ -1,515 +0,0 @@
-/*
- * @author alteredq / http://alteredqualia.com/
- *
- * Normal map shader
- *  - Blinn-Phong
- *  - normal + diffuse + specular + AO + displacement + reflection + shadow maps
- *  - point and directional lights (use with "lights: true" material option)
- */
-
-THREE.NormalDisplacementShader = {
-
-	uniforms: THREE.UniformsUtils.merge( [
-
-		THREE.UniformsLib[ "fog" ],
-		THREE.UniformsLib[ "lights" ],
-		THREE.UniformsLib[ "shadowmap" ],
-
-		{
-
-			"enableAO"          : { type: "i", value: 0 },
-			"enableDiffuse"     : { type: "i", value: 0 },
-			"enableSpecular"    : { type: "i", value: 0 },
-			"enableReflection"  : { type: "i", value: 0 },
-			"enableDisplacement": { type: "i", value: 0 },
-
-			"tDisplacement": { type: "t", value: null }, // must go first as this is vertex texture
-			"tDiffuse"     : { type: "t", value: null },
-			"tCube"        : { type: "t", value: null },
-			"tNormal"      : { type: "t", value: null },
-			"tSpecular"    : { type: "t", value: null },
-			"tAO"          : { type: "t", value: null },
-
-			"uNormalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) },
-
-			"uDisplacementBias": { type: "f", value: 0.0 },
-			"uDisplacementScale": { type: "f", value: 1.0 },
-
-			"diffuse": { type: "c", value: new THREE.Color( 0xffffff ) },
-			"specular": { type: "c", value: new THREE.Color( 0x111111 ) },
-			"shininess": { type: "f", value: 30 },
-			"opacity": { type: "f", value: 1 },
-
-			"refractionRatio": { type: "f", value: 0.98 },
-			"reflectivity": { type: "f", value: 0.5 },
-
-			"uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) },
-			"uRepeat" : { type: "v2", value: new THREE.Vector2( 1, 1 ) },
-
-		}
-
-	] ),
-
-	fragmentShader: [
-
-		"uniform vec3 diffuse;",
-		"uniform vec3 specular;",
-		"uniform float shininess;",
-		"uniform float opacity;",
-
-		"uniform bool enableDiffuse;",
-		"uniform bool enableSpecular;",
-		"uniform bool enableAO;",
-		"uniform bool enableReflection;",
-
-		"uniform sampler2D tDiffuse;",
-		"uniform sampler2D tNormal;",
-		"uniform sampler2D tSpecular;",
-		"uniform sampler2D tAO;",
-
-		"uniform samplerCube tCube;",
-
-		"uniform vec2 uNormalScale;",
-
-		"uniform float refractionRatio;",
-		"uniform float reflectivity;",
-
-		"varying vec3 vTangent;",
-		"varying vec3 vBinormal;",
-		"varying vec3 vNormal;",
-		"varying vec2 vUv;",
-
-		"uniform vec3 ambientLightColor;",
-
-		"#if MAX_DIR_LIGHTS > 0",
-
-		"	uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
-		"	uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
-
-		"#endif",
-
-		"#if MAX_HEMI_LIGHTS > 0",
-
-		"	uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
-		"	uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
-		"	uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];",
-
-		"#endif",
-
-		"#if MAX_POINT_LIGHTS > 0",
-
-		"	uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
-		"	uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
-		"	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
-
-		"#endif",
-
-		"#if MAX_SPOT_LIGHTS > 0",
-
-		"	uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
-		"	uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
-		"	uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
-
-		"#endif",
-
-		"varying vec3 vWorldPosition;",
-		"varying vec3 vViewPosition;",
-
-		THREE.ShaderChunk[ "common" ],
-		THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
-		THREE.ShaderChunk[ "fog_pars_fragment" ],
-		THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
-
-		"void main() {",
-
-			THREE.ShaderChunk[ "logdepthbuf_fragment" ],
-
-		"	vec3 outgoingLight = vec3( 0.0 );",
-
-		"	vec4 diffuseColor = vec4( diffuse, opacity );",
-
-		"	vec3 specularTex = vec3( 1.0 );",
-
-		"	vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
-		"	normalTex.xy *= uNormalScale;",
-		"	normalTex = normalize( normalTex );",
-
-		"	if( enableDiffuse ) {",
-
-		"		#ifdef GAMMA_INPUT",
-
-		"			vec4 texelColor = texture2D( tDiffuse, vUv );",
-		"			texelColor.xyz *= texelColor.xyz;",
-
-		"			diffuseColor *= texelColor;",
-
-		"		#else",
-
-		"			diffuseColor *= texture2D( tDiffuse, vUv );",
-
-		"		#endif",
-
-		"	}",
-
-		"	if( enableAO ) {",
-
-		"		diffuseColor.rgb *= texture2D( tAO, vUv ).xyz;", // actually, the AOmap should be modulating ambient light sources only,
-																 // and should use the second set of UVs, as is done elsewhere in the library
-		"	}",
-
-			THREE.ShaderChunk[ "alphatest_fragment" ],
-
-		"	if( enableSpecular )",
-		"		specularTex = texture2D( tSpecular, vUv ).xyz;",
-
-		"	mat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );",
-		"	vec3 finalNormal = tsb * normalTex;",
-
-		"	#ifdef FLIP_SIDED",
-
-		"		finalNormal = - finalNormal;",
-
-		"	#endif",
-
-		"	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",
-
-		"		for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
-
-		"			vec3 pointVector = pointLightPosition[ i ] + vViewPosition.xyz;",
-
-		"			float pointDistance = 1.0;",
-		"			if ( pointLightDistance[ i ] > 0.0 )",
-		"				pointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );",
-
-		"			pointVector = normalize( pointVector );",
-
-					// diffuse
-
-		"			float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
-
-		"			totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
-
-					// specular
-
-		"			vec3 pointHalfVector = normalize( pointVector + viewPosition );",
-		"			float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
-		"			float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
-
-		"			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 );",
-		"			totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;",
-
-		"		}",
-
-		"	#endif",
-
-			// spot lights
-
-		"	#if MAX_SPOT_LIGHTS > 0",
-
-		"		for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
-
-		"			vec3 spotVector = spotLightPosition[ i ] + vViewPosition.xyz;",
-
-		"			float spotDistance = 1.0;",
-		"			if ( spotLightDistance[ i ] > 0.0 )",
-		"				spotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );",
-
-		"			spotVector = normalize( spotVector );",
-
-		"			float spotEffect = dot( spotLightDirection[ i ], spotVector );",
-
-		"			if ( spotEffect > spotLightAngleCos[ i ] ) {",
-
-		"				spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );",
-
-						// diffuse
-
-
-		"				float spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );",
-
-		"				totalDiffuseLight += spotDistance * spotLightColor[ i ] * spotDiffuseWeight * spotEffect;",
-
-						// specular
-
-		"				vec3 spotHalfVector = normalize( spotVector + viewPosition );",
-		"				float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
-		"				float spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, shininess ), 0.0 );",
-
-		"				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 );",
-		"				totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
-
-		"			}",
-
-		"		}",
-
-		"	#endif",
-
-			// directional lights
-
-		"	#if MAX_DIR_LIGHTS > 0",
-
-		"		for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
-
-		"			vec3 dirVector = directionalLightDirection[ i ];",
-
-					// diffuse
-
-		"			float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
-
-		"			totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
-
-					// specular
-
-		"			vec3 dirHalfVector = normalize( dirVector + viewPosition );",
-		"			float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
-		"			float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
-
-		"			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 );",
-		"			totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
-
-		"		}",
-
-		"	#endif",
-
-			// hemisphere lights
-
-		"	#if MAX_HEMI_LIGHTS > 0",
-
-		"		for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
-
-		"			vec3 lVector = hemisphereLightDirection[ i ];",
-
-					// diffuse
-
-		"			float dotProduct = dot( normal, lVector );",
-		"			float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
-
-		"			vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
-
-		"			totalDiffuseLight += hemiColor;",
-
-					// specular (sky light)
-
-		"			vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
-		"			float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
-		"			float hemiSpecularWeightSky = specularTex.r * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );",
-
-					//
-
-		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"			vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );",
-		"			totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) );",
-
-		"		}",
-
-		"	#endif",
-
-		"	#ifdef METAL",
-
-		"		outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + totalSpecularLight );",
-
-		"	#else",
-
-		"		outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight;",
-
-		"	#endif",
-
-		"	if ( enableReflection ) {",
-
-		"		vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
-
-		"		vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );",
-
-		"		#ifdef ENVMAP_MODE_REFLECTION",
-
-		"			vec3 vReflect = reflect( cameraToVertex, worldNormal );",
-
-		"		#else",
-
-		"			vec3 vReflect = refract( cameraToVertex, worldNormal, refractionRatio );",
-
-		"		#endif",
-
-		"		vec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
-
-		"		#ifdef GAMMA_INPUT",
-
-		"			cubeColor.xyz *= cubeColor.xyz;",
-
-		"		#endif",
-
-		"		outgoingLight = mix( outgoingLight, cubeColor.xyz, specularTex.r * reflectivity );",
-
-		"	}",
-
-			THREE.ShaderChunk[ "shadowmap_fragment" ],
-			THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-			THREE.ShaderChunk[ "fog_fragment" ],
-
-		"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
-
-		"}"
-
-	].join( "\n" ),
-
-	vertexShader: [
-
-		"attribute vec4 tangent;",
-
-		"uniform vec2 uOffset;",
-		"uniform vec2 uRepeat;",
-
-		"uniform bool enableDisplacement;",
-
-		"#ifdef VERTEX_TEXTURES",
-
-		"	uniform sampler2D tDisplacement;",
-		"	uniform float uDisplacementScale;",
-		"	uniform float uDisplacementBias;",
-
-		"#endif",
-
-		"varying vec3 vTangent;",
-		"varying vec3 vBinormal;",
-		"varying vec3 vNormal;",
-		"varying vec2 vUv;",
-
-		"varying vec3 vWorldPosition;",
-		"varying vec3 vViewPosition;",
-
-		THREE.ShaderChunk[ "skinning_pars_vertex" ],
-		THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
-		THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
-
-		"void main() {",
-
-			THREE.ShaderChunk[ "skinbase_vertex" ],
-			THREE.ShaderChunk[ "skinnormal_vertex" ],
-
-			// normal, tangent and binormal vectors
-
-		"	#ifdef USE_SKINNING",
-
-		"		vNormal = normalize( normalMatrix * skinnedNormal.xyz );",
-
-		"		vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
-		"		vTangent = normalize( normalMatrix * skinnedTangent.xyz );",
-
-		"	#else",
-
-		"		vNormal = normalize( normalMatrix * normal );",
-		"		vTangent = normalize( normalMatrix * tangent.xyz );",
-
-		"	#endif",
-
-		"	vBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );",
-
-		"	vUv = uv * uRepeat + uOffset;",
-
-			// displacement mapping
-
-		"	vec3 displacedPosition;",
-
-		"	#ifdef VERTEX_TEXTURES",
-
-		"		if ( enableDisplacement ) {",
-
-		"			vec3 dv = texture2D( tDisplacement, uv ).xyz;",
-		"			float df = uDisplacementScale * dv.x + uDisplacementBias;",
-		"			displacedPosition = position + normalize( normal ) * df;",
-
-		"		} else {",
-
-		"			#ifdef USE_SKINNING",
-
-		"				vec4 skinVertex = bindMatrix * vec4( position, 1.0 );",
-
-		"				vec4 skinned = vec4( 0.0 );",
-		"				skinned += boneMatX * skinVertex * skinWeight.x;",
-		"				skinned += boneMatY * skinVertex * skinWeight.y;",
-		"				skinned += boneMatZ * skinVertex * skinWeight.z;",
-		"				skinned += boneMatW * skinVertex * skinWeight.w;",
-		"				skinned  = bindMatrixInverse * skinned;",
-
-		"				displacedPosition = skinned.xyz;",
-
-		"			#else",
-
-		"				displacedPosition = position;",
-
-		"			#endif",
-
-		"		}",
-
-		"	#else",
-
-		"		#ifdef USE_SKINNING",
-
-		"			vec4 skinVertex = bindMatrix * vec4( position, 1.0 );",
-
-		"			vec4 skinned = vec4( 0.0 );",
-		"			skinned += boneMatX * skinVertex * skinWeight.x;",
-		"			skinned += boneMatY * skinVertex * skinWeight.y;",
-		"			skinned += boneMatZ * skinVertex * skinWeight.z;",
-		"			skinned += boneMatW * skinVertex * skinWeight.w;",
-		"			skinned  = bindMatrixInverse * skinned;",
-
-		"			displacedPosition = skinned.xyz;",
-
-		"		#else",
-
-		"			displacedPosition = position;",
-
-		"		#endif",
-
-		"	#endif",
-
-			//
-
-		"	vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );",
-		"	vec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
-
-		"	gl_Position = projectionMatrix * mvPosition;",
-
-			THREE.ShaderChunk[ "logdepthbuf_vertex" ],
-
-			//
-
-		"	vWorldPosition = worldPosition.xyz;",
-		"	vViewPosition = - mvPosition.xyz;",
-
-			// shadows
-
-		"	#ifdef USE_SHADOWMAP",
-
-		"		for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
-
-		"			vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;",
-
-		"		}",
-
-		"	#endif",
-
-		"}"
-
-	].join( "\n" )
-
-};

+ 6 - 7
examples/misc_controls_fly.html

@@ -108,20 +108,19 @@
 				scene.add( dirLight );
 
 				var materialNormalMap = new THREE.MeshPhongMaterial( {
-				
+
 					specular: 0x333333,
 					shininess: 15,
 					map: THREE.ImageUtils.loadTexture( "textures/planets/earth_atmos_2048.jpg" ),
 					specularMap: THREE.ImageUtils.loadTexture( "textures/planets/earth_specular_2048.jpg" ),
 					normalMap: THREE.ImageUtils.loadTexture( "textures/planets/earth_normal_2048.jpg" ),
 					normalScale: new THREE.Vector2( 0.85, 0.85 )
-				
+
 				} );
 
 				// planet
 
 				geometry = new THREE.SphereGeometry( radius, 100, 50 );
-				geometry.computeTangents();
 
 				meshPlanet = new THREE.Mesh( geometry, materialNormalMap );
 				meshPlanet.rotation.y = 0;
@@ -131,10 +130,10 @@
 				// clouds
 
 				var materialClouds = new THREE.MeshLambertMaterial( {
-				
+
 					map: THREE.ImageUtils.loadTexture( "textures/planets/earth_clouds_1024.png" ),
 					transparent: true
-				
+
 				} );
 
 				meshClouds = new THREE.Mesh( geometry, materialClouds );
@@ -145,9 +144,9 @@
 				// moon
 
 				var materialMoon = new THREE.MeshPhongMaterial( {
-				
+
 					map: THREE.ImageUtils.loadTexture( "textures/planets/moon_1024.jpg" )
-				
+
 				} );
 
 				meshMoon = new THREE.Mesh( geometry, materialMoon );

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 43
examples/models/animated/elderlyWalk.js


BIN
examples/models/sea3d/flag.sea


BIN
examples/models/sea3d/flag.tjs.sea


BIN
examples/models/sea3d/keyframe.tjs.sea


BIN
examples/models/sea3d/mascot.tjs.sea


BIN
examples/models/sea3d/morph.tjs.sea


BIN
examples/models/sea3d/robot.tjs.sea


BIN
examples/models/sea3d/skin.tjs.sea


BIN
examples/models/sea3d/sound.tjs.sea


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 43
examples/models/skinned/human_walk_0_female.js


BIN
examples/obj/box/box.bin


+ 0 - 29
examples/obj/box/box.js

@@ -1,29 +0,0 @@
-{
-
-    "metadata" :
-    {
-        "formatVersion" : 3.1,
-        "sourceFile"    : "box.obj",
-        "generatedBy"   : "OBJConverter",
-        "vertices"      : 36,
-        "faces"         : 25,
-        "normals"       : 8,
-        "uvs"           : 0,
-        "materials"     : 1
-    },
-
-    "materials": [	{
-	"DbgColor" : 15658734,
-	"DbgIndex" : 0,
-	"DbgName" : "",
-	"colorAmbient" : [0.0, 0.0, 0.0],
-	"colorDiffuse" : [0.8, 0.8, 0.8],
-	"colorSpecular" : [0.8, 0.8, 0.8],
-	"illumination" : 2,
-	"specularCoef" : 0.0,
-	"opacity" : 1.0
-	}],
-
-    "buffers": "box.bin"
-
-}

+ 0 - 7
examples/obj/ninja/.htaccess

@@ -1,7 +0,0 @@
-<Files *.js>
-SetOutputFilter DEFLATE
-</Files>
-
-<Files *.bin>
-SetOutputFilter DEFLATE
-</Files>

+ 0 - 2
examples/webgl_loader_ctm.html

@@ -179,8 +179,6 @@
 
 				loader.load( "models/ctm/LeePerry.ctm",  function( geometry ) {
 
-					geometry.computeTangents();
-
 					var material = new THREE.MeshPhongMaterial( {
 
 						specular: 0x303030,

+ 5 - 7
examples/webgl_loader_sea3d.html

@@ -71,26 +71,26 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : true, // Auto play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.AUTO, // Auto choose THREE.BufferGeometry and THREE.Geometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
 			loader.onComplete = function( e ) {
 
-				// Get camera from 3ds Max
+				// Get camera from SEA3D Studio
 				// use loader.get... to get others objects
 
 				var cam = loader.getCamera( "Camera007" );
 				camera.position.copy( cam.position );
 				camera.rotation.copy( cam.rotation );
 
+				controls = new THREE.OrbitControls( camera );
+
 				animate();
 
 			};
 
-			loader.load( './models/sea3d/mascot.sea' );
+			loader.load( './models/sea3d/mascot.tjs.sea' );
 
 			//
 
@@ -104,8 +104,6 @@
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
 				camera.position.set( 1000, - 300, 1000 );
 
-				controls = new THREE.OrbitControls( camera );
-
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 3 - 7
examples/webgl_loader_sea3d_hierarchy.html

@@ -71,9 +71,7 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : false, // Auto play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.BUFFER, // THREE.BufferGeometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
@@ -88,7 +86,7 @@
 						loader.meshes[i].animation.play("root");
 				}
 
-				// Get the first camera from 3ds Max
+				// Get the first camera from SEA3D Studio
 				// use loader.get... to get others objects
 
 				var cam = loader.cameras[0];
@@ -96,14 +94,12 @@
 				camera.rotation.copy( cam.rotation );
 
 				controls = new THREE.OrbitControls( camera );
-				controls.enableZoom = false;
-				controls.enablePan = false;
 
 				animate();
 
 			};
 
-			loader.load( './models/sea3d/robot.sea' );
+			loader.load( './models/sea3d/robot.tjs.sea' );
 
 			//
 

+ 4 - 6
examples/webgl_loader_sea3d_keyframe.html

@@ -72,9 +72,7 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : false, // Manual play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.BUFFER, // THREE.SEA3D.BUFFER to THREE.BufferGeometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
@@ -87,6 +85,8 @@
 				camera.position.copy( cam.position );
 				camera.rotation.copy( cam.rotation );
 
+				controls = new THREE.OrbitControls( camera );
+
 				// reset global animation time
 				SEA3D.AnimationHandler.setTime( 0 );
 
@@ -98,7 +98,7 @@
 
 			};
 
-			loader.load( './models/sea3d/keyframe.sea' );
+			loader.load( './models/sea3d/keyframe.tjs.sea' );
 
 			//
 			//	Animation Functions
@@ -148,8 +148,6 @@
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.position.set( 1000, - 300, 1000 );
 
-				controls = new THREE.OrbitControls( camera );
-
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 5 - 7
examples/webgl_loader_sea3d_morph.html

@@ -71,21 +71,21 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : true, // Auto play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.DEFAULT, // Auto choose THREE.BufferGeometry and THREE.Geometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
 			loader.onComplete = function( e ) {
 
-				// Get the first camera from 3ds Max
+				// Get the first camera from SEA3D Studio
 				// use loader.get... to get others objects
 
 				var cam = loader.cameras[0];
 				camera.position.copy( cam.position );
 				camera.rotation.copy( cam.rotation );
 
+				controls = new THREE.OrbitControls( camera );
+
 				// get mesh
 				teapot = loader.getMesh("Teapot01");
 
@@ -97,7 +97,7 @@
 
 			};
 
-			loader.load( './models/sea3d/morph.sea' );
+			loader.load( './models/sea3d/morph.tjs.sea' );
 
 			//
 
@@ -111,8 +111,6 @@
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.position.set( 1000, - 300, 1000 );
 
-				controls = new THREE.OrbitControls( camera );
-
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 5 - 6
examples/webgl_loader_sea3d_skinning.html

@@ -74,20 +74,21 @@
 
 				autoPlay : true, // Auto play animations
 				container : scene, // Container to add models
-				parser : THREE.SEA3D.AUTO, // Auto choose THREE.BufferGeometry and THREE.Geometry
-				multiplier : 1 // Light multiplier
+				multiplier : .6 // Light multiplier
 
 			} );
 
 			loader.onComplete = function( e ) {
 
-				// Get the first camera from 3ds Max
+				// Get the first camera from SEA3D Studio
 				// use loader.get... to get others objects
 
 				var cam = loader.cameras[0];
 				camera.position.copy( cam.position );
 				camera.rotation.copy( cam.rotation );
 
+				controls = new THREE.OrbitControls( camera );
+
 				// get meshes
 				player = loader.getMesh("Player");
 
@@ -102,7 +103,7 @@
 
 			};
 
-			loader.load( './models/sea3d/skin.sea' );
+			loader.load( './models/sea3d/skin.tjs.sea' );
 
 			//
 
@@ -116,8 +117,6 @@
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.position.set( 1000, - 300, 1000 );
 
-				controls = new THREE.OrbitControls( camera );
-
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 2 - 4
examples/webgl_loader_sea3d_sound.html

@@ -128,9 +128,7 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : true, // Auto play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.AUTO, // Auto choose THREE.BufferGeometry and THREE.Geometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
@@ -150,7 +148,7 @@
 
 			};
 
-			loader.load( './models/sea3d/sound.sea' );
+			loader.load( './models/sea3d/sound.tjs.sea' );
 
 			//
 

+ 0 - 325
examples/webgl_materials_normaldisplacementmap.html

@@ -1,325 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js webgl - materials - normal map</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				background:#000;
-				color:#fff;
-				padding:0;
-				margin:0;
-				font-weight: bold;
-				overflow:hidden;
-			}
-
-			a {	color: #ffffff;	}
-
-			#info {
-				position: absolute;
-				top: 0px; width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family:Monospace;
-				font-size:13px;
-				text-align:center;
-				z-index:1000;
-			}
-
-			#oldie {
-				background:rgb(200,100,0) !important;
-				color:#fff;
-			}
-
-			#vt { display:none }
-			#vt, #vt a { color:orange; }
-		</style>
-	</head>
-
-	<body>
-
-		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - webgl (<span id="description">normal + ao + displacement + environment + shadow</span>) map demo.
-			ninja head from <a href="http://developer.amd.com/archive/gpu/MeshMapper/pages/default.aspx" target="_blank">AMD GPU MeshMapper</a>
-
-			<div id="vt">displacement mapping needs vertex textures (GPU with Shader Model 3.0)</div>
-		</div>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/loaders/BinaryLoader.js"></script>
-		<script src="js/shaders/NormalDisplacementShader.js"></script>
-
-		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
-
-		<script>
-
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
-			var stats, loader;
-
-			var camera, scene, renderer;
-
-			var mesh1, mesh2;
-
-			var pointLight;
-
-			var mouseX = 0;
-			var mouseY = 0;
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
-
-			var r = 0.0;
-
-			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-
-			init();
-			animate();
-
-			function init() {
-
-				var container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
-				scene = new THREE.Scene();
-
-				var width = 500;
-				var aspect = window.innerWidth / window.innerHeight;
-				camera = new THREE.OrthographicCamera( - width * aspect, width * aspect, width, - width, 1, 10000 );
-				camera.position.z = 1500;
-
-				// LIGHTS
-
-				var ambientLight = new THREE.AmbientLight( 0x111111 );
-				scene.add( ambientLight );
-
-				pointLight = new THREE.PointLight( 0xff0000 );
-				pointLight.position.z = 10000;
-				pointLight.distance = 4000;
-				scene.add( pointLight );
-
-				var pointLight2 = new THREE.PointLight( 0xff5500 );
-				pointLight2.position.z = 1000;
-				scene.add( pointLight2 );
-
-				var pointLight3 = new THREE.PointLight( 0x0000ff );
-				pointLight3.position.x = -1000;
-				pointLight3.position.z = 1000;
-				scene.add( pointLight3 );
-
-				var spotLight = new THREE.SpotLight( 0xaaaaaa );
-				spotLight.position.set( 1000, 500, 1000 );
-				spotLight.castShadow = true;
-				spotLight.shadowCameraNear = 500;
-				spotLight.shadowCameraFov = 70;
-				spotLight.shadowBias = - 0.001;
-				spotLight.shadowMapWidth = 1024;
-				spotLight.shadowMapHeight = 1024;
-				spotLight.shadowDarkness = 0.5;
-				scene.add( spotLight );
-
-				// env map
-
-				var path = "textures/cube/SwedishRoyalCastle/";
-				var format = '.jpg';
-				var urls = [
-						path + 'px' + format, path + 'nx' + format,
-						path + 'py' + format, path + 'ny' + format,
-						path + 'pz' + format, path + 'nz' + format
-					];
-
-				var reflectionCube = THREE.ImageUtils.loadTextureCube( urls, THREE.CubeReflectionMapping );
-
-				// common material parameters
-
-				var diffuse = 0x0a0100, specular = 0xffffff, shininess = 10, scale = 23;
-
-				// normal map shader
-
-				var shader = THREE.NormalDisplacementShader;
-				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
-
-				uniforms[ "enableAO" ].value = true;
-				uniforms[ "enableDiffuse" ].value = false;
-				uniforms[ "enableSpecular" ].value = false;
-				uniforms[ "enableReflection" ].value = true;
-				uniforms[ "enableDisplacement" ].value = true;
-
-				uniforms[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/normal.jpg" );
-				uniforms[ "tAO" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/ao.jpg" );
-
-				uniforms[ "tDisplacement" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/displacement.jpg" );
-				uniforms[ "uDisplacementBias" ].value = - 0.428408;
-				uniforms[ "uDisplacementScale" ].value = 2.436143;
-
-				uniforms[ "uNormalScale" ].value.y = - 1;
-
-				uniforms[ "diffuse" ].value.setHex( diffuse );
-				uniforms[ "specular" ].value.setHex( specular );
-
-				uniforms[ "shininess" ].value = shininess;
-
-				uniforms[ "tCube" ].value = reflectionCube;
-				uniforms[ "reflectivity" ].value = 0.2;
-
-				var defines = {};
-				defines[ "ENVMAP_MODE_REFLECTION" ] = "";
-
-				var parameters = {
-					defines: defines,
-					uniforms: uniforms,
-					vertexShader: shader.vertexShader,
-					fragmentShader: shader.fragmentShader,
-					lights: true,
-					fog: false
-				};
-
-				var material1 = new THREE.ShaderMaterial( parameters );
-
-				var material2 = new THREE.MeshPhongMaterial( {
-					color: diffuse,
-					specular: specular,
-					shininess: shininess,
-					normalMap: uniforms[ "tNormal" ].value,
-					normalScale: uniforms[ "uNormalScale" ].value,
-					aoMap: uniforms[ "tAO" ].value,
-					aoMapIntensity: 1,
-					envMap: reflectionCube,
-					combine: THREE.MixOperation,
-					reflectivity: 0.2
-				} );
-
-				//
-
-				loader = new THREE.BinaryLoader();
-				loader.load( "obj/ninja/NinjaLo_bin.js", function( geometry ) { createScene( geometry, scale, material1, material2 ) } );
-
-				//
-
-				renderer = new THREE.WebGLRenderer();
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
-
-				//
-
-				renderer.gammaInput = true;
-				renderer.gammaOutput = true;
-
-				//
-
-				renderer.shadowMap.enabled = true;
-				renderer.shadowMap.type = THREE.PCFShadowMap;
-
-				//
-
-				var description = "normal + ao" + ( renderer.supportsVertexTextures() ? " + displacement + environment + shadow" : " + <strike>displacement</strike>" );
-				document.getElementById( "description" ).innerHTML = description;
-				document.getElementById( "vt" ).style.display = renderer.supportsVertexTextures() ? "none" : "block";
-
-				//
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '0px';
-				stats.domElement.style.zIndex = 100;
-				container.appendChild( stats.domElement );
-
-				//
-
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			function onWindowResize() {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				camera.left = window.innerWidth / - 2;
-				camera.right = window.innerWidth / 2;
-				camera.top = window.innerHeight / 2;
-				camera.bottom = window.innerHeight / - 2;
-
-				camera.updateProjectionMatrix();
-
-				renderer.setSize( window.innerWidth, window.innerHeight );
-
-			}
-
-			function createScene( geometry, scale, material1, material2 ) {
-
-				geometry.computeTangents(); // attribute tangents are required for NormalDisplacementShader
-
-				geometry.faceVertexUvs[ 1 ] = geometry.faceVertexUvs[ 0 ]; // 2nd set of UVs required for aoMap with MeshPhongMaterial
-
-				mesh1 = new THREE.Mesh( geometry, material1 );
-				mesh1.position.x = - scale * 12;
-				mesh1.scale.set( scale, scale, scale );
-				mesh1.castShadow = true;
-				mesh1.receiveShadow = true;
-				scene.add( mesh1 );
-
-				mesh2 = new THREE.Mesh( geometry, material2 );
-				mesh2.position.x = scale * 12;
-				mesh2.scale.set( scale, scale, scale );
-				mesh2.castShadow = true;
-				mesh2.receiveShadow = true;
-				scene.add( mesh2 );
-
-			}
-
-			function onDocumentMouseMove(event) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 10;
-				mouseY = ( event.clientY - windowHalfY ) * 10;
-
-			}
-
-			//
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-
-				stats.update();
-
-			}
-
-			function render() {
-
-				var ry = mouseX * 0.0003, rx = mouseY * 0.0003;
-
-				if( mesh1 ) {
-
-					mesh1.rotation.y = ry;
-					mesh1.rotation.x = rx;
-
-				}
-
-				if( mesh2 ) {
-
-					mesh2.rotation.y = ry;
-					mesh2.rotation.x = rx;
-
-				}
-
-				pointLight.position.x = 2500 * Math.cos( r );
-				pointLight.position.z = 2500 * Math.sin( r );
-
-				r += 0.01;
-
-				renderer.render( scene, camera );
-
-			}
-
-
-		</script>
-
-	</body>
-</html>

+ 0 - 2
examples/webgl_materials_normalmap.html

@@ -190,8 +190,6 @@
 
 			function createScene( geometry, scale, material ) {
 
-				geometry.computeTangents();
-
 				mesh1 = new THREE.Mesh( geometry, material );
 
 				mesh1.position.y = - 50;

+ 0 - 2
examples/webgl_postprocessing_advanced.html

@@ -329,8 +329,6 @@
 
 			function createMesh( geometry, scene, scale ) {
 
-				geometry.computeTangents();
-
 				var mat2 = new THREE.MeshLambertMaterial( {
 
 					color: 0x999999,

+ 377 - 0
examples/webgl_raycast_texture.html

@@ -0,0 +1,377 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js raycast - texture</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #808080;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+
+				background-color: #ffffff;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+			}
+
+			#controls {
+				position: absolute;
+				text-align:left;
+				top: 40px;
+				left: 5px;
+				padding: 5px;
+			}
+
+			.control {
+				margin-bottom: 3px;
+			}
+
+			input {
+				width: 50px;
+			}
+		</style>
+	</head>
+	<body>
+		<div id="container"></div>
+		<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - raycast texture<br>Left to right: buffer geometry - geometry - indexed buffer geometry</div>
+		<fieldset id="controls">
+			<legend>Circle</legend>
+			<div class="control">
+				WrapS : <select onchange="setwrapS(this)">
+					<option value="ClampToEdgeWrapping">ClampToEdgeWrapping</option>
+					<option value="RepeatWrapping" selected>RepeatWrapping</option>
+					<option value="MirroredRepeatWrapping">MirroredRepeatWrapping</option>
+				</select>
+			</div>
+			<div class="control">
+				WrapT : <select onchange="setwrapT(this)">
+					<option value="ClampToEdgeWrapping">ClampToEdgeWrapping</option>
+					<option value="RepeatWrapping" selected>RepeatWrapping</option>
+					<option value="MirroredRepeatWrapping">MirroredRepeatWrapping</option>
+				</select>
+			</div>
+			<div class="control">
+				Offset : X <input type="number" value="0" step="0.05" onchange="setOffsetU(this)" />
+				Y <input type="number" value="0" step="0.05" onchange="setOffsetV(this)" /><br />
+			</div>
+			<div class="control">
+				Repeat : X <input type="number" value="1" step="0.1" onchange="setRepeatU(this)" />
+				Y <input type="number" value="1" step="0.1" onchange="setRepeatV(this)" />
+			</div>
+		</fieldset>
+		<script src="../build/three.min.js"></script>
+		<script>
+
+			CanvasTexture = function ( parentTexture ) {
+
+				this._canvas = document.createElement( "canvas" );
+				this._canvas.width = this._canvas.height = 1024;
+				this._context2D = this._canvas.getContext( "2d" );
+
+				if ( parentTexture ) {
+
+					this._parentTexture.push( parentTexture );
+					parentTexture.image = this._canvas;
+
+				}
+
+				var that = this;
+				this._background = document.createElement( "img" );
+				this._background.addEventListener( "load", function ( event ) {
+
+					that._canvas.width = that._background.naturalWidth;
+					that._canvas.height = that._background.naturalHeight;
+
+					that._crossRadius = Math.ceil( Math.min( that._canvas.width, that._canvas.height / 30 ) );
+					that._crossMax = Math.ceil( 0.70710678 * that._crossRadius );
+					that._crossMin = Math.ceil( that._crossMax / 10 );
+					that._crossThickness = Math.ceil( that._crossMax / 10 );
+
+					that._draw();
+
+				}, false );
+				this._background.crossOrigin = '';
+				this._background.src = "textures/UV_Grid_Sm.jpg";
+
+				this._draw();
+
+			}
+
+
+			CanvasTexture.prototype = {
+
+				constructor: CanvasTexture,
+
+				_canvas: null,
+				_context2D: null,
+				_xCross: 0,
+				_yCross: 0,
+
+				_crossRadius: 57,
+				_crossMax: 40,
+				_crossMin: 4,
+				_crossThickness: 4,
+
+				_parentTexture: [],
+
+				addParent: function ( parentTexture ) {
+
+					if ( this._parentTexture.indexOf( parentTexture ) === - 1 ) {
+
+						this._parentTexture.push( parentTexture );
+						parentTexture.image = this._canvas;
+
+					}
+
+				},
+
+				setCrossPosition: function ( x, y ) {
+
+					this._xCross = x * this._canvas.width;
+					this._yCross = y * this._canvas.height;
+
+					this._draw();
+
+				},
+
+				_draw: function () {
+
+					if ( ! this._context2D ) return;
+
+					this._context2D.clearRect( 0, 0, this._canvas.width, this._canvas.height )
+
+					// Background.
+					this._context2D.drawImage( this._background, 0, 0 );
+
+					// Yellow cross.
+					this._context2D.lineWidth = this._crossThickness * 3;
+					this._context2D.strokeStyle = "#FFFF00";
+
+					this._context2D.beginPath();
+					this._context2D.moveTo( this._xCross - this._crossMax - 2, this._yCross - this._crossMax - 2 );
+					this._context2D.lineTo( this._xCross - this._crossMin, this._yCross - this._crossMin );
+
+					this._context2D.moveTo( this._xCross + this._crossMin, this._yCross + this._crossMin );
+					this._context2D.lineTo( this._xCross + this._crossMax + 2, this._yCross + this._crossMax + 2 );
+
+					this._context2D.moveTo( this._xCross - this._crossMax - 2, this._yCross + this._crossMax + 2 );
+					this._context2D.lineTo( this._xCross - this._crossMin, this._yCross + this._crossMin );
+
+					this._context2D.moveTo( this._xCross + this._crossMin, this._yCross - this._crossMin );
+					this._context2D.lineTo( this._xCross + this._crossMax + 2, this._yCross - this._crossMax - 2 );
+
+					this._context2D.stroke();
+
+					for ( var i = 0; i < this._parentTexture.length; i ++ ) {
+
+						this._parentTexture[ i ].needsUpdate = true;
+
+					}
+
+				}
+
+			}
+
+		</script>
+		<script>
+
+			var width = window.innerWidth;
+			var height = window.innerHeight;
+
+			var canvas;
+			var planeTexture, cubeTexture, circleTexture;
+
+			var container;
+
+			var camera, scene, renderer;
+
+			var raycaster = new THREE.Raycaster();
+			var mouse = new THREE.Vector2();
+			var onClickPosition = new THREE.Vector2();
+
+			init();
+			render();
+
+			function init() {
+
+				container = document.getElementById( "container" );
+
+				scene = new THREE.Scene();
+
+				camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
+				camera.position.x = - 30;
+				camera.position.y = 40;
+				camera.position.z = 50;
+				camera.lookAt( scene.position );
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setClearColor( new THREE.Color( 0xEEEEEE, 1.0 ) );
+				renderer.setSize( width, height );
+				container.appendChild( renderer.domElement );
+
+				// A cube, in the middle.
+				cubeTexture = new THREE.Texture( undefined, THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping );
+				canvas = new CanvasTexture( cubeTexture );
+				var cubeMaterial = new THREE.MeshBasicMaterial( { map: cubeTexture } );
+				var cubeGeometry = new THREE.BoxGeometry( 20, 20, 20 );
+				// Set a specific texture mapping.
+				var uvs;
+				for ( var i = 0; i < cubeGeometry.faceVertexUvs[ 0 ].length; i ++ ) {
+
+					uvs = cubeGeometry.faceVertexUvs[ 0 ][ i ];
+					for ( var j = 0; j < 3; j ++ ) {
+
+						if ( uvs[ j ].x < 0.1 ) uvs[ j ].x = - 1;
+						if ( uvs[ j ].y < 0.1 ) uvs[ j ].y = - 1;
+
+					}
+
+				}
+				var cube = new THREE.Mesh( cubeGeometry, cubeMaterial );
+				cube.position.x = 4;
+				cube.position.y = - 5;
+				cube.position.z = 0;
+				scene.add( cube );
+
+				// A plane on the left.
+				planeTexture = new THREE.Texture( undefined, THREE.UVMapping, THREE.MirroredRepeatWrapping, THREE.MirroredRepeatWrapping );
+				canvas.addParent( planeTexture );
+				var planeMaterial = new THREE.MeshBasicMaterial( { map: planeTexture } );
+				var planeGeometry = new THREE.PlaneBufferGeometry( 25, 25, 1, 1 );
+				var uvs = planeGeometry.attributes.uv.array;
+				// Set a specific texture mapping.
+				for ( var i = 0; i < uvs.length; i ++ ) {
+
+					uvs[ i ] *= 2;
+
+				}
+				var plane = new THREE.Mesh( planeGeometry, planeMaterial );
+				plane.position.x = - 16;
+				plane.position.y = - 5;
+				plane.position.z = 0;
+				scene.add( plane );
+
+				// A circle on the right.
+				circleTexture = new THREE.Texture( undefined, THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping );
+				canvas.addParent( circleTexture );
+				var circleMaterial = new THREE.MeshBasicMaterial( { map: circleTexture } );
+				var circleGeometry = new THREE.CircleBufferGeometry( 25, 40, 0, Math.PI * 2 );
+				var uvs = circleGeometry.attributes.uv.array;
+				// Set a specific texture mapping.
+				for ( var i = 0; i < uvs.length; i ++ ) {
+
+					uvs[ i ] = ( uvs[ i ] - 0.25 ) * 2;
+
+				}
+				var circle = new THREE.Mesh( circleGeometry, circleMaterial );
+				circle.position.x = 24;
+				circle.position.y = - 5;
+				circle.position.z = 0;
+				scene.add( circle );
+
+				window.addEventListener( 'resize', onWindowResize, false );
+				container.addEventListener( 'mousemove', onMouseMove, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			};
+
+			function onMouseMove( evt ) {
+
+				evt.preventDefault();
+
+				var array = getMousePosition( container, evt.clientX, evt.clientY );
+				onClickPosition.fromArray( array );
+
+				var intersects = getIntersects( onClickPosition, scene.children );
+
+				if ( intersects.length > 0 && intersects[ 0 ].uv ) {
+
+					var uv = intersects[ 0 ].uv;
+					intersects[ 0 ].object.material.map.transformUv( uv );
+					canvas.setCrossPosition( uv.x, uv.y );
+
+				}
+
+			};
+
+			var getMousePosition = function ( dom, x, y ) {
+
+				var rect = dom.getBoundingClientRect();
+				return [ ( x - rect.left ) / rect.width, ( y - rect.top ) / rect.height ];
+
+			};
+
+			var getIntersects = function ( point, objects ) {
+
+				mouse.set( ( point.x * 2 ) - 1, - ( point.y * 2 ) + 1 );
+
+				raycaster.setFromCamera( mouse, camera );
+
+				return raycaster.intersectObjects( objects );
+
+			};
+
+			function render() {
+
+				requestAnimationFrame( render );
+				renderer.render( scene, camera );
+
+			};
+
+			function setwrapS( that ) {
+
+				circleTexture.wrapS = THREE[ that.value ];
+				circleTexture.needsUpdate = true;
+
+			};
+
+			function setwrapT( that ) {
+
+				circleTexture.wrapT = THREE[ that.value ];
+				circleTexture.needsUpdate = true;
+
+			};
+
+			function setOffsetU( that ) {
+
+				circleTexture.offset.x = parseFloat( that.value );
+
+			};
+
+			function setOffsetV( that ) {
+
+				circleTexture.offset.y = parseFloat( that.value );
+
+			};
+
+			function setRepeatU( that ) {
+
+				circleTexture.repeat.x = parseFloat( that.value );
+
+			};
+
+			function setRepeatV( that ) {
+
+				circleTexture.repeat.y = parseFloat( that.value );
+
+			};
+
+		</script>
+	</body>
+</html>

+ 1 - 9
examples/webgl_sandbox.html

@@ -97,14 +97,7 @@
 
 				];
 
-				var geometries = [];
-
-				for ( var i = 0, l = materials.length; i < l; i ++ ) {
-
-					var geometry = new THREE.SphereGeometry( 50, 32, 16 );
-					geometries.push( geometry );
-
-				}
+				var geometry = new THREE.SphereGeometry( 50, 32, 16 );
 
 				for ( var i = 0; i < 5000; i ++ ) {
 
@@ -115,7 +108,6 @@
 					var index = Math.floor( ( i / 5000 ) * materials.length );
 
 					var material = materials[ index ];
-					var geometry = geometries[ index ];
 
 					var mesh = new THREE.Mesh( geometry, material );
 

+ 3 - 1
examples/webgl_terrain_dynamic.html

@@ -73,6 +73,7 @@
 		<script src="js/postprocessing/MaskPass.js"></script>
 		<script src="js/postprocessing/SavePass.js"></script>
 
+		<script src="js/BufferGeometryUtils.js"></script>
 		<script src="js/ShaderTerrain.js"></script>
 
 		<script src="js/Detector.js"></script>
@@ -415,7 +416,8 @@
 				// TERRAIN MESH
 
 				var geometryTerrain = new THREE.PlaneBufferGeometry( 6000, 6000, 256, 256 );
-				geometryTerrain.computeTangents();
+
+				THREE.BufferGeometryUtils.computeTangents( geometryTerrain );
 
 				terrain = new THREE.Mesh( geometryTerrain, mlib[ "terrain" ] );
 				terrain.position.set( 0, -125, 0 );

+ 0 - 479
examples/webgldeferred_animation.html

@@ -1,479 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-	<head>
-		<title>three.js webgl - deferred rendering [morphing + skinning]</title>
-		<meta charset="utf-8" />
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				background-color: #000;
-				margin: 0px;
-				overflow: hidden;
-			}
-
-			#info {
-				position: absolute;
-				top: 20px; width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family: Monospace;
-				font-size: 13px;
-				text-align: center;
-			}
-
-			a {
-				color: #ff0080;
-				text-decoration: none;
-			}
-
-			a:hover {
-				color: #0080ff;
-			}
-
-			#stats { position: absolute; top:10px; left: 5px }
-			#stats #fps { background: transparent !important }
-			#stats #fps #fpsText { color: #aaa !important }
-			#stats #fps #fpsGraph { display: none }
-		</style>
-	</head>
-
-	<body>
-		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - webgl deferred rendering with morphing and skinning animations -
-			characters from <a href="http://www.sintel.org/">Sintel</a> and by <a href="http://opengameart.org/content/walk-cycles">Clint Bellanger</a>
-		</div>
-		<div id="container"></div>
-
-
-		<script src="js/libs/stats.min.js"></script>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/Detector.js"></script>
-
-		<script src="js/renderers/WebGLDeferredRenderer.js"></script>
-		<script src="js/ShaderDeferred.js"></script>
-
-		<script src="js/shaders/CopyShader.js"></script>
-		<script src="js/shaders/FXAAShader.js"></script>
-
-		<script src="js/postprocessing/EffectComposer.js"></script>
-		<script src="js/postprocessing/RenderPass.js"></script>
-		<script src="js/postprocessing/ShaderPass.js"></script>
-		<script src="js/postprocessing/MaskPass.js"></script>
-
-		<script>
-
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
-			var SCALE = 0.75;
-
-			var WIDTH = window.innerWidth;
-			var HEIGHT = window.innerHeight;
-
-			var NEAR = 1.0, FAR = 350.0;
-			var VIEW_ANGLE = 45;
-
-			// controls
-
-			var mouseX = 0;
-			var mouseY = 0;
-
-			var targetX = 0, targetY = 0;
-			var angle = 0;
-			var target = new THREE.Vector3( 0, 0, 0 );
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
-
-			// core
-
-			var renderer, camera, scene, controls, stats, clock;
-
-			// lights
-
-			var numLights = 50;
-			var lights = [];
-
-			// morphs
-
-			var morphs = [];
-
-			// skins
-
-			var skins = [];
-
-			//
-
-			init();
-			animate();
-
-			// -----------------------------
-
-			function init() {
-
-				// renderer
-
-				renderer = new THREE.WebGLDeferredRenderer( { width: WIDTH, height: HEIGHT, scale: SCALE, brightness: 2, antialias: true } );
-
-				var container = document.getElementById( 'container' );
-				container.appendChild( renderer.domElement );
-
-				// camera
-
-				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, WIDTH / HEIGHT, NEAR, FAR );
-				camera.position.z = 150;
-
-				// scene
-
-				scene = new THREE.Scene();
-				scene.add( camera );
-
-				// stats
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '8px';
-				stats.domElement.style.zIndex = 100;
-				container.appendChild( stats.domElement );
-
-				// clock
-
-				clock = new THREE.Clock();
-
-				// add lights
-
-				initLights();
-
-				// add objects
-
-				initObjects();
-
-				// events
-
-				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-
-			// -----------------------------
-
-			function initLights() {
-
-				var distance = 40;
-
-				// front light
-
-				var light = new THREE.PointLight( 0xffffff, 1.5, 1.5 * distance );
-				scene.add( light );
-				lights.push( light );
-
-				// random lights
-
-				var c = new THREE.Vector3();
-
-				for ( var i = 1; i < numLights; i ++ ) {
-
-					var light = new THREE.PointLight( 0xffffff, 2.0, distance );
-
-					c.set( Math.random(), Math.random(), Math.random() ).normalize();
-					light.color.setRGB( c.x, c.y, c.z );
-
-					scene.add( light );
-					lights.push( light );
-
-				}
-
-				var geometry = new THREE.SphereGeometry( 0.7, 7, 7 );
-
-				for ( var i = 0; i < numLights; i ++ ) {
-
-					var light = lights[ i ];
-
-					var material = new THREE.MeshBasicMaterial();
-					material.color = light.color;
-
-					var emitter = new THREE.Mesh( geometry, material );
-					light.add( emitter );
-
-				}
-
-			}
-
-			function ensureLoop( animation ) {
-
-				for ( var i = 0; i < animation.hierarchy.length; i ++ ) {
-
-					var bone = animation.hierarchy[ i ];
-
-					var first = bone.keys[ 0 ];
-					var last = bone.keys[ bone.keys.length - 1 ];
-
-					last.pos = first.pos;
-					last.rot = first.rot;
-					last.scl = first.scl;
-
-				}
-
-			}
-
-			function initObjects() {
-
-				// add animated model
-
-				var loader = new THREE.JSONLoader();
-				loader.load( "models/animated/elderlyWalk.js", function( geometry ) {
-
-					geometry.computeMorphNormals();
-
-					var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x333333, shininess: 20, morphTargets: true, morphNormals: true, vertexColors: THREE.NoColors, shading: THREE.FlatShading } );
-					var meshAnim = new THREE.MorphAnimMesh( geometry, material );
-
-					meshAnim.duration = 3000;
-					meshAnim.userData.delta = -13;
-
-					meshAnim.scale.multiplyScalar( 50 );
-					meshAnim.position.set( 180, -48, -10 );
-					meshAnim.rotation.y = -Math.PI/2;
-
-					scene.add( meshAnim );
-					morphs.push( meshAnim );
-
-				} );
-
-				loader.load( "models/skinned/human_walk_0_female.js", function ( geometry, materials ) {
-
-					geometry.computeVertexNormals();
-					geometry.computeBoundingBox();
-
-					ensureLoop( geometry.animation );
-
-					for ( var i = 0, il = materials.length; i < il; i ++ ) {
-
-						var originalMaterial = materials[ i ];
-						originalMaterial.skinning = true;
-
-						originalMaterial.map = undefined;
-						originalMaterial.shading = THREE.SmoothShading;
-						originalMaterial.color.setHSL( 0.01, 0.3, 0.3 );
-						originalMaterial.specular.setHSL( 0, 0, 0.1 );
-						originalMaterial.shininess = 75;
-
-					}
-
-					var s = 18.5;
-
-					var material = new THREE.MeshFaceMaterial( materials );
-					var mesh = new THREE.SkinnedMesh( geometry, material, false );
-					mesh.scale.set( s, s, s );
-
-					mesh.rotation.y = Math.PI/2;
-
-					mesh.position.x = -100;
-					mesh.position.y = -geometry.boundingBox.min.y * s - 48;
-					mesh.position.z = 18;
-
-					mesh.userData.delta = 25;
-
-					scene.add( mesh );
-					skins.push( mesh );
-
-
-					animation = new THREE.Animation( mesh, geometry.animation );
-					animation.play();
-					animation.update( 0 );
-
-				} );
-
-				// add box
-
-				var box = generateBox();
-				box.scale.multiplyScalar( 8 );
-				scene.add( box );
-
-			}
-
-			// -----------------------------
-
-			function generateBox() {
-
-				var object = new THREE.Object3D();
-
-				var mapHeight2 = THREE.ImageUtils.loadTexture( "obj/lightmap/rocks.jpg" );
-				mapHeight2.repeat.set( 3, 1.5 );
-				mapHeight2.wrapS = mapHeight2.wrapT = THREE.RepeatWrapping;
-				mapHeight2.anisotropy = 4;
-				mapHeight2.format = THREE.RGBFormat;
-
-				var mapHeight3 = THREE.ImageUtils.loadTexture( "textures/water.jpg" );
-				mapHeight3.repeat.set( 16, 8 );
-				mapHeight3.wrapS = mapHeight3.wrapT = THREE.RepeatWrapping;
-				mapHeight3.anisotropy = 4;
-				mapHeight3.format = THREE.RGBFormat;
-
-				var geoPlane = new THREE.PlaneBufferGeometry( 40, 20 );
-
-				var matPlaneSide   = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x222222, shininess: 75, bumpMap: mapHeight2, bumpScale: 0.5 } );
-				var matPlaneBottom = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x222222, shininess: 75, bumpMap: mapHeight3, bumpScale: 0.5 } );
-				var matPlaneTop    = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x222222, shininess: 75, bumpMap: mapHeight3, bumpScale: 1 } );
-
-
-				// bottom
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneBottom );
-				mesh.position.z = -2;
-				mesh.position.y = -6;
-				mesh.rotation.x = -Math.PI/2;
-				object.add( mesh );
-
-				// top
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneTop );
-				mesh.position.z = -2;
-				mesh.position.y = 7;
-				mesh.rotation.x = Math.PI/2;
-				object.add( mesh );
-
-				// back
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneSide );
-				mesh.position.z = -4;
-				mesh.position.y = 0;
-				object.add( mesh );
-
-				// right
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneSide );
-				mesh.position.z = 0;
-				mesh.position.y = 0;
-				mesh.position.x = 13;
-				mesh.rotation.y = -Math.PI/2;
-				//object.add( mesh );
-
-				// left
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneSide );
-				mesh.position.z = 0;
-				mesh.position.y = 0;
-				mesh.position.x = -13;
-				mesh.rotation.y = Math.PI/2;
-				//object.add( mesh );
-
-				return object;
-
-			}
-
-			// -----------------------------
-
-			function onWindowResize( event ) {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				WIDTH = window.innerWidth;
-				HEIGHT = window.innerHeight;
-
-				renderer.setSize( WIDTH, HEIGHT );
-
-				camera.aspect = WIDTH / HEIGHT;
-				camera.updateProjectionMatrix();
-
-			}
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 1;
-				mouseY = ( event.clientY - windowHalfY ) * 1;
-
-			}
-
-			// -----------------------------
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				var delta = clock.getDelta();
-				var time = Date.now() * 0.0005;
-
-				// update lights
-
-				var x, y, z;
-
-				for ( var i = 0, il = lights.length; i < il; i ++ ) {
-
-					var light = lights[ i ];
-
-					if ( i > 0 ) {
-
-						x = Math.sin( time + i * 1.7 ) * 80;
-						y = Math.cos( time + i * 1.5 ) * 40;
-						z = Math.cos( time + i * 1.3 ) * 30;
-
-					} else {
-
-						x = Math.sin( time * 3 ) * 20;
-						y = 15;
-						z = Math.cos( time * 3 ) * 25 + 10;
-
-					}
-
-					light.position.set( x, y, z );
-
-				}
-
-				// update morphs
-
-				for ( var i = 0; i < morphs.length; i ++ ) {
-
-					var morph = morphs[ i ];
-					morph.updateAnimation( 1000 * delta );
-
-					morph.position.x += morph.userData.delta * delta;
-					if ( morph.position.x < -50 ) morph.position.x = 200;
-
-				}
-
-				// update skins
-
-				THREE.AnimationHandler.update( 0.4 * delta );
-
-				for ( var i = 0; i < skins.length; i ++ ) {
-
-					var skin = skins[ i ];
-
-					skin.position.x += skin.userData.delta * delta;
-					if ( skin.position.x > 200 ) skin.position.x = -200;
-
-				}
-
-				// update controls
-
-				targetX = mouseX * .001;
-				targetY = mouseY * .001;
-
-				angle += 0.05 * ( targetX - angle );
-
-				camera.position.x = -Math.sin( angle ) * 150;
-				camera.position.z = Math.cos( angle ) * 150;
-
-				camera.lookAt( target );
-
-				// render
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-	</body>
-
-</html>

+ 0 - 388
examples/webgldeferred_arealights.html

@@ -1,388 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-	<head>
-		<title>three.js webgl - deferred rendering</title>
-		<meta charset="utf-8" />
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				background-color: #000;
-				margin: 0px;
-				overflow: hidden;
-			}
-
-			#info {
-				position: absolute;
-				top: 20px; width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family: Monospace;
-				font-size: 13px;
-				text-align: center;
-			}
-
-			a {
-				color: #ff0080;
-				text-decoration: none;
-			}
-
-			a:hover {
-				color: #0080ff;
-			}
-
-			#stats { position: absolute; top:10px; left: 5px }
-			#stats #fps { background: transparent !important }
-			#stats #fps #fpsText { color: #aaa !important }
-			#stats #fps #fpsGraph { display: none }
-		</style>
-	</head>
-
-	<body>
-		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - deferred area lights WebGL demo by <a href="http://de.redplant.de" target=_blank>redPlant</a> -
-			based on <a href="http://www.gamedev.net/topic/552315-glsl-area-light-implementation/" target=_blank>ArKano22's</a> glsl implementation
-		</div>
-		<div id="container"></div>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/loaders/BinaryLoader.js"></script>
-
-		<script src="js/renderers/WebGLDeferredRenderer.js"></script>
-		<script src="js/ShaderDeferred.js"></script>
-
-		<script src="js/shaders/CopyShader.js"></script>
-		<script src="js/shaders/FXAAShader.js"></script>
-		<script src="js/shaders/ConvolutionShader.js"></script>
-
-		<script src="js/postprocessing/EffectComposer.js"></script>
-		<script src="js/postprocessing/RenderPass.js"></script>
-		<script src="js/postprocessing/ShaderPass.js"></script>
-		<script src="js/postprocessing/MaskPass.js"></script>
-		<script src="js/postprocessing/BloomPass.js"></script>
-
-		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
-
-		<script>
-
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
-			var SCALE = 1;
-
-			var WIDTH = window.innerWidth;
-			var HEIGHT = window.innerHeight;
-
-			var NEAR = 1.0, FAR = 350.0;
-			var VIEW_ANGLE = 40;
-
-			// controls
-
-			var mouseX = 0;
-			var mouseY = 0;
-
-			var targetX = 0, targetY = 0;
-			var angle = 0;
-			var target = new THREE.Vector3( 0, 0, 0 );
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
-
-			// core
-
-			var renderer, camera, scene, stats, clock;
-
-			// lights
-
-			var areaLight1, areaLight2, areaLight3;
-
-			//
-
-			init();
-			animate();
-
-			// -----------------------------
-
-			function init() {
-
-				// renderer
-
-				renderer = new THREE.WebGLDeferredRenderer( { width: WIDTH, height: HEIGHT, scale: SCALE, antialias: true, tonemapping: THREE.FilmicOperator, brightness: 2.5 } );
-
-				var container = document.getElementById( 'container' );
-				container.appendChild( renderer.domElement );
-
-				// effects
-
-				var bloomEffect = new THREE.BloomPass( 0.65 );
-				renderer.addEffect( bloomEffect );
-
-				// camera
-
-				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, WIDTH / HEIGHT, NEAR, FAR );
-				camera.position.y = 40;
-
-				// scene
-
-				scene = new THREE.Scene();
-				scene.add( camera );
-
-				// stats
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '8px';
-				stats.domElement.style.zIndex = 100;
-				container.appendChild( stats.domElement );
-
-				// clock
-
-				clock = new THREE.Clock();
-
-				// add lights
-
-				initLights();
-
-				// add objects
-
-				initObjects();
-
-				// events
-
-				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			// -----------------------------
-
-			function createAreaEmitter( light ) {
-
-				var geometry = new THREE.BoxGeometry( 1, 1, 1 );
-				var material = new THREE.MeshBasicMaterial( { color: light.color.getHex(), vertexColors: THREE.FaceColors } );
-
-				var backColor = 0x222222;
-
-				geometry.faces[ 5 ].color.setHex( backColor );
-				geometry.faces[ 4 ].color.setHex( backColor );
-				geometry.faces[ 2 ].color.setHex( backColor );
-				geometry.faces[ 1 ].color.setHex( backColor );
-				geometry.faces[ 0 ].color.setHex( backColor );
-
-				var emitter = new THREE.Mesh( geometry, material );
-				emitter.scale.set( light.width * 2, 0.2, light.height * 2 );
-
-				return emitter;
-
-			}
-
-			function setupAreaLight( light ) {
-
-				var matrix = light.matrixWorld;
-
-				light.right.set( 1, 0, 0 );
-				light.normal.set( 0, -1, 0 );
-
-				light.right.applyMatrix4( matrix );
-				light.normal.applyMatrix4( matrix );
-
-			}
-
-			function initLights() {
-
-				areaLight1 = new THREE.AreaLight( 0xffffff, 1 );
-				areaLight1.position.set( 0.0001, 10.0001, -18.5001 );
-				areaLight1.rotation.set( -0.74719, 0.0001, 0.0001 );
-				areaLight1.width = 10;
-				areaLight1.height = 1;
-				scene.add( areaLight1 );
-
-				var meshEmitter = createAreaEmitter( areaLight1 );
-				areaLight1.add( meshEmitter );
-
-				//
-
-				areaLight2 = new THREE.AreaLight( 0x33ff66, 1.5 );
-				areaLight2.position.set( -19.0001, 3.0001, 0.0001 );
-				areaLight2.rotation.set( -1.5707, 0.0001, 1.5707 );
-				areaLight2.width = 8;
-				areaLight2.height = 1;
-				scene.add( areaLight2 );
-
-				var meshEmitter = createAreaEmitter( areaLight2 );
-				areaLight2.add( meshEmitter );
-
-				//
-
-				areaLight3 = new THREE.AreaLight( 0x3366ff, 1.5 );
-				areaLight3.position.set( 19.0001, 3.0001, 0.0001 );
-				areaLight3.rotation.set( 1.5707, 0.0001, -1.5707 );
-				areaLight3.width = 8;
-				areaLight3.height = 1;
-				scene.add( areaLight3 );
-
-				var meshEmitter = createAreaEmitter( areaLight3 );
-				areaLight3.add( meshEmitter );
-
-			}
-
-			// -----------------------------
-
-			function initObjects() {
-
-				var loader = new THREE.BinaryLoader();
-				loader.load( "obj/box/box.js", function ( geometry, materials ) {
-
-					var material = new THREE.MeshPhongMaterial( { color: 0xffaa55, specular: 0x888888, shininess: 200 } );
-					var object = new THREE.Mesh( geometry, material );
-					object.scale.multiplyScalar( 2 );
-					scene.add( object );
-
-				} );
-
-				/*
-				var loader = new THREE.BinaryLoader();
-				loader.load( "obj/veyron/VeyronNoUv_bin.js", function ( geometry ) {
-
-					var r = "textures/cube/Bridge2/";
-					var urls = [
-						r + "posx.jpg", r + "negx.jpg",
-						r + "posy.jpg", r + "negy.jpg",
-						r + "posz.jpg", r + "negz.jpg"
-					];
-
-					var textureCube = THREE.ImageUtils.loadTextureCube( urls );
-					textureCube.format = THREE.RGBFormat;
-
-					var materials = [
-						// tires + inside
-						new THREE.MeshLambertMaterial( {
-							color: 0x050505
-						} ),
-						// wheels + extras chrome
-						new THREE.MeshLambertMaterial( {
-							color: 0xffffff,
-							envMap: textureCube
-						} ),
-						// back / top / front torso
-						new THREE.MeshLambertMaterial( {
-							color: 0x000000,
-							envMap: textureCube,
-							combine: THREE.MixOperation,
-							reflectivity: 0.15
-						} ),
-						// glass
-						new THREE.MeshLambertMaterial( {
-							color: 0x101046,
-							envMap: textureCube,
-							opacity: 0.25,
-							transparent: true
-						} ),
-						// sides torso
-						new THREE.MeshLambertMaterial( {
-							color: 0xffffff,
-							envMap: textureCube
-						} ),
-						// engine
-						new THREE.MeshLambertMaterial( {
-							color: 0xffffff,
-							envMap: textureCube
-						} ),
-						// backlights
-						new THREE.MeshLambertMaterial( {
-							color: 0xff0000,
-							opacity: 0.5,
-							transparent: true
-						} ),
-						// backsignals
-						new THREE.MeshLambertMaterial( {
-							color: 0xffbb00,
-							opacity: 0.5,
-							transparent: true
-						} )
-					];
-
-					var object = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
-					object.position.y = 5;
-					object.rotation.y = Math.PI / 4;
-					object.scale.multiplyScalar( 0.1 );
-					scene.add( object );
-
-				} );
-				*/
-
-			}
-
-
-			// -----------------------------
-
-			function onWindowResize( event ) {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				WIDTH = window.innerWidth;
-				HEIGHT = window.innerHeight - 2 * MARGIN;
-
-				renderer.setSize( WIDTH, HEIGHT );
-
-				camera.aspect = WIDTH / HEIGHT;
-				camera.updateProjectionMatrix();
-
-			}
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 1;
-				mouseY = ( event.clientY - windowHalfY ) * 1;
-
-			}
-
-			// -----------------------------
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				// update camera
-
-				var delta = clock.getDelta();
-
-				targetX = mouseX * .001;
-				targetY = mouseY * .001;
-
-				angle += 0.05 * ( targetX - angle );
-
-				camera.position.x = -Math.sin( angle ) * 40;
-				camera.position.z =  Math.cos( angle ) * 40;
-
-				camera.lookAt( target );
-
-				var time = Date.now();
-
-				areaLight1.position.x = Math.sin( Date.now() * 0.001 ) * 9;
-				areaLight1.position.y = Math.sin( Date.now() * 0.0013 ) * 5 + 5;
-
-				areaLight2.position.y = Math.sin( Date.now() * 0.0011 ) * 3 + 5;
-				areaLight2.position.z = Math.sin( Date.now() * 0.00113 ) * 10;
-
-				areaLight3.position.y = Math.sin( Date.now() * 0.00111 ) * 3 + 5;
-				areaLight3.position.z = Math.sin( Date.now() * 0.001113 ) * 10;
-
-				// render
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-	</body>
-
-</html>

+ 0 - 429
examples/webgldeferred_pointlights.html

@@ -1,429 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-	<head>
-		<title>three.js webgl - deferred rendering</title>
-		<meta charset="utf-8" />
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				background-color: #000;
-				margin: 0px;
-				overflow: hidden;
-			}
-
-			#info {
-				position: absolute;
-				top: 20px; width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family: Monospace;
-				font-size: 13px;
-				text-align: center;
-			}
-
-			a {
-				color: #ff0080;
-				text-decoration: none;
-			}
-
-			a:hover {
-				color: #0080ff;
-			}
-
-			#stats { position: absolute; top:10px; left: 5px }
-			#stats #fps { background: transparent !important }
-			#stats #fps #fpsText { color: #aaa !important }
-			#stats #fps #fpsGraph { display: none }
-		</style>
-	</head>
-
-	<body>
-		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - deferred point lights WebGL demo by <a href="http://de.redplant.de" target=_blank>redPlant</a> -
-			<a href="http://www.ir-ltd.net/infinite-3d-head-scan-released/" target="_blank">Lee Perry-Smith</a> head -
-			light attenuation formula by <a href="http://imdoingitwrong.wordpress.com/tag/glsl/" target=_blank>Tom Madams</a>
-		</div>
-		<div id="container"></div>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/loaders/BinaryLoader.js"></script>
-		<!-- <script src="js/loaders/UTF8Loader.js"></script> -->
-
-		<script src="js/renderers/WebGLDeferredRenderer.js"></script>
-		<script src="js/ShaderDeferred.js"></script>
-
-		<script src="js/shaders/CopyShader.js"></script>
-		<script src="js/shaders/FXAAShader.js"></script>
-
-		<script src="js/postprocessing/EffectComposer.js"></script>
-		<script src="js/postprocessing/RenderPass.js"></script>
-		<script src="js/postprocessing/ShaderPass.js"></script>
-		<script src="js/postprocessing/MaskPass.js"></script>
-
-		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
-
-		<script>
-
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
-			var SCALE = 1;
-
-			var WIDTH = window.innerWidth;
-			var HEIGHT = window.innerHeight;
-
-			var NEAR = 1.0, FAR = 350.0;
-			var VIEW_ANGLE = 45;
-
-			// controls
-
-			var mouseX = 0;
-			var mouseY = 0;
-
-			var targetX = 0, targetY = 0;
-			var angle = 0;
-			var target = new THREE.Vector3( 0, 0, 0 );
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
-
-			// core
-
-			var renderer, camera, scene, stats, clock;
-
-			// lights
-
-			var numLights = 50;
-			var lights = [];
-
-			//
-
-			init();
-			animate();
-
-			// -----------------------------
-
-			function init() {
-
-				// renderer
-
-				renderer = new THREE.WebGLDeferredRenderer( { width: WIDTH, height: HEIGHT, scale: SCALE, antialias: true } );
-
-				var container = document.getElementById( 'container' );
-				container.appendChild( renderer.domElement );
-
-				// camera
-
-				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, WIDTH / HEIGHT, NEAR, FAR );
-				camera.position.z = 150;
-
-				// scene
-
-				scene = new THREE.Scene();
-				scene.add( camera );
-
-				// stats
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '8px';
-				stats.domElement.style.zIndex = 100;
-				container.appendChild( stats.domElement );
-
-				// clock
-
-				clock = new THREE.Clock();
-
-				// add lights
-
-				initLights();
-
-				// add objects
-
-				initObjects();
-
-				// events
-
-				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			// -----------------------------
-
-			function initLights() {
-
-				var distance = 40;
-
-				// front light
-
-				var light = new THREE.PointLight( 0xffffff, 1.5, 1.5 * distance );
-				scene.add( light );
-				lights.push( light );
-
-				// random lights
-
-				var c = new THREE.Vector3();
-
-				for ( var i = 1; i < numLights; i ++ ) {
-
-					var light = new THREE.PointLight( 0xffffff, 2.0, distance );
-
-					c.set( Math.random(), Math.random(), Math.random() ).normalize();
-					light.color.setRGB( c.x, c.y, c.z );
-
-					scene.add( light );
-					lights.push( light );
-
-				}
-
-				var geometry = new THREE.SphereGeometry( 0.7, 7, 7 );
-
-				for ( var i = 0; i < numLights; i ++ ) {
-
-					var light = lights[ i ];
-
-					var material = new THREE.MeshBasicMaterial();
-					material.color = light.color;
-
-					var emitter = new THREE.Mesh( geometry, material );
-					light.add( emitter );
-
-				}
-
-			}
-
-			// -----------------------------
-
-			function initObjects() {
-
-				/*
-
-				var loader = new THREE.UTF8Loader();
-
-				loader.load( "models/utf8/ben_dds.js", function ( object ) {
-
-					object.scale.multiplyScalar( 150 );
-					object.position.y = -75;
-					scene.add( object );
-
-				}, { normalizeRGB: true } );
-
-				loader.load( "models/utf8/WaltHi.js", function ( object ) {
-
-					object.position.y = -35;
-					scene.add( object );
-
-				}, { normalizeRGB: true } );
-
-				*/
-
-
-				var loader = new THREE.JSONLoader();
-				loader.load( "obj/leeperrysmith/LeePerrySmith.js", function( geometry, materials ) {
-
-					var mapColor = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
-					var mapHeight = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg" );
-					mapHeight.repeat.set( 0.998, 0.998 );
-					mapHeight.offset.set( 0.001, 0.001 );
-					mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
-					mapHeight.anisotropy = 4;
-					mapHeight.format = THREE.RGBFormat;
-
-					var material = new THREE.MeshPhongMaterial( { map: mapColor, bumpMap: mapHeight, bumpScale: 2.5, shininess: 75, specular: 0x333333, metal: true } );
-
-					var object = new THREE.Mesh( geometry, material );
-					object.scale.multiplyScalar( 8 );
-					scene.add( object );
-
-				} );
-
-
-				var loader = new THREE.BinaryLoader();
-				loader.load( "obj/female02/Female02_bin.js", function( geometry, materials ) {
-
-					var object = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
-					object.position.x = -50;
-					object.position.y = -48;
-					object.scale.multiplyScalar( 0.45 );
-					scene.add( object );
-
-				} );
-
-				loader.load( "obj/male02/Male02_bin.js", function( geometry, materials ) {
-
-					var object = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
-					object.position.x = 50;
-					object.position.y = -48;
-					object.scale.multiplyScalar( 0.45 );
-					scene.add( object );
-
-				} );
-
-				// create box
-
-				var box = generateBox();
-				box.scale.multiplyScalar( 8 );
-				scene.add( box );
-
-			}
-
-			// -----------------------------
-
-			function generateBox() {
-
-				var object = new THREE.Object3D();
-
-				var mapHeight2 = THREE.ImageUtils.loadTexture( "obj/lightmap/rocks.jpg" );
-				mapHeight2.repeat.set( 3, 1.5 );
-				mapHeight2.wrapS = mapHeight2.wrapT = THREE.RepeatWrapping;
-				mapHeight2.anisotropy = 4;
-				mapHeight2.format = THREE.RGBFormat;
-
-				var mapHeight3 = THREE.ImageUtils.loadTexture( "textures/water.jpg" );
-				mapHeight3.repeat.set( 16, 8 );
-				mapHeight3.wrapS = mapHeight3.wrapT = THREE.RepeatWrapping;
-				mapHeight3.anisotropy = 4;
-				mapHeight3.format = THREE.RGBFormat;
-
-				var geoPlane = new THREE.PlaneBufferGeometry( 40, 20 );
-
-				var matPlane  = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess:  50, bumpMap: mapHeight2, bumpScale: 0.5 } );
-				var matPlane2 = new THREE.MeshPhongMaterial( { color: 0x331919, specular: 0x111111, shininess:  50, bumpMap: mapHeight2, bumpScale: 1 } );
-				var matPlane3 = new THREE.MeshPhongMaterial( { color: 0x00aaff, specular: 0xffffff, shininess: 200, bumpMap: mapHeight3, bumpScale: 1.2 } );
-				var matPlane4 = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess:  50, bumpMap: mapHeight3, bumpScale: 1 } );
-
-				// bottom
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane3 );
-				mesh.position.z = -2;
-				mesh.position.y = -6;
-				mesh.rotation.x = -Math.PI/2;
-				object.add( mesh );
-
-				// top
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane4 );
-				mesh.position.z = -2;
-				mesh.position.y = 6;
-				mesh.rotation.x = Math.PI/2;
-				object.add( mesh );
-
-				// back
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane );
-				mesh.position.z = -4;
-				mesh.position.y = 0;
-				object.add( mesh );
-
-				// right
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane );
-				mesh.position.z = 0;
-				mesh.position.y = 0;
-				mesh.position.x = 13;
-				mesh.rotation.y = -Math.PI/2;
-				//object.add( mesh );
-
-				// left
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane );
-				mesh.position.z = 0;
-				mesh.position.y = 0;
-				mesh.position.x = -13;
-				mesh.rotation.y = Math.PI/2;
-				//object.add( mesh );
-
-				return object;
-
-			}
-
-			// -----------------------------
-
-			function onWindowResize( event ) {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				WIDTH = window.innerWidth;
-				HEIGHT = window.innerHeight;
-
-				renderer.setSize( WIDTH, HEIGHT );
-
-				camera.aspect = WIDTH / HEIGHT;
-				camera.updateProjectionMatrix();
-
-			}
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 1;
-				mouseY = ( event.clientY - windowHalfY ) * 1;
-
-			}
-
-			// -----------------------------
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				// update lights
-
-				var time = Date.now() * 0.0005;
-				var x, y, z;
-
-				for ( var i = 0, il = lights.length; i < il; i ++ ) {
-
-					var light = lights[ i ];
-
-					if ( i > 0 ) {
-
-						x = Math.sin( time + i * 1.7 ) * 80;
-						y = Math.cos( time + i * 1.5 ) * 40;
-						z = Math.cos( time + i * 1.3 ) * 30;
-
-					} else {
-
-						x = Math.sin( time * 3 ) * 20;
-						y = 15;
-						z = Math.cos( time * 3 ) * 25 + 10;
-
-					}
-
-					light.position.set( x, y, z );
-
-				}
-
-				// update camera
-
-				var delta = clock.getDelta();
-
-				targetX = mouseX * .001;
-				targetY = mouseY * .001;
-
-				angle += 0.05 * ( targetX - angle );
-
-				camera.position.x = -Math.sin( angle ) * 150;
-				camera.position.z =  Math.cos( angle ) * 150;
-
-				camera.lookAt( target );
-
-				// render
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-	</body>
-
-</html>

+ 18 - 206
src/core/BufferGeometry.js

@@ -353,14 +353,12 @@ THREE.BufferGeometry.prototype = {
 			direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
 			direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
 			direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
-			direct.tangentsNeedUpdate = geometry.tangentsNeedUpdate;
 			direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
 
 			geometry.verticesNeedUpdate = false;
 			geometry.normalsNeedUpdate = false;
 			geometry.colorsNeedUpdate = false;
 			geometry.uvsNeedUpdate = false;
-			geometry.tangentsNeedUpdate = false;
 			geometry.groupsNeedUpdate = false;
 
 			geometry = direct;
@@ -412,21 +410,6 @@ THREE.BufferGeometry.prototype = {
 
 		}
 
-		if ( geometry.tangentsNeedUpdate === true ) {
-
-			var attribute = this.attributes.tangent;
-
-			if ( attribute !== undefined ) {
-
-				attribute.copyVector4sArray( geometry.tangents );
-				attribute.needsUpdate = true;
-
-			}
-
-			geometry.tangentsNeedUpdate = false;
-
-		}
-
 		if ( geometry.lineDistancesNeedUpdate ) {
 
 			var attribute = this.attributes.lineDistance;
@@ -496,13 +479,6 @@ THREE.BufferGeometry.prototype = {
 
 		}
 
-		if ( geometry.tangents.length > 0 ) {
-
-			var tangents = new Float32Array( geometry.tangents.length * 4 );
-			this.addAttribute( 'tangent', new THREE.BufferAttribute( tangents, 4 ).copyVector4sArray( geometry.tangents ) );
-
-		}
-
 		if ( geometry.indices.length > 0 ) {
 
 			var TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;
@@ -805,185 +781,7 @@ THREE.BufferGeometry.prototype = {
 
 	computeTangents: function () {
 
-		// based on http://www.terathon.com/code/tangent.html
-		// (per vertex tangents)
-
-		if ( this.index === undefined ||
-			 this.attributes.position === undefined ||
-			 this.attributes.normal === undefined ||
-			 this.attributes.uv === undefined ) {
-
-			console.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' );
-			return;
-
-		}
-
-		var indices = this.index.array;
-		var positions = this.attributes.position.array;
-		var normals = this.attributes.normal.array;
-		var uvs = this.attributes.uv.array;
-
-		var nVertices = positions.length / 3;
-
-		if ( this.attributes.tangent === undefined ) {
-
-			this.addAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );
-
-		}
-
-		var tangents = this.attributes.tangent.array;
-
-		var tan1 = [], tan2 = [];
-
-		for ( var k = 0; k < nVertices; k ++ ) {
-
-			tan1[ k ] = new THREE.Vector3();
-			tan2[ k ] = new THREE.Vector3();
-
-		}
-
-		var vA = new THREE.Vector3(),
-			vB = new THREE.Vector3(),
-			vC = new THREE.Vector3(),
-
-			uvA = new THREE.Vector2(),
-			uvB = new THREE.Vector2(),
-			uvC = new THREE.Vector2(),
-
-			x1, x2, y1, y2, z1, z2,
-			s1, s2, t1, t2, r;
-
-		var sdir = new THREE.Vector3(), tdir = new THREE.Vector3();
-
-		function handleTriangle( a, b, c ) {
-
-			vA.fromArray( positions, a * 3 );
-			vB.fromArray( positions, b * 3 );
-			vC.fromArray( positions, c * 3 );
-
-			uvA.fromArray( uvs, a * 2 );
-			uvB.fromArray( uvs, b * 2 );
-			uvC.fromArray( uvs, c * 2 );
-
-			x1 = vB.x - vA.x;
-			x2 = vC.x - vA.x;
-
-			y1 = vB.y - vA.y;
-			y2 = vC.y - vA.y;
-
-			z1 = vB.z - vA.z;
-			z2 = vC.z - vA.z;
-
-			s1 = uvB.x - uvA.x;
-			s2 = uvC.x - uvA.x;
-
-			t1 = uvB.y - uvA.y;
-			t2 = uvC.y - uvA.y;
-
-			r = 1.0 / ( s1 * t2 - s2 * t1 );
-
-			sdir.set(
-				( t2 * x1 - t1 * x2 ) * r,
-				( t2 * y1 - t1 * y2 ) * r,
-				( t2 * z1 - t1 * z2 ) * r
-			);
-
-			tdir.set(
-				( s1 * x2 - s2 * x1 ) * r,
-				( s1 * y2 - s2 * y1 ) * r,
-				( s1 * z2 - s2 * z1 ) * r
-			);
-
-			tan1[ a ].add( sdir );
-			tan1[ b ].add( sdir );
-			tan1[ c ].add( sdir );
-
-			tan2[ a ].add( tdir );
-			tan2[ b ].add( tdir );
-			tan2[ c ].add( tdir );
-
-		}
-
-		var i, il;
-		var j, jl;
-		var iA, iB, iC;
-
-		if ( this.groups.length === 0 ) {
-
-			this.addGroup( 0, indices.length );
-
-		}
-
-		var groups = this.groups;
-
-		for ( j = 0, jl = groups.length; j < jl; ++ j ) {
-
-			var group = groups[ j ];
-
-			var start = group.start;
-			var count = group.count;
-
-			for ( i = start, il = start + count; i < il; i += 3 ) {
-
-				iA = indices[ i + 0 ];
-				iB = indices[ i + 1 ];
-				iC = indices[ i + 2 ];
-
-				handleTriangle( iA, iB, iC );
-
-			}
-
-		}
-
-		var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
-		var n = new THREE.Vector3(), n2 = new THREE.Vector3();
-		var w, t, test;
-
-		function handleVertex( v ) {
-
-			n.fromArray( normals, v * 3 );
-			n2.copy( n );
-
-			t = tan1[ v ];
-
-			// Gram-Schmidt orthogonalize
-
-			tmp.copy( t );
-			tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
-
-			// Calculate handedness
-
-			tmp2.crossVectors( n2, t );
-			test = tmp2.dot( tan2[ v ] );
-			w = ( test < 0.0 ) ? - 1.0 : 1.0;
-
-			tangents[ v * 4 ] = tmp.x;
-			tangents[ v * 4 + 1 ] = tmp.y;
-			tangents[ v * 4 + 2 ] = tmp.z;
-			tangents[ v * 4 + 3 ] = w;
-
-		}
-
-		for ( j = 0, jl = groups.length; j < jl; ++ j ) {
-
-			var group = groups[ j ];
-
-			var start = group.start;
-			var count = group.count;
-
-			for ( i = start, il = start + count; i < il; i += 3 ) {
-
-				iA = indices[ i + 0 ];
-				iB = indices[ i + 1 ];
-				iC = indices[ i + 2 ];
-
-				handleVertex( iA );
-				handleVertex( iB );
-				handleVertex( iC );
-
-			}
-
-		}
+		console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
 
 	},
 
@@ -1084,10 +882,20 @@ THREE.BufferGeometry.prototype = {
 
 		data.data = { attributes: {} };
 
-		var attributes = this.attributes;
-		var groups = this.groups;
+		var index = this.index;
 
-		var boundingSphere = this.boundingSphere;
+		if ( index !== null ) {
+
+			var array = Array.prototype.slice.call( index.array );
+
+			data.data.index = {
+				type: index.array.constructor.name,
+				array: array
+			};
+
+		}
+
+		var attributes = this.attributes;
 
 		for ( var key in attributes ) {
 
@@ -1103,12 +911,16 @@ THREE.BufferGeometry.prototype = {
 
 		}
 
+		var groups = this.groups;
+
 		if ( groups.length > 0 ) {
 
 			data.data.groups = JSON.parse( JSON.stringify( groups ) );
 
 		}
 
+		var boundingSphere = this.boundingSphere;
+
 		if ( boundingSphere !== null ) {
 
 			data.data.boundingSphere = {

+ 0 - 34
src/core/DirectGeometry.js

@@ -17,7 +17,6 @@ THREE.DirectGeometry = function () {
 	this.colors = [];
 	this.uvs = [];
 	this.uvs2 = [];
-	this.tangents = [];
 
 	this.groups = [];
 
@@ -37,7 +36,6 @@ THREE.DirectGeometry = function () {
 	this.normalsNeedUpdate = false;
 	this.colorsNeedUpdate = false;
 	this.uvsNeedUpdate = false;
-	this.tangentsNeedUpdate = false;
 	this.groupsNeedUpdate = false;
 
 };
@@ -52,21 +50,12 @@ THREE.DirectGeometry.prototype = {
 	computeFaceNormals: function () {
 
 		console.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' );
-		return this;
 
 	},
 
 	computeVertexNormals: function () {
 
 		console.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' );
-		return this;
-
-	},
-
-	computeTangents: function () {
-
-		console.warn( 'THREE.DirectGeometry: computeTangents() is not a method of this type of geometry.' );
-		return this;
 
 	},
 
@@ -124,8 +113,6 @@ THREE.DirectGeometry.prototype = {
 		var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
 		var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
 
-		var hasTangents = geometry.hasTangents;
-
 		// morphs
 
 		var morphTargets = geometry.morphTargets;
@@ -242,26 +229,6 @@ THREE.DirectGeometry.prototype = {
 
 			}
 
-			// tangents
-
-			if ( hasTangents === true ) {
-
-				var vertexTangents = face.vertexTangents;
-
-				if ( vertexTangents.length === 3 ) {
-
-					this.tangents.push( vertexTangents[ 0 ], vertexTangents[ 1 ], vertexTangents[ 2 ] );
-
-				} else {
-
-					console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined tangents ', i );
-
-					this.tangents.push( new THREE.Vector4(), new THREE.Vector4(), new THREE.Vector4() );
-
-				}
-
-			}
-
 			// morphs
 
 			for ( var j = 0; j < morphTargetsLength; j ++ ) {
@@ -302,7 +269,6 @@ THREE.DirectGeometry.prototype = {
 		this.normalsNeedUpdate = geometry.normalsNeedUpdate;
 		this.colorsNeedUpdate = geometry.colorsNeedUpdate;
 		this.uvsNeedUpdate = geometry.uvsNeedUpdate;
-		this.tangentsNeedUpdate = geometry.tangentsNeedUpdate;
 		this.groupsNeedUpdate = geometry.groupsNeedUpdate;
 
 		return this;

+ 0 - 8
src/core/Face3.js

@@ -15,8 +15,6 @@ THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
 	this.color = color instanceof THREE.Color ? color : new THREE.Color();
 	this.vertexColors = Array.isArray( color ) ? color : [];
 
-	this.vertexTangents = [];
-
 	this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
 
 };
@@ -54,12 +52,6 @@ THREE.Face3.prototype = {
 
 		}
 
-		for ( var i = 0, il = source.vertexTangents.length; i < il; i ++ ) {
-
-			this.vertexTangents[ i ] = source.vertexTangents[ i ].clone();
-
-		}
-
 		return this;
 
 	}

+ 1 - 118
src/core/Geometry.js

@@ -33,15 +33,12 @@ THREE.Geometry = function () {
 	this.boundingBox = null;
 	this.boundingSphere = null;
 
-	this.hasTangents = false;
-
 	// update flags
 
 	this.verticesNeedUpdate = false;
 	this.elementsNeedUpdate = false;
 	this.uvsNeedUpdate = false;
 	this.normalsNeedUpdate = false;
-	this.tangentsNeedUpdate = false;
 	this.colorsNeedUpdate = false;
 	this.lineDistancesNeedUpdate = false;
 	this.groupsNeedUpdate = false;
@@ -223,15 +220,12 @@ THREE.Geometry.prototype = {
 		var colors = attributes.color !== undefined ? attributes.color.array : undefined;
 		var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;
 		var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;
-		var tangents = attributes.tangent !== undefined ? attributes.tangent.array : undefined;
 
 		if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];
-		if ( tangents !== undefined ) this.hasTangents = true;
 
 		var tempNormals = [];
 		var tempUVs = [];
 		var tempUVs2 = [];
-		var tempTangents = [];
 
 		for ( var i = 0, j = 0, k = 0; i < vertices.length; i += 3, j += 2, k += 4 ) {
 
@@ -261,12 +255,6 @@ THREE.Geometry.prototype = {
 
 			}
 
-			if ( tangents !== undefined ) {
-
-				tempTangents.push( new THREE.Vector4( tangents[ k ], tangents[ k + 1 ], tangents[ k + 2 ], tangents[ k + 3 ] ) );
-
-			}
-
 		}
 
 		var addFace = function ( a, b, c ) {
@@ -290,12 +278,6 @@ THREE.Geometry.prototype = {
 
 			}
 
-			if ( tangents !== undefined ) {
-
-				face.vertexTangents.push( tempTangents[ a ].clone(), tempTangents[ b ].clone(), tempTangents[ c ].clone() );
-
-			}
-
 		};
 
 		if ( indices !== undefined ) {
@@ -617,106 +599,7 @@ THREE.Geometry.prototype = {
 
 	computeTangents: function () {
 
-		// based on http://www.terathon.com/code/tangent.html
-		// tangents go to vertices
-
-		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,
-			tan1 = [], tan2 = [],
-			sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
-			tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
-			n = new THREE.Vector3(), w;
-
-		for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
-
-			tan1[ v ] = new THREE.Vector3();
-			tan2[ v ] = new THREE.Vector3();
-
-		}
-
-		function handleTriangle( context, a, b, c, ua, ub, uc ) {
-
-			vA = context.vertices[ a ];
-			vB = context.vertices[ b ];
-			vC = context.vertices[ c ];
-
-			uvA = uv[ ua ];
-			uvB = uv[ ub ];
-			uvC = uv[ uc ];
-
-			x1 = vB.x - vA.x;
-			x2 = vC.x - vA.x;
-			y1 = vB.y - vA.y;
-			y2 = vC.y - vA.y;
-			z1 = vB.z - vA.z;
-			z2 = vC.z - vA.z;
-
-			s1 = uvB.x - uvA.x;
-			s2 = uvC.x - uvA.x;
-			t1 = uvB.y - uvA.y;
-			t2 = uvC.y - uvA.y;
-
-			r = 1.0 / ( s1 * t2 - s2 * t1 );
-			sdir.set( ( t2 * x1 - t1 * x2 ) * r,
-					  ( t2 * y1 - t1 * y2 ) * r,
-					  ( t2 * z1 - t1 * z2 ) * r );
-			tdir.set( ( s1 * x2 - s2 * x1 ) * r,
-					  ( s1 * y2 - s2 * y1 ) * r,
-					  ( s1 * z2 - s2 * z1 ) * r );
-
-			tan1[ a ].add( sdir );
-			tan1[ b ].add( sdir );
-			tan1[ c ].add( sdir );
-
-			tan2[ a ].add( tdir );
-			tan2[ b ].add( tdir );
-			tan2[ c ].add( tdir );
-
-		}
-
-		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-			face = this.faces[ f ];
-			uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents
-
-			handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
-
-		}
-
-		var faceIndex = [ 'a', 'b', 'c', 'd' ];
-
-		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-			face = this.faces[ f ];
-
-			for ( i = 0; i < Math.min( face.vertexNormals.length, 3 ); i ++ ) {
-
-				n.copy( face.vertexNormals[ i ] );
-
-				vertexIndex = face[ faceIndex[ i ] ];
-
-				t = tan1[ vertexIndex ];
-
-				// Gram-Schmidt orthogonalize
-
-				tmp.copy( t );
-				tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
-
-				// Calculate handedness
-
-				tmp2.crossVectors( face.vertexNormals[ i ], t );
-				test = tmp2.dot( tan2[ vertexIndex ] );
-				w = ( test < 0.0 ) ? - 1.0 : 1.0;
-
-				face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w );
-
-			}
-
-		}
-
-		this.hasTangents = true;
+		console.warn( 'THREE.Geometry: .computeTangents() has been removed.' );
 
 	},
 

+ 1 - 90
src/extras/geometries/SphereGeometry.js

@@ -4,8 +4,6 @@
 
 THREE.SphereGeometry = function ( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
 
-	console.log( 'THREE.SphereGeometry: Consider using THREE.SphereBufferGeometry for lower memory footprint.' );
-
 	THREE.Geometry.call( this );
 
 	this.type = 'SphereGeometry';
@@ -20,94 +18,7 @@ THREE.SphereGeometry = function ( radius, widthSegments, heightSegments, phiStar
 		thetaLength: thetaLength
 	};
 
-	radius = radius || 50;
-
-	widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
-	heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
-
-	phiStart = phiStart !== undefined ? phiStart : 0;
-	phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
-
-	thetaStart = thetaStart !== undefined ? thetaStart : 0;
-	thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
-
-	var x, y, vertices = [], uvs = [];
-
-	for ( y = 0; y <= heightSegments; y ++ ) {
-
-		var verticesRow = [];
-		var uvsRow = [];
-
-		for ( x = 0; x <= widthSegments; x ++ ) {
-
-			var u = x / widthSegments;
-			var v = y / heightSegments;
-
-			var vertex = new THREE.Vector3();
-			vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
-			vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
-			vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
-
-			this.vertices.push( vertex );
-
-			verticesRow.push( this.vertices.length - 1 );
-			uvsRow.push( new THREE.Vector2( u, 1 - v ) );
-
-		}
-
-		vertices.push( verticesRow );
-		uvs.push( uvsRow );
-
-	}
-
-	for ( y = 0; y < heightSegments; y ++ ) {
-
-		for ( x = 0; x < widthSegments; x ++ ) {
-
-			var v1 = vertices[ y ][ x + 1 ];
-			var v2 = vertices[ y ][ x ];
-			var v3 = vertices[ y + 1 ][ x ];
-			var v4 = vertices[ y + 1 ][ x + 1 ];
-
-			var n1 = this.vertices[ v1 ].clone().normalize();
-			var n2 = this.vertices[ v2 ].clone().normalize();
-			var n3 = this.vertices[ v3 ].clone().normalize();
-			var n4 = this.vertices[ v4 ].clone().normalize();
-
-			var uv1 = uvs[ y ][ x + 1 ].clone();
-			var uv2 = uvs[ y ][ x ].clone();
-			var uv3 = uvs[ y + 1 ][ x ].clone();
-			var uv4 = uvs[ y + 1 ][ x + 1 ].clone();
-
-			if ( Math.abs( this.vertices[ v1 ].y ) === radius ) {
-
-				uv1.x = ( uv1.x + uv2.x ) / 2;
-				this.faces.push( new THREE.Face3( v1, v3, v4, [ n1, n3, n4 ] ) );
-				this.faceVertexUvs[ 0 ].push( [ uv1, uv3, uv4 ] );
-
-			} else if ( Math.abs( this.vertices[ v3 ].y ) === radius ) {
-
-				uv3.x = ( uv3.x + uv4.x ) / 2;
-				this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) );
-				this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
-
-			} else {
-
-				this.faces.push( new THREE.Face3( v1, v2, v4, [ n1, n2, n4 ] ) );
-				this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv4 ] );
-
-				this.faces.push( new THREE.Face3( v2, v3, v4, [ n2.clone(), n3, n4.clone() ] ) );
-				this.faceVertexUvs[ 0 ].push( [ uv2.clone(), uv3, uv4.clone() ] );
-
-			}
-
-		}
-
-	}
-
-	this.computeFaceNormals();
-
-	this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );
+	this.fromBufferGeometry( new THREE.SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
 
 };
 

+ 0 - 144
src/extras/helpers/VertexTangentsHelper.js

@@ -1,144 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author WestLangley / http://github.com/WestLangley
-*/
-
-THREE.VertexTangentsHelper = function ( object, size, hex, linewidth ) {
-
-	this.object = object;
-
-	this.size = ( size !== undefined ) ? size : 1;
-
-	var color = ( hex !== undefined ) ? hex : 0x0000ff;
-
-	var width = ( linewidth !== undefined ) ? linewidth : 1;
-
-	//
-
-	var nTangents = 0;
-
-	var objGeometry = this.object.geometry;
-
-	if ( objGeometry instanceof THREE.Geometry ) {
-
-		nTangents = objGeometry.faces.length * 3;
-
-	} else if ( objGeometry instanceof THREE.BufferGeometry ) {
-
-		nTangents = objGeometry.attributes.tangent.count
-
-	}
-
-	//
-
-	var geometry = new THREE.BufferGeometry();
-
-	var positions = new THREE.Float32Attribute( nTangents * 2 * 3, 3 );
-
-	geometry.addAttribute( 'position', positions );
-
-	THREE.LineSegments.call( this, geometry, new THREE.LineBasicMaterial( { color: color, linewidth: width } ) );
-
-	//
-
-	this.matrixAutoUpdate = false;
-
-	this.update();
-
-};
-
-THREE.VertexTangentsHelper.prototype = Object.create( THREE.LineSegments.prototype );
-THREE.VertexTangentsHelper.prototype.constructor = THREE.VertexTangentsHelper;
-
-THREE.VertexTangentsHelper.prototype.update = ( function ( object ) {
-
-	var v1 = new THREE.Vector3();
-	var v2 = new THREE.Vector3();
-
-	return function() {
-
-		var keys = [ 'a', 'b', 'c' ];
-
-		this.object.updateMatrixWorld( true );
-
-		var matrixWorld = this.object.matrixWorld;
-
-		var position = this.geometry.attributes.position;
-
-		//
-
-		var objGeometry = this.object.geometry;
-
-		if ( objGeometry instanceof THREE.Geometry ) {
-
-			var vertices = objGeometry.vertices;
-
-			var faces = objGeometry.faces;
-
-			var idx = 0;
-
-			for ( var i = 0, l = faces.length; i < l; i ++ ) {
-
-				var face = faces[ i ];
-
-				for ( var j = 0, jl = face.vertexTangents.length; j < jl; j ++ ) {
-
-					var vertex = vertices[ face[ keys[ j ] ] ];
-
-					var tangent = face.vertexTangents[ j ];
-
-					v1.copy( vertex ).applyMatrix4( matrixWorld );
-
-					v2.set( tangent.x, tangent.y, tangent.z ); // tangent.w used for bitangents only
-
-					v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( v1 );
-
-					position.setXYZ( idx, v1.x, v1.y, v1.z );
-
-					idx = idx + 1;
-
-					position.setXYZ( idx, v2.x, v2.y, v2.z );
-
-					idx = idx + 1;
-
-				}
-
-			}
-
-		} else if ( objGeometry instanceof THREE.BufferGeometry ) {
-
-			var objPos = objGeometry.attributes.position;
-
-			var objTan = objGeometry.attributes.tangent;
-
-			var idx = 0;
-
-			// for simplicity, ignore index and drawcalls, and render every tangent
-
-			for ( var j = 0, jl = objPos.count; j < jl; j ++ ) {
-
-				v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );
-
-				v2.set( objTan.getX( j ), objTan.getY( j ), objTan.getZ( j ) ); // tangent.w used for bitangents only
-
-				v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( v1 );
-
-				position.setXYZ( idx, v1.x, v1.y, v1.z );
-
-				idx = idx + 1;
-
-				position.setXYZ( idx, v2.x, v2.y, v2.z );
-
-				idx = idx + 1;
-
-			}
-
-		}
-
-		position.needsUpdate = true;
-
-		return this;
-
-	}
-
-}() );

+ 0 - 56
src/lights/AreaLight.js

@@ -1,56 +0,0 @@
-/**
- * @author MPanknin / http://www.redplant.de/
- * @author alteredq / http://alteredqualia.com/
- * @author prafullit
- */
-
-THREE.AreaLight = function ( color, intensity ) {
-
-	THREE.Light.call( this, color );
-
-	this.type = 'AreaLight';
-
-	this.normal = new THREE.Vector3( 0, - 1, 0 );
-	this.right = new THREE.Vector3( 1, 0, 0 );
-
-	this.intensity = ( intensity !== undefined ) ? intensity : 1;
-
-	this.width = 1.0;
-	this.height = 1.0;
-
-	this.constantAttenuation = 1.5;
-	this.linearAttenuation = 0.5;
-	this.quadraticAttenuation = 0.1;
-
-};
-
-THREE.AreaLight.prototype = Object.create( THREE.Light.prototype );
-THREE.AreaLight.prototype.constructor = THREE.AreaLight;
-
-THREE.AreaLight.prototype.copy = function ( source ) {
-
-	THREE.Light.prototype.copy.call( this, source );
-
-	this.intensity = source.intensity;
-	this.normal.copy( source.normal );
-	this.right.copy( source.right );
-	this.width = source.width;
-	this.height = source.height;
-	this.constantAttenuation = source.constantAttenuation;
-	this.linearAttenuation = source.linearAttenuation;
-	this.quadraticAttenuation = source.quadraticAttenuation;
-
-	return this;
-
-};
-
-THREE.AreaLight.prototype.toJSON = function ( meta ) {
-
-	var data = THREE.Object3D.prototype.toJSON.call( this, meta );
-
-	data.object.color = this.color.getHex();
-	data.object.intensity = this.intensity;
-
-	return data;
-
-};

+ 9 - 0
src/loaders/BufferGeometryLoader.js

@@ -36,6 +36,15 @@ THREE.BufferGeometryLoader.prototype = {
 
 		var geometry = new THREE.BufferGeometry();
 
+		var index = json.data.index;
+
+		if ( index !== undefined ) {
+
+			var typedArray = new self[ index.type ]( index.array );
+			geometry.addIndex( new THREE.BufferAttribute( typedArray, 1 ) );
+
+		}
+
 		var attributes = json.data.attributes;
 
 		for ( var key in attributes ) {

+ 4 - 6
src/loaders/ImageLoader.js

@@ -56,15 +56,13 @@ THREE.ImageLoader.prototype = {
 
 		}
 
-		if ( onError !== undefined ) {
+		image.addEventListener( 'error', function ( event ) {
 
-			image.addEventListener( 'error', function ( event ) {
+			if ( onError ) onError( event );
 
-				onError( event );
+			scope.manager.itemError( url );
 
-			}, false );
-
-		}
+		}, false );
 
 		if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;
 

+ 0 - 6
src/loaders/JSONLoader.js

@@ -535,12 +535,6 @@ THREE.JSONLoader.prototype = {
 
 			var materials = THREE.Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );
 
-			if ( THREE.Loader.prototype.needsTangents( materials ) ) {
-
-				geometry.computeTangents();
-
-			}
-
 			return { geometry: geometry, materials: materials };
 
 		}

+ 0 - 14
src/loaders/Loader.js

@@ -42,20 +42,6 @@ THREE.Loader.prototype = {
 
 	},
 
-	needsTangents: function ( materials ) {
-
-		for ( var i = 0, il = materials.length; i < il; i ++ ) {
-
-			var m = materials[ i ];
-
-			if ( m instanceof THREE.ShaderMaterial ) return true;
-
-		}
-
-		return false;
-
-	},
-
 	createMaterial: ( function () {
 
 		var imageLoader;

+ 11 - 0
src/loaders/LoadingManager.js

@@ -8,6 +8,7 @@ THREE.LoadingManager = function ( onLoad, onProgress, onError ) {
 
 	var isLoading = false, itemsLoaded = 0, itemsTotal = 0;
 
+	this.onStart = undefined;
 	this.onLoad = onLoad;
 	this.onProgress = onProgress;
 	this.onError = onError;
@@ -54,6 +55,16 @@ THREE.LoadingManager = function ( onLoad, onProgress, onError ) {
 
 	};
 
+	this.itemError = function ( url ) {
+
+		if ( scope.onError !== undefined ) {
+
+			scope.onError( url );
+
+		}
+
+	};
+
 };
 
 THREE.DefaultLoadingManager = new THREE.LoadingManager();

+ 38 - 13
src/loaders/ObjectLoader.js

@@ -260,6 +260,15 @@ THREE.ObjectLoader.prototype = {
 
 						break;
 
+					case 'TextGeometry':
+
+						geometry = new THREE.TextGeometry(
+							data.text,
+							data.data
+						);
+
+						break;
+
 					case 'BufferGeometry':
 
 						geometry = bufferGeometryLoader.parse( data );
@@ -272,14 +281,11 @@ THREE.ObjectLoader.prototype = {
 
 						break;
 
-					case 'TextGeometry':
+					default:
 
-						geometry = new THREE.TextGeometry(
-							data.text,
-							data.data
-						);
+						console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
 
-						break;
+						continue;
 
 				}
 
@@ -449,6 +455,7 @@ THREE.ObjectLoader.prototype = {
 
 				if ( data.name !== undefined ) texture.name = data.name;
 				if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping );
+				if ( data.offset !== undefined ) texture.offset = new THREE.Vector2( data.offset[ 0 ], data.offset[ 1 ] );
 				if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
 				if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter );
 				if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter );
@@ -528,13 +535,6 @@ THREE.ObjectLoader.prototype = {
 
 					break;
 
-
-				case 'AreaLight':
-
-					object = new THREE.AreaLight( data.color, data.intensity );
-
-					break;
-
 				case 'DirectionalLight':
 
 					object = new THREE.DirectionalLight( data.color, data.intensity );
@@ -565,6 +565,12 @@ THREE.ObjectLoader.prototype = {
 
 					break;
 
+				case 'LOD':
+
+					object = new THREE.LOD();
+
+					break;
+
 				case 'Line':
 
 					object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
@@ -650,6 +656,25 @@ THREE.ObjectLoader.prototype = {
 
 			}
 
+			if ( data.type === 'LOD' ) {
+
+				var levels = data.levels;
+
+				for ( var l = 0; l < levels.length; l ++ ) {
+
+					var level = levels[ l ];
+					var child = object.getObjectByProperty( 'uuid', level.object );
+
+					if ( child !== undefined ) {
+
+						object.addLevel( child, level.distance );
+
+					}
+
+				}
+
+			}
+
 			return object;
 
 		}

+ 4 - 6
src/loaders/XHRLoader.js

@@ -57,15 +57,13 @@ THREE.XHRLoader.prototype = {
 
 		}
 
-		if ( onError !== undefined ) {
+		request.addEventListener( 'error', function ( event ) {
 
-			request.addEventListener( 'error', function ( event ) {
+			if ( onError ) onError( event );
 
-				onError( event );
+			scope.manager.itemError( url );
 
-			}, false );
-
-		}
+		}, false );
 
 		if ( this.crossOrigin !== undefined ) request.crossOrigin = this.crossOrigin;
 		if ( this.responseType !== undefined ) request.responseType = this.responseType;

+ 8 - 6
src/math/Quaternion.js

@@ -121,42 +121,44 @@ THREE.Quaternion.prototype = {
 		var s2 = Math.sin( euler._y / 2 );
 		var s3 = Math.sin( euler._z / 2 );
 
-		if ( euler.order === 'XYZ' ) {
+		var order = euler.order;
+
+		if ( order === 'XYZ' ) {
 
 			this._x = s1 * c2 * c3 + c1 * s2 * s3;
 			this._y = c1 * s2 * c3 - s1 * c2 * s3;
 			this._z = c1 * c2 * s3 + s1 * s2 * c3;
 			this._w = c1 * c2 * c3 - s1 * s2 * s3;
 
-		} else if ( euler.order === 'YXZ' ) {
+		} else if ( order === 'YXZ' ) {
 
 			this._x = s1 * c2 * c3 + c1 * s2 * s3;
 			this._y = c1 * s2 * c3 - s1 * c2 * s3;
 			this._z = c1 * c2 * s3 - s1 * s2 * c3;
 			this._w = c1 * c2 * c3 + s1 * s2 * s3;
 
-		} else if ( euler.order === 'ZXY' ) {
+		} else if ( order === 'ZXY' ) {
 
 			this._x = s1 * c2 * c3 - c1 * s2 * s3;
 			this._y = c1 * s2 * c3 + s1 * c2 * s3;
 			this._z = c1 * c2 * s3 + s1 * s2 * c3;
 			this._w = c1 * c2 * c3 - s1 * s2 * s3;
 
-		} else if ( euler.order === 'ZYX' ) {
+		} else if ( order === 'ZYX' ) {
 
 			this._x = s1 * c2 * c3 - c1 * s2 * s3;
 			this._y = c1 * s2 * c3 + s1 * c2 * s3;
 			this._z = c1 * c2 * s3 - s1 * s2 * c3;
 			this._w = c1 * c2 * c3 + s1 * s2 * s3;
 
-		} else if ( euler.order === 'YZX' ) {
+		} else if ( order === 'YZX' ) {
 
 			this._x = s1 * c2 * c3 + c1 * s2 * s3;
 			this._y = c1 * s2 * c3 + s1 * c2 * s3;
 			this._z = c1 * c2 * s3 - s1 * s2 * c3;
 			this._w = c1 * c2 * c3 - s1 * s2 * s3;
 
-		} else if ( euler.order === 'XZY' ) {
+		} else if ( order === 'XZY' ) {
 
 			this._x = s1 * c2 * c3 - c1 * s2 * s3;
 			this._y = c1 * s2 * c3 - s1 * c2 * s3;

+ 25 - 0
src/objects/LOD.js

@@ -8,6 +8,8 @@ THREE.LOD = function () {
 
 	THREE.Object3D.call( this );
 
+	this.type = 'LOD';
+
 	Object.defineProperties( this, {
 		levels: {
 			enumerable: true,
@@ -149,3 +151,26 @@ THREE.LOD.prototype.copy = function ( source ) {
 	return this;
 
 };
+
+THREE.LOD.prototype.toJSON = function ( meta ) {
+
+	var data = THREE.Object3D.prototype.toJSON.call( this, meta );
+
+	data.object.levels = [];
+
+	var levels = this.levels;
+
+	for ( var i = 0, l = levels.length; i < l; i ++ ) {
+
+		var level = levels[ i ];
+
+		data.object.levels.push( {
+			object: level.object.uuid,
+			distance: level.distance
+		} );
+
+	}
+
+	return data;
+
+};

+ 80 - 21
src/objects/Mesh.js

@@ -69,6 +69,29 @@ THREE.Mesh.prototype.raycast = ( function () {
 	var tempB = new THREE.Vector3();
 	var tempC = new THREE.Vector3();
 
+	var uvA = new THREE.Vector2();
+	var uvB = new THREE.Vector2();
+	var uvC = new THREE.Vector2();
+
+	var barycoord = new THREE.Vector3();
+
+	var intersectionPoint = new THREE.Vector3();
+	var intersectionPointWorld = new THREE.Vector3();
+
+	function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {
+
+		THREE.Triangle.barycoordFromPoint( point, p1, p2, p3, barycoord );
+
+		uv1.multiplyScalar( barycoord.x );
+		uv2.multiplyScalar( barycoord.y );
+		uv3.multiplyScalar( barycoord.z );
+
+		uv1.add( uv2 ).add( uv3 );
+
+		return uv1.clone();
+
+	}
+
 	return function raycast( raycaster, intersects ) {
 
 		var geometry = this.geometry;
@@ -145,26 +168,38 @@ THREE.Mesh.prototype.raycast = ( function () {
 
 						if ( material.side === THREE.BackSide ) {
 
-							var intersectionPoint = ray.intersectTriangle( vC, vB, vA, true );
+							if ( ray.intersectTriangle( vC, vB, vA, true, intersectionPoint ) === null ) continue;
 
 						} else {
 
-							var intersectionPoint = ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide );
+							if ( ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide, intersectionPoint ) === null ) continue;
 
 						}
 
-						if ( intersectionPoint === null ) continue;
-
-						intersectionPoint.applyMatrix4( this.matrixWorld );
+						intersectionPointWorld.copy( intersectionPoint );
+						intersectionPointWorld.applyMatrix4( this.matrixWorld );
 
-						var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
+						var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );
 
 						if ( distance < raycaster.near || distance > raycaster.far ) continue;
 
+						var uv;
+
+						if ( attributes.uv !== undefined ) {
+
+							var uvs = attributes.uv.array;
+							uvA.fromArray( uvs, a * 2 );
+							uvB.fromArray( uvs, b * 2 );
+							uvC.fromArray( uvs, c * 2 );
+							uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );
+
+						}
+
 						intersects.push( {
 
 							distance: distance,
-							point: intersectionPoint,
+							point: intersectionPointWorld.clone(),
+							uv: uv,
 							face: new THREE.Face3( a, b, c, THREE.Triangle.normal( vA, vB, vC ) ),
 							faceIndex: Math.floor( i / 3 ), // triangle number in indices buffer semantics
 							object: this
@@ -187,22 +222,33 @@ THREE.Mesh.prototype.raycast = ( function () {
 
 					if ( material.side === THREE.BackSide ) {
 
-						var intersectionPoint = ray.intersectTriangle( vC, vB, vA, true );
+						if ( ray.intersectTriangle( vC, vB, vA, true, intersectionPoint ) === null ) continue;
 
 					} else {
 
-						var intersectionPoint = ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide );
+						if ( ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide, intersectionPoint ) === null ) continue;
 
 					}
 
-					if ( intersectionPoint === null ) continue;
+					intersectionPointWorld.copy( intersectionPoint );
+					intersectionPointWorld.applyMatrix4( this.matrixWorld );
 
-					intersectionPoint.applyMatrix4( this.matrixWorld );
-
-					var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
+					var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );
 
 					if ( distance < raycaster.near || distance > raycaster.far ) continue;
 
+					var uv;
+
+					if ( attributes.uv !== undefined ) {
+
+						var uvs = attributes.uv.array;
+						uvA.fromArray( uvs, i );
+						uvB.fromArray( uvs, i + 2 );
+						uvC.fromArray( uvs, i + 4 );
+						uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );
+
+					}
+
 					a = i / 3;
 					b = a + 1;
 					c = a + 2;
@@ -210,7 +256,8 @@ THREE.Mesh.prototype.raycast = ( function () {
 					intersects.push( {
 
 						distance: distance,
-						point: intersectionPoint,
+						point: intersectionPointWorld.clone(),
+						uv: uv,
 						face: new THREE.Face3( a, b, c, THREE.Triangle.normal( vA, vB, vC ) ),
 						index: a, // triangle number in positions buffer semantics
 						object: this
@@ -275,26 +322,38 @@ THREE.Mesh.prototype.raycast = ( function () {
 
 				if ( faceMaterial.side === THREE.BackSide ) {
 
-					var intersectionPoint = ray.intersectTriangle( c, b, a, true );
+					if ( ray.intersectTriangle( c, b, a, true, intersectionPoint ) === null ) continue;
 
 				} else {
 
-					var intersectionPoint = ray.intersectTriangle( a, b, c, faceMaterial.side !== THREE.DoubleSide );
+					if ( ray.intersectTriangle( a, b, c, faceMaterial.side !== THREE.DoubleSide, intersectionPoint ) === null ) continue;
 
 				}
 
-				if ( intersectionPoint === null ) continue;
-
-				intersectionPoint.applyMatrix4( this.matrixWorld );
+				intersectionPointWorld.copy( intersectionPoint );
+				intersectionPointWorld.applyMatrix4( this.matrixWorld );
 
-				var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
+				var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );
 
 				if ( distance < raycaster.near || distance > raycaster.far ) continue;
 
+				var uv;
+
+				if ( geometry.faceVertexUvs[ 0 ].length > 0 ) {
+
+					var uvs = geometry.faceVertexUvs[ 0 ][ f ];
+					uvA.copy( uvs[ 0 ] );
+					uvB.copy( uvs[ 1 ] );
+					uvC.copy( uvs[ 2 ] );
+					uv = uvIntersection( intersectionPoint, a, b, c, uvA, uvB, uvC );
+
+				}
+
 				intersects.push( {
 
 					distance: distance,
-					point: intersectionPoint,
+					point: intersectionPointWorld.clone(),
+					uv: uv,
 					face: face,
 					faceIndex: f,
 					object: this

+ 0 - 4
src/renderers/WebGLRenderer.js

@@ -872,10 +872,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				renderer.renderInstances( geometry );
 
-			} else if ( position instanceof THREE.InterleavedBufferAttribute ) {
-
-				renderer.render( 0, position.data.count );
-
 			} else {
 
 				renderer.render( group.start, group.count );

+ 20 - 4
src/renderers/webgl/WebGLObjects.js

@@ -191,13 +191,29 @@ THREE.WebGLObjects = function ( gl, properties, info ) {
 
 	function checkEdge( edges, a, b ) {
 
-		var hash = a < b ? a + '_' + b : b + '_' + a;
+		if ( a > b ) {
 
-		if ( edges.hasOwnProperty( hash ) ) return false;
+			var tmp = a;
+			a = b;
+			b = tmp;
 
-		edges[ hash ] = 1;
+		}
+
+		var list = edges[ a ];
+
+		if ( list === undefined ) {
+
+			edges[ a ] = [ b ];
+			return true;
+
+		} else if ( list.indexOf( b ) === -1 ) {
+
+			list.push( b );
+			return true;
+
+		}
 
-		return true;
+		return false;
 
 	}
 

+ 77 - 0
src/textures/Texture.js

@@ -185,6 +185,83 @@ THREE.Texture.prototype = {
 
 		this.dispatchEvent( { type: 'dispose' } );
 
+	},
+
+	transformUv: function ( uv ) {
+
+		if ( this.mapping !== THREE.UVMapping )  return;
+
+		uv.multiply( this.repeat );
+		uv.add( this.offset );
+
+		if ( uv.x < 0 || uv.x > 1 ) {
+
+			switch ( this.wrapS ) {
+
+				case THREE.RepeatWrapping:
+
+					uv.x = uv.x - Math.floor( uv.x );
+					break;
+
+				case THREE.ClampToEdgeWrapping:
+
+					uv.x = uv.x < 0 ? 0 : 1;
+					break;
+
+				case THREE.MirroredRepeatWrapping:
+
+					if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
+
+						uv.x = Math.ceil( uv.x ) - uv.x;
+
+					} else {
+
+						uv.x = uv.x - Math.floor( uv.x );
+
+					}
+					break;
+
+			}
+
+		}
+
+		if ( uv.y < 0 || uv.y > 1 ) {
+
+			switch ( this.wrapT ) {
+
+				case THREE.RepeatWrapping:
+
+					uv.y = uv.y - Math.floor( uv.y );
+					break;
+
+				case THREE.ClampToEdgeWrapping:
+
+					uv.y = uv.y < 0 ? 0 : 1;
+					break;
+
+				case THREE.MirroredRepeatWrapping:
+
+					if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
+
+						uv.y = Math.ceil( uv.y ) - uv.y;
+
+					} else {
+
+						uv.y = uv.y - Math.floor( uv.y );
+
+					}
+					break;
+
+			}
+
+		}
+
+		if ( this.flipY ) {
+
+			uv.y = 1 - uv.y;
+
+		}
+
 	}
 
 };

+ 0 - 28
test/unit/lights/AreaLight.tests.js

@@ -1,28 +0,0 @@
-(function () {
-
-	'use strict';
-
-	var lights;
-
-	QUnit.module( "Lights - AreaLight", {
-
-		beforeEach: function() {
-
-			lights = [
-
-				new THREE.AreaLight( 0xaaaaaa ),
-				new THREE.AreaLight( 0xaaaaaa, 0.7 ),
-
-			];
-
-		}
-
-	});
-
-	QUnit.test( "standard light tests", function( assert ) {
-
-		runStdLightTests( assert, lights );
-
-	});
-
-})();

+ 0 - 1
test/unit/unittests_three.html

@@ -39,7 +39,6 @@
   <script src="geometry/EdgesGeometry.js"></script>
   <script src="extras/ImageUtils.test.js"></script>
   <script src="lights/AmbientLight.tests.js"></script>
-  <script src="lights/AreaLight.tests.js"></script>
   <script src="lights/DirectionalLight.tests.js"></script>
   <script src="lights/HemisphereLight.tests.js"></script>
   <script src="lights/PointLight.tests.js"></script>

+ 0 - 1
utils/build/includes/common.json

@@ -50,7 +50,6 @@
 	"src/cameras/PerspectiveCamera.js",
 	"src/lights/Light.js",
 	"src/lights/AmbientLight.js",
-	"src/lights/AreaLight.js",
 	"src/lights/DirectionalLight.js",
 	"src/lights/HemisphereLight.js",
 	"src/lights/PointLight.js",

+ 0 - 1
utils/build/includes/extras.json

@@ -63,7 +63,6 @@
 	"src/extras/helpers/SkeletonHelper.js",
 	"src/extras/helpers/SpotLightHelper.js",
 	"src/extras/helpers/VertexNormalsHelper.js",
-	"src/extras/helpers/VertexTangentsHelper.js",
 	"src/extras/helpers/WireframeHelper.js",
 	"src/extras/objects/ImmediateRenderObject.js",
 	"src/extras/objects/MorphBlendMesh.js"

+ 0 - 1
utils/exporters/blender/addons/io_three/constants.py

@@ -197,7 +197,6 @@ PERSPECTIVE_CAMERA = 'PerspectiveCamera'
 ORTHOGRAPHIC_CAMERA = 'OrthographicCamera'
 AMBIENT_LIGHT = 'AmbientLight'
 DIRECTIONAL_LIGHT = 'DirectionalLight'
-AREA_LIGHT = 'AreaLight'
 POINT_LIGHT = 'PointLight'
 SPOT_LIGHT = 'SpotLight'
 HEMISPHERE_LIGHT = 'HemisphereLight'

+ 15 - 15
utils/exporters/blender/tests/scripts/js/review.js

@@ -4,9 +4,9 @@ var prevTime = Date.now();
 var clock = new THREE.Clock();
 
 function render() {
-        
+
     renderer.render( scene, camera );
- 
+
     if ( hasMorph ) {
 
         var time = Date.now();
@@ -15,7 +15,7 @@ function render() {
 
         prevTime = time;
 
-    }     
+    }
 }
 
 function animate() {
@@ -57,7 +57,7 @@ function setupLights() {
     directionalLight.position.set(1, 1, 1).normalize();
     directionalLight.intensity = 1.0;
     scene.add( directionalLight );
-    
+
     directionalLight = new THREE.DirectionalLight( 0xb8b8b8 );
     directionalLight.position.set(-1, 0.6, 0.5).normalize();
     directionalLight.intensity = 0.5;
@@ -77,7 +77,7 @@ function loadObject( data ) {
 
     var hasLights = false;
 
-    var lights = ['AmbientLight', 'DirectionalLight', 'AreaLight',
+    var lights = ['AmbientLight', 'DirectionalLight',
         'PointLight', 'SpotLight', 'HemisphereLight']
 
     var cameras = ['OrthographicCamera', 'PerspectiveCamera'];
@@ -126,13 +126,13 @@ function loadGeometry( data, url ) {
     data = loader.parse( data, texturePath );
 
     if ( data.materials === undefined ) {
-    
+
         console.log('using default material');
         data.materials = [new THREE.MeshLambertMaterial( { color: 0xb8b8b8 } )];
-    
+
     }
 
-    var material = new THREE.MeshFaceMaterial( data.materials ); 
+    var material = new THREE.MeshFaceMaterial( data.materials );
     var mesh;
 
     if ( data.geometry.animations !== undefined && data.geometry.animations.length > 0 ) {
@@ -195,11 +195,11 @@ function loadBufferGeometry( data ) {
 function loadData( data, url ) {
 
     if ( data.metadata.type === 'Geometry' ) {
-        
+
         loadGeometry( data, url );
-    
+
     } else if ( data.metadata.type === 'Object' ) {
-    
+
         loadObject( data );
 
     } else if ( data.metadata.type === 'BufferGeometry' ) {
@@ -226,7 +226,7 @@ function init( url ) {
     container.appendChild( renderer.domElement );
     renderer.gammaInput = true;
     renderer.gammaOutput = true;
-    
+
     var aspect = container.offsetWidth / container.offsetHeight;
     camera = new THREE.PerspectiveCamera( 50, aspect, 0.01, 50 );
     orbit = new THREE.OrbitControls( camera, container );
@@ -243,7 +243,7 @@ function init( url ) {
 
 	var xhr = new XMLHttpRequest();
     xhr.onreadystatechange = function ( x ) {
-    
+
         if ( xhr.readyState === xhr.DONE ) {
 
             if ( xhr.status === 200 || xhr.status === 0  ) {
@@ -256,8 +256,8 @@ function init( url ) {
 
             }
 
-        } 
-    
+        }
+
     };
     xhr.open( 'GET', url, true );
     xhr.withCredentials = false;

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác